Commit 44ced457 authored by Ana Salazar's avatar Ana Salazar Committed by Commit Bot

Cros: Only round shelf corners when an ink drop is visible

We have rounded corners on the shelf to clip the ink-drop effect,
this causes an additional renderpass. We added an InkDropObserver
to listen for the ink drop animation starting and ending and
toggle the rounded corners as needed.

Bug: 1021772
Change-Id: Icf4aafa6ddb1d917ec8ae07b68fb4063b0b6c995
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2001745Reviewed-by: default avatarManu Cornet <manucornet@chromium.org>
Commit-Queue: Ana Salazar <anasalazar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735063}
parent 1411a948
...@@ -652,6 +652,33 @@ views::View* ScrollableShelfView::GetShelfContainerViewForTest() { ...@@ -652,6 +652,33 @@ views::View* ScrollableShelfView::GetShelfContainerViewForTest() {
return shelf_container_view_; return shelf_container_view_;
} }
void ScrollableShelfView::SetRoundedCornersForShelf(
bool show,
views::View* ink_drop_host) {
shelf_container_view_->layer()->SetRoundedCornerRadius(
show && InkDropNeedsClipping(ink_drop_host)
? CalculateShelfContainerRoundedCorners()
: gfx::RoundedCornersF());
shelf_container_view_->layer()->SetIsFastRoundedCorner(true);
}
bool ScrollableShelfView::InkDropNeedsClipping(views::View* ink_drop_host) {
// The ink drop needs to be clipped only if the host is the app at one of the
// corners of the shelf. This happens if it is either the first or the last
// tappable app and no arrow is showing on its side.
if (shelf_view_->view_model()->view_at(first_tappable_app_index_) ==
ink_drop_host) {
return !(layout_strategy_ == kShowButtons ||
layout_strategy_ == kShowLeftArrowButton);
}
if (shelf_view_->view_model()->view_at(last_tappable_app_index_) ==
ink_drop_host) {
return !(layout_strategy_ == kShowButtons ||
layout_strategy_ == kShowRightArrowButton);
}
return false;
}
bool ScrollableShelfView::ShouldAdjustForTest() const { bool ScrollableShelfView::ShouldAdjustForTest() const {
return CalculateAdjustmentOffset(CalculateMainAxisScrollDistance(), return CalculateAdjustmentOffset(CalculateMainAxisScrollDistance(),
layout_strategy_, GetSpaceForIcons()); layout_strategy_, GetSpaceForIcons());
...@@ -859,9 +886,6 @@ void ScrollableShelfView::Layout() { ...@@ -859,9 +886,6 @@ void ScrollableShelfView::Layout() {
// Layout |shelf_container_view_|. // Layout |shelf_container_view_|.
shelf_container_view_->SetBoundsRect(shelf_container_bounds); shelf_container_view_->SetBoundsRect(shelf_container_bounds);
shelf_container_view_->layer()->SetRoundedCornerRadius(
CalculateShelfContainerRoundedCorners());
} }
void ScrollableShelfView::ChildPreferredSizeChanged(views::View* child) { void ScrollableShelfView::ChildPreferredSizeChanged(views::View* child) {
...@@ -1992,7 +2016,7 @@ ScrollableShelfView::CalculateShelfContainerRoundedCorners() const { ...@@ -1992,7 +2016,7 @@ ScrollableShelfView::CalculateShelfContainerRoundedCorners() const {
const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment(); const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment();
const float radius = (is_horizontal_alignment ? height() : width()) / 2.f; const float radius = (is_horizontal_alignment ? height() : width()) / 2.f;
const int upper_left = left_arrow_->GetVisible() ? 0 : radius; int upper_left = left_arrow_->GetVisible() ? 0 : radius;
int upper_right; int upper_right;
if (is_horizontal_alignment) if (is_horizontal_alignment)
...@@ -2000,7 +2024,7 @@ ScrollableShelfView::CalculateShelfContainerRoundedCorners() const { ...@@ -2000,7 +2024,7 @@ ScrollableShelfView::CalculateShelfContainerRoundedCorners() const {
else else
upper_right = left_arrow_->GetVisible() ? 0 : radius; upper_right = left_arrow_->GetVisible() ? 0 : radius;
const int lower_right = right_arrow_->GetVisible() ? 0 : radius; int lower_right = right_arrow_->GetVisible() ? 0 : radius;
int lower_left; int lower_left;
if (is_horizontal_alignment) if (is_horizontal_alignment)
...@@ -2008,6 +2032,11 @@ ScrollableShelfView::CalculateShelfContainerRoundedCorners() const { ...@@ -2008,6 +2032,11 @@ ScrollableShelfView::CalculateShelfContainerRoundedCorners() const {
else else
lower_left = right_arrow_->GetVisible() ? 0 : radius; lower_left = right_arrow_->GetVisible() ? 0 : radius;
if (ShouldAdaptToRTL()) {
std::swap(upper_left, upper_right);
std::swap(lower_left, lower_right);
}
return gfx::RoundedCornersF(upper_left, upper_right, lower_right, lower_left); return gfx::RoundedCornersF(upper_left, upper_right, lower_right, lower_left);
} }
......
...@@ -93,6 +93,10 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -93,6 +93,10 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
void SetTestObserver(TestObserver* test_observer); void SetTestObserver(TestObserver* test_observer);
void SetRoundedCornersForShelf(bool show, views::View* ink_drop_host);
// Returns whether the ink drop for the |ink_drop_host| needs to be clipped.
bool InkDropNeedsClipping(views::View* ink_drop_host);
ShelfView* shelf_view() { return shelf_view_; } ShelfView* shelf_view() { return shelf_view_; }
ShelfContainerView* shelf_container_view() { return shelf_container_view_; } ShelfContainerView* shelf_container_view() { return shelf_container_view_; }
ScrollArrowView* left_arrow() { return left_arrow_; } ScrollArrowView* left_arrow() { return left_arrow_; }
......
...@@ -462,6 +462,20 @@ class HotseatScrollableShelfViewTest : public ScrollableShelfViewTest { ...@@ -462,6 +462,20 @@ class HotseatScrollableShelfViewTest : public ScrollableShelfViewTest {
scoped_feature_list_.Reset(); scoped_feature_list_.Reset();
} }
bool HasRoundedCornersOnLongTapAtLocation(gfx::Point location) {
GetEventGenerator()->MoveTouch(location);
GetEventGenerator()->PressTouch();
// The gfx::RoundedCornersF object is considered empty when all of the
// corners are squared (no effective radius).
bool has_rounded_corners = !(scrollable_shelf_view_->shelf_container_view()
->layer()
->rounded_corner_radii()
.IsEmpty());
GetEventGenerator()->ReleaseTouch();
return has_rounded_corners;
}
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
}; };
...@@ -544,6 +558,74 @@ TEST_F(HotseatScrollableShelfViewTest, CorrectUIInTabletWithoutOverflow) { ...@@ -544,6 +558,74 @@ TEST_F(HotseatScrollableShelfViewTest, CorrectUIInTabletWithoutOverflow) {
EXPECT_EQ(hotseat_background.right() - 4, last_tappable_view_bounds.right()); EXPECT_EQ(hotseat_background.right() - 4, last_tappable_view_bounds.right());
} }
// Verifies that the scrollable shelf without overflow has the correct layout in
// tablet mode.
TEST_F(HotseatScrollableShelfViewTest, CheckRoundedCornersSetForInkDrop) {
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
AddAppShortcutsUntilOverflow();
ASSERT_EQ(ScrollableShelfView::kShowRightArrowButton,
scrollable_shelf_view_->layout_strategy_for_test());
ASSERT_TRUE(scrollable_shelf_view_->shelf_container_view()
->layer()
->rounded_corner_radii()
.IsEmpty());
views::ViewModel* view_model = shelf_view_->view_model();
gfx::Rect first_tappable_view_bounds =
view_model->view_at(scrollable_shelf_view_->first_tappable_app_index())
->GetBoundsInScreen();
gfx::Rect last_tappable_view_bounds =
view_model->view_at(scrollable_shelf_view_->last_tappable_app_index())
->GetBoundsInScreen();
// When the right arrow is showing, check rounded corners are set if the ink
// drop is visible for the first visible app.
EXPECT_TRUE(HasRoundedCornersOnLongTapAtLocation(
first_tappable_view_bounds.CenterPoint()));
// Tap outside the app and verify that rounded corners are not set if the ink
// drop is hidden.
GetEventGenerator()->GestureTapAt(first_tappable_view_bounds.bottom_center());
EXPECT_TRUE(scrollable_shelf_view_->shelf_container_view()
->layer()
->rounded_corner_radii()
.IsEmpty());
// When the right arrow is showing, check rounded corners are not set if the
// ink drop is visible for the last visible app
EXPECT_FALSE(HasRoundedCornersOnLongTapAtLocation(
last_tappable_view_bounds.CenterPoint()));
// Tap right arrow. Hotseat layout must now show left arrow.
gfx::Rect right_arrow =
scrollable_shelf_view_->right_arrow()->GetBoundsInScreen();
GetEventGenerator()->GestureTapAt(right_arrow.CenterPoint());
ASSERT_EQ(ScrollableShelfView::kShowLeftArrowButton,
scrollable_shelf_view_->layout_strategy_for_test());
// Recalculate first and last view bounds.
first_tappable_view_bounds =
view_model->view_at(scrollable_shelf_view_->first_tappable_app_index())
->GetBoundsInScreen();
last_tappable_view_bounds =
view_model->view_at(scrollable_shelf_view_->last_tappable_app_index())
->GetBoundsInScreen();
// When the left arrow is showing, check rounded corners are set if the ink
// drop is visible for the last visible app.
EXPECT_TRUE(HasRoundedCornersOnLongTapAtLocation(
last_tappable_view_bounds.CenterPoint()));
// Tap outside the app and verify that rounded corners are not set if the ink
// drop is hidden.
GetEventGenerator()->GestureTapAt(last_tappable_view_bounds.bottom_center());
EXPECT_TRUE(scrollable_shelf_view_->shelf_container_view()
->layer()
->rounded_corner_radii()
.IsEmpty());
// When the left arrow is showing, check rounded corners are not set if the
// ink drop is visible for the first visible app
EXPECT_FALSE(HasRoundedCornersOnLongTapAtLocation(
first_tappable_view_bounds.CenterPoint()));
}
// Verifies that doing a mousewheel scroll on the scrollable shelf does scroll // Verifies that doing a mousewheel scroll on the scrollable shelf does scroll
// forward. // forward.
TEST_F(ScrollableShelfViewTest, ScrollWithMouseWheel) { TEST_F(ScrollableShelfViewTest, ScrollWithMouseWheel) {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "ash/public/cpp/shelf_model.h" #include "ash/public/cpp/shelf_model.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/root_window_controller.h" #include "ash/root_window_controller.h"
#include "ash/shelf/scrollable_shelf_view.h"
#include "ash/shelf/shelf_controller.h" #include "ash/shelf/shelf_controller.h"
#include "ash/shelf/shelf_focus_cycler.h" #include "ash/shelf/shelf_focus_cycler.h"
#include "ash/shelf/shelf_layout_manager.h" #include "ash/shelf/shelf_layout_manager.h"
...@@ -447,6 +448,15 @@ void Shelf::SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds) { ...@@ -447,6 +448,15 @@ void Shelf::SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds) {
work_area_insets->OnKeyboardAppearanceChanged(state); work_area_insets->OnKeyboardAppearanceChanged(state);
} }
void Shelf::SetRoundedCornersForInkDrop(bool show, views::View* ink_drop_host) {
if (!shelf_widget_->hotseat_widget() ||
!shelf_widget_->hotseat_widget()->scrollable_shelf_view())
return;
shelf_widget_->hotseat_widget()
->scrollable_shelf_view()
->SetRoundedCornersForShelf(show, ink_drop_host);
}
ShelfLockingManager* Shelf::GetShelfLockingManagerForTesting() { ShelfLockingManager* Shelf::GetShelfLockingManagerForTesting() {
return &shelf_locking_manager_; return &shelf_locking_manager_;
} }
......
...@@ -27,6 +27,10 @@ class MouseWheelEvent; ...@@ -27,6 +27,10 @@ class MouseWheelEvent;
class MouseEvent; class MouseEvent;
} }
namespace views {
class View;
}
namespace ash { namespace ash {
enum class AnimationChangeType; enum class AnimationChangeType;
...@@ -165,6 +169,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver { ...@@ -165,6 +169,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
bool ShouldHideOnSecondaryDisplay(session_manager::SessionState state); bool ShouldHideOnSecondaryDisplay(session_manager::SessionState state);
void SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds); void SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds);
void SetRoundedCornersForInkDrop(bool show, views::View* ink_drop_host);
ShelfLockingManager* GetShelfLockingManagerForTesting(); ShelfLockingManager* GetShelfLockingManagerForTesting();
ShelfView* GetShelfViewForTesting(); ShelfView* GetShelfViewForTesting();
......
...@@ -334,9 +334,11 @@ ShelfAppButton::ShelfAppButton(ShelfView* shelf_view, ...@@ -334,9 +334,11 @@ ShelfAppButton::ShelfAppButton(ShelfView* shelf_view,
notification_indicator_->SetVisible(false); notification_indicator_->SetVisible(false);
AddChildView(notification_indicator_); AddChildView(notification_indicator_);
} }
GetInkDrop()->AddObserver(this);
} }
ShelfAppButton::~ShelfAppButton() { ShelfAppButton::~ShelfAppButton() {
GetInkDrop()->RemoveObserver(this);
if (destroyed_flag_) if (destroyed_flag_)
*destroyed_flag_ = true; *destroyed_flag_ = true;
} }
...@@ -662,6 +664,17 @@ void ShelfAppButton::ChildPreferredSizeChanged(views::View* child) { ...@@ -662,6 +664,17 @@ void ShelfAppButton::ChildPreferredSizeChanged(views::View* child) {
Layout(); Layout();
} }
void ShelfAppButton::InkDropAnimationStarted() {
shelf_view_->shelf()->SetRoundedCornersForInkDrop(/*show=*/true,
/*ink_drop_host=*/this);
}
void ShelfAppButton::InkDropRippleAnimationEnded(views::InkDropState state) {
if (state == views::InkDropState::HIDDEN)
shelf_view_->shelf()->SetRoundedCornersForInkDrop(/*show=*/false,
/*ink_drop_host=*/this);
}
void ShelfAppButton::OnGestureEvent(ui::GestureEvent* event) { void ShelfAppButton::OnGestureEvent(ui::GestureEvent* event) {
switch (event->type()) { switch (event->type()) {
case ui::ET_GESTURE_TAP_DOWN: case ui::ET_GESTURE_TAP_DOWN:
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "ui/gfx/shadow_value.h" #include "ui/gfx/shadow_value.h"
#include "ui/views/animation/ink_drop_observer.h"
#include "ui/views/animation/ink_drop_state.h"
namespace views { namespace views {
class ImageView; class ImageView;
...@@ -20,7 +22,8 @@ struct ShelfItem; ...@@ -20,7 +22,8 @@ struct ShelfItem;
class ShelfView; class ShelfView;
// Button used for app shortcuts on the shelf.. // Button used for app shortcuts on the shelf..
class ASH_EXPORT ShelfAppButton : public ShelfButton { class ASH_EXPORT ShelfAppButton : public ShelfButton,
public views::InkDropObserver {
public: public:
static const char kViewClassName[]; static const char kViewClassName[];
...@@ -86,6 +89,10 @@ class ASH_EXPORT ShelfAppButton : public ShelfButton { ...@@ -86,6 +89,10 @@ class ASH_EXPORT ShelfAppButton : public ShelfButton {
void Layout() override; void Layout() override;
void ChildPreferredSizeChanged(views::View* child) override; void ChildPreferredSizeChanged(views::View* child) override;
// views::InkDropListener:
void InkDropAnimationStarted() override;
void InkDropRippleAnimationEnded(views::InkDropState state) override;
// Update button state from ShelfItem. // Update button state from ShelfItem.
void ReflectItemStatus(const ShelfItem& item); void ReflectItemStatus(const ShelfItem& item);
......
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