Commit fab7ecce authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

cros: Modify ink drops to use clip instead of mask.

It's a cheaper alternative that gets the same visuals. Design doc in the
linked bug. First application will be on the overview item close button.

Short-term follow ups:
1) Apply on ink drops ash-wide.
2) Change ink drop highlight for ash ink drops to use solid color layer.

Test: manual
Bug: 1042303
Change-Id: Ia1728762fd9234304277e3bb42c12dfa03f87fef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2026527
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarPeter Boström <pbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737182}
parent 99659043
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "ui/views/animation/ink_drop_impl.h" #include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/animation/ink_drop_mask.h" #include "ui/views/animation/ink_drop_mask.h"
#include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/label.h" #include "ui/views/controls/label.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
...@@ -51,7 +52,7 @@ constexpr base::TimeDelta kCloseButtonSlowFadeInDuration = ...@@ -51,7 +52,7 @@ constexpr base::TimeDelta kCloseButtonSlowFadeInDuration =
constexpr base::TimeDelta kCloseButtonSlowFadeInDelay = constexpr base::TimeDelta kCloseButtonSlowFadeInDelay =
base::TimeDelta::FromMilliseconds(750); base::TimeDelta::FromMilliseconds(750);
constexpr int kCloseButtonInkDropInsetDp = 2; constexpr int kCloseButtonInkDropRadiusDp = 18;
constexpr SkColor kCloseButtonColor = SK_ColorWHITE; constexpr SkColor kCloseButtonColor = SK_ColorWHITE;
...@@ -102,10 +103,16 @@ class OverviewCloseButton : public views::ImageButton { ...@@ -102,10 +103,16 @@ class OverviewCloseButton : public views::ImageButton {
SetMinimumImageSize(gfx::Size(kHeaderHeightDp, kHeaderHeightDp)); SetMinimumImageSize(gfx::Size(kHeaderHeightDp, kHeaderHeightDp));
SetAccessibleName(l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE)); SetAccessibleName(l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
SetTooltipText(l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE)); SetTooltipText(l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
views::InstallFixedSizeCircleHighlightPathGenerator(
this, kCloseButtonInkDropRadiusDp);
} }
~OverviewCloseButton() override = default; ~OverviewCloseButton() override = default;
OverviewCloseButton(const OverviewCloseButton&) = delete;
OverviewCloseButton& operator=(const OverviewCloseButton&) = delete;
// Resets the listener so that the listener can go out of scope. // Resets the listener so that the listener can go out of scope.
void ResetListener() { listener_ = nullptr; } void ResetListener() { listener_ = nullptr; }
...@@ -115,7 +122,6 @@ class OverviewCloseButton : public views::ImageButton { ...@@ -115,7 +122,6 @@ class OverviewCloseButton : public views::ImageButton {
auto ink_drop = std::make_unique<views::InkDropImpl>(this, size()); auto ink_drop = std::make_unique<views::InkDropImpl>(this, size());
ink_drop->SetAutoHighlightMode( ink_drop->SetAutoHighlightMode(
views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE); views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE);
ink_drop->SetShowHighlightOnHover(true);
return ink_drop; return ink_drop;
} }
...@@ -130,21 +136,9 @@ class OverviewCloseButton : public views::ImageButton { ...@@ -130,21 +136,9 @@ class OverviewCloseButton : public views::ImageButton {
return std::make_unique<views::InkDropHighlight>( return std::make_unique<views::InkDropHighlight>(
gfx::PointF(GetLocalBounds().CenterPoint()), gfx::PointF(GetLocalBounds().CenterPoint()),
std::make_unique<views::CircleLayerDelegate>( std::make_unique<views::CircleLayerDelegate>(
kCloseButtonInkDropRippleHighlightColor, GetInkDropRadius())); kCloseButtonInkDropRippleHighlightColor,
} kCloseButtonInkDropRadiusDp));
std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override {
return std::make_unique<views::CircleInkDropMask>(
size(), GetLocalBounds().CenterPoint(), GetInkDropRadius());
} }
private:
int GetInkDropRadius() const {
return std::min(size().width(), size().height()) / 2 -
kCloseButtonInkDropInsetDp;
}
DISALLOW_COPY_AND_ASSIGN(OverviewCloseButton);
}; };
} // namespace } // namespace
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "ui/views/animation/ink_drop_stub.h" #include "ui/views/animation/ink_drop_stub.h"
#include "ui/views/animation/square_ink_drop_ripple.h" #include "ui/views/animation/square_ink_drop_ripple.h"
#include "ui/views/controls/focus_ring.h" #include "ui/views/controls/focus_ring.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/style/platform_style.h" #include "ui/views/style/platform_style.h"
#include "ui/views/view_class_properties.h" #include "ui/views/view_class_properties.h"
...@@ -52,7 +53,9 @@ InkDropHostView::~InkDropHostView() { ...@@ -52,7 +53,9 @@ InkDropHostView::~InkDropHostView() {
} }
void InkDropHostView::AddInkDropLayer(ui::Layer* ink_drop_layer) { void InkDropHostView::AddInkDropLayer(ui::Layer* ink_drop_layer) {
InstallInkDropMask(ink_drop_layer); // If a clip is provided, use that as it is more performant than a mask.
if (!AddInkDropClip(ink_drop_layer))
InstallInkDropMask(ink_drop_layer);
AddLayerBeneathView(ink_drop_layer); AddLayerBeneathView(ink_drop_layer);
} }
...@@ -63,6 +66,11 @@ void InkDropHostView::RemoveInkDropLayer(ui::Layer* ink_drop_layer) { ...@@ -63,6 +66,11 @@ void InkDropHostView::RemoveInkDropLayer(ui::Layer* ink_drop_layer) {
if (destroying_) if (destroying_)
return; return;
RemoveLayerBeneathView(ink_drop_layer); RemoveLayerBeneathView(ink_drop_layer);
// Remove clipping.
ink_drop_layer->SetClipRect(gfx::Rect());
ink_drop_layer->SetRoundedCornerRadius(gfx::RoundedCornersF(0.f));
// Layers safely handle destroying a mask layer before the masked layer. // Layers safely handle destroying a mask layer before the masked layer.
ink_drop_mask_.reset(); ink_drop_mask_.reset();
} }
...@@ -188,6 +196,18 @@ void InkDropHostView::ResetInkDropMask() { ...@@ -188,6 +196,18 @@ void InkDropHostView::ResetInkDropMask() {
ink_drop_mask_.reset(); ink_drop_mask_.reset();
} }
bool InkDropHostView::AddInkDropClip(ui::Layer* ink_drop_layer) {
base::Optional<HighlightPathGenerator::RoundRect> clipping_data =
HighlightPathGenerator::GetRoundRectForView(this);
if (!clipping_data)
return false;
ink_drop_layer->SetClipRect(gfx::ToNearestRect(clipping_data->bounds));
ink_drop_layer->SetRoundedCornerRadius(
gfx::RoundedCornersF(clipping_data->corner_radius));
ink_drop_layer->SetIsFastRoundedCorner(true);
return true;
}
// static // static
gfx::Size InkDropHostView::CalculateLargeInkDropSize( gfx::Size InkDropHostView::CalculateLargeInkDropSize(
const gfx::Size& small_size) { const gfx::Size& small_size) {
......
...@@ -187,11 +187,17 @@ class VIEWS_EXPORT InkDropHostView : public View { ...@@ -187,11 +187,17 @@ class VIEWS_EXPORT InkDropHostView : public View {
gfx::Point GetInkDropCenterBasedOnLastEvent() const; gfx::Point GetInkDropCenterBasedOnLastEvent() const;
// Initializes and sets a mask on |ink_drop_layer|. No-op if // Initializes and sets a mask on |ink_drop_layer|. No-op if
// CreateInkDropMask() returns null. // CreateInkDropMask() returns null. This will not run if |AddInkDropClip()|
// succeeds in the default implementation of |AddInkDropLayer()|.
void InstallInkDropMask(ui::Layer* ink_drop_layer); void InstallInkDropMask(ui::Layer* ink_drop_layer);
void ResetInkDropMask(); void ResetInkDropMask();
// Adds a clip rect on the root layer of the ink drop impl. This is a more
// performant alternative to using circles or rectangle mask layers. Returns
// true if a clip was added.
bool AddInkDropClip(ui::Layer* ink_drop_layer);
// Returns a large ink drop size based on the |small_size| that works well // Returns a large ink drop size based on the |small_size| that works well
// with the SquareInkDropRipple animation durations. // with the SquareInkDropRipple animation durations.
static gfx::Size CalculateLargeInkDropSize(const gfx::Size& small_size); static gfx::Size CalculateLargeInkDropSize(const gfx::Size& small_size);
......
...@@ -13,12 +13,38 @@ namespace views { ...@@ -13,12 +13,38 @@ namespace views {
HighlightPathGenerator::~HighlightPathGenerator() = default; HighlightPathGenerator::~HighlightPathGenerator() = default;
// static
void HighlightPathGenerator::Install( void HighlightPathGenerator::Install(
View* host, View* host,
std::unique_ptr<HighlightPathGenerator> generator) { std::unique_ptr<HighlightPathGenerator> generator) {
host->SetProperty(kHighlightPathGeneratorKey, generator.release()); host->SetProperty(kHighlightPathGeneratorKey, generator.release());
} }
// static
base::Optional<HighlightPathGenerator::RoundRect>
HighlightPathGenerator::GetRoundRectForView(const View* view) {
HighlightPathGenerator* path_generator =
view->GetProperty(kHighlightPathGeneratorKey);
return path_generator ? path_generator->GetRoundRect(view) : base::nullopt;
}
SkPath HighlightPathGenerator::GetHighlightPath(const View* view) {
// A rounded rectangle must be supplied if using this default implementation.
base::Optional<HighlightPathGenerator::RoundRect> round_rect =
GetRoundRect(view);
DCHECK(round_rect);
const float corner_radius = round_rect->corner_radius;
return SkPath().addRoundRect(
gfx::RectToSkRect(gfx::ToNearestRect(round_rect->bounds)), corner_radius,
corner_radius);
}
base::Optional<HighlightPathGenerator::RoundRect>
HighlightPathGenerator::GetRoundRect(const View* view) {
return base::nullopt;
}
SkPath RectHighlightPathGenerator::GetHighlightPath(const View* view) { SkPath RectHighlightPathGenerator::GetHighlightPath(const View* view) {
return SkPath().addRect(gfx::RectToSkRect(view->GetLocalBounds())); return SkPath().addRect(gfx::RectToSkRect(view->GetLocalBounds()));
} }
...@@ -30,9 +56,10 @@ void InstallRectHighlightPathGenerator(View* view) { ...@@ -30,9 +56,10 @@ void InstallRectHighlightPathGenerator(View* view) {
SkPath CircleHighlightPathGenerator::GetHighlightPath(const View* view) { SkPath CircleHighlightPathGenerator::GetHighlightPath(const View* view) {
const SkRect rect = gfx::RectToSkRect(view->GetLocalBounds()); const SkRect rect = gfx::RectToSkRect(view->GetLocalBounds());
const SkScalar radius = SkScalarHalf(std::min(rect.width(), rect.height())); const SkScalar corner_radius =
SkScalarHalf(std::min(rect.width(), rect.height()));
return SkPath().addCircle(rect.centerX(), rect.centerY(), radius); return SkPath().addCircle(rect.centerX(), rect.centerY(), corner_radius);
} }
void InstallCircleHighlightPathGenerator(View* view) { void InstallCircleHighlightPathGenerator(View* view) {
...@@ -42,10 +69,11 @@ void InstallCircleHighlightPathGenerator(View* view) { ...@@ -42,10 +69,11 @@ void InstallCircleHighlightPathGenerator(View* view) {
SkPath PillHighlightPathGenerator::GetHighlightPath(const View* view) { SkPath PillHighlightPathGenerator::GetHighlightPath(const View* view) {
const SkRect rect = gfx::RectToSkRect(view->GetLocalBounds()); const SkRect rect = gfx::RectToSkRect(view->GetLocalBounds());
const SkScalar radius = SkScalarHalf(std::min(rect.width(), rect.height())); const SkScalar corner_radius =
SkScalarHalf(std::min(rect.width(), rect.height()));
return SkPath().addRoundRect(gfx::RectToSkRect(view->GetLocalBounds()), return SkPath().addRoundRect(gfx::RectToSkRect(view->GetLocalBounds()),
radius, radius); corner_radius, corner_radius);
} }
void InstallPillHighlightPathGenerator(View* view) { void InstallPillHighlightPathGenerator(View* view) {
...@@ -53,4 +81,26 @@ void InstallPillHighlightPathGenerator(View* view) { ...@@ -53,4 +81,26 @@ void InstallPillHighlightPathGenerator(View* view) {
view, std::make_unique<PillHighlightPathGenerator>()); view, std::make_unique<PillHighlightPathGenerator>());
} }
FixedSizeCircleHighlightPathGenerator::FixedSizeCircleHighlightPathGenerator(
int corner_radius)
: corner_radius_(corner_radius) {}
base::Optional<HighlightPathGenerator::RoundRect>
FixedSizeCircleHighlightPathGenerator::GetRoundRect(const View* view) {
gfx::RectF bounds(view->GetLocalBounds());
bounds.ClampToCenteredSize(
gfx::SizeF(corner_radius_ * 2, corner_radius_ * 2));
HighlightPathGenerator::RoundRect round_rect;
round_rect.bounds = bounds;
round_rect.corner_radius = corner_radius_;
return base::make_optional(round_rect);
}
void InstallFixedSizeCircleHighlightPathGenerator(View* view,
int corner_radius) {
HighlightPathGenerator::Install(
view,
std::make_unique<FixedSizeCircleHighlightPathGenerator>(corner_radius));
}
} // namespace views } // namespace views
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
#include <memory> #include <memory>
#include "base/optional.h"
#include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPath.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/views/views_export.h" #include "ui/views/views_export.h"
namespace views { namespace views {
...@@ -19,6 +21,11 @@ class View; ...@@ -19,6 +21,11 @@ class View;
// effects. // effects.
class VIEWS_EXPORT HighlightPathGenerator { class VIEWS_EXPORT HighlightPathGenerator {
public: public:
struct RoundRect {
gfx::RectF bounds;
float corner_radius;
};
HighlightPathGenerator() = default; HighlightPathGenerator() = default;
virtual ~HighlightPathGenerator(); virtual ~HighlightPathGenerator();
...@@ -27,8 +34,17 @@ class VIEWS_EXPORT HighlightPathGenerator { ...@@ -27,8 +34,17 @@ class VIEWS_EXPORT HighlightPathGenerator {
static void Install(View* host, static void Install(View* host,
std::unique_ptr<HighlightPathGenerator> generator); std::unique_ptr<HighlightPathGenerator> generator);
static base::Optional<RoundRect> GetRoundRectForView(const View* view);
// TODO(sammiequon): Deprecate |GetHighlightPath()| in favor of
// |GetRoundRect()|.
virtual SkPath GetHighlightPath(const View* view);
virtual SkPath GetHighlightPath(const View* view) = 0; // Optionally returns a RoundRect struct which contains data for drawing a
// highlight.
// TODO(sammiequon): Once |GetHighlightPath()| is deprecated, make this a pure
// virtual function and make the return not optional.
virtual base::Optional<RoundRect> GetRoundRect(const View* view);
}; };
// Sets a rectangular highlight path. // Sets a rectangular highlight path.
...@@ -77,6 +93,28 @@ class VIEWS_EXPORT PillHighlightPathGenerator : public HighlightPathGenerator { ...@@ -77,6 +93,28 @@ class VIEWS_EXPORT PillHighlightPathGenerator : public HighlightPathGenerator {
void VIEWS_EXPORT InstallPillHighlightPathGenerator(View* view); void VIEWS_EXPORT InstallPillHighlightPathGenerator(View* view);
// Sets a centered fixed-size circular highlight path.
class VIEWS_EXPORT FixedSizeCircleHighlightPathGenerator
: public HighlightPathGenerator {
public:
explicit FixedSizeCircleHighlightPathGenerator(int radius);
FixedSizeCircleHighlightPathGenerator(
const FixedSizeCircleHighlightPathGenerator&) = delete;
FixedSizeCircleHighlightPathGenerator& operator=(
const FixedSizeCircleHighlightPathGenerator&) = delete;
// HighlightPathGenerator:
base::Optional<HighlightPathGenerator::RoundRect> GetRoundRect(
const View* view) override;
private:
const int corner_radius_;
};
void VIEWS_EXPORT InstallFixedSizeCircleHighlightPathGenerator(View* view,
int radius);
} // namespace views } // namespace views
#endif // UI_VIEWS_CONTROLS_HIGHLIGHT_PATH_GENERATOR_H_ #endif // UI_VIEWS_CONTROLS_HIGHLIGHT_PATH_GENERATOR_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment