Commit 9017789b authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

[scrollable shelf] Add additional gradient zone

This CL adds the left gradient zone during gesture drag and scrolling
animation.

Bug: 1004134
Change-Id: I134b0ea33ae06cbfe0974113ed08203d2b8c63cd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1818118
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700450}
parent f2b5b01e
...@@ -100,7 +100,19 @@ class ScrollableShelfView::GradientLayerDelegate : public ui::LayerDelegate { ...@@ -100,7 +100,19 @@ class ScrollableShelfView::GradientLayerDelegate : public ui::LayerDelegate {
~GradientLayerDelegate() override { layer_.set_delegate(nullptr); } ~GradientLayerDelegate() override { layer_.set_delegate(nullptr); }
void set_fade_zone(const FadeZone& fade_zone) { fade_zone_ = fade_zone; } bool IsStartFadeZoneVisible() const {
return !start_fade_zone_.zone_rect.IsEmpty();
}
bool IsEndFadeZoneVisible() const {
return !end_fade_zone_.zone_rect.IsEmpty();
}
void set_start_fade_zone(const FadeZone& fade_zone) {
start_fade_zone_ = fade_zone;
}
void set_end_fade_zone(const FadeZone& fade_zone) {
end_fade_zone_ = fade_zone;
}
ui::Layer* layer() { return &layer_; } ui::Layer* layer() { return &layer_; }
private: private:
...@@ -120,33 +132,43 @@ class ScrollableShelfView::GradientLayerDelegate : public ui::LayerDelegate { ...@@ -120,33 +132,43 @@ class ScrollableShelfView::GradientLayerDelegate : public ui::LayerDelegate {
static_cast<float>(paint_recording_size.height()) / size.height(), static_cast<float>(paint_recording_size.height()) / size.height(),
nullptr); nullptr);
recorder.canvas()->DrawColor(SK_ColorBLACK, SkBlendMode::kSrc);
if (!start_fade_zone_.zone_rect.IsEmpty())
DrawFadeZone(start_fade_zone_, recorder.canvas());
if (!end_fade_zone_.zone_rect.IsEmpty())
DrawFadeZone(end_fade_zone_, recorder.canvas());
}
void OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) override {}
void DrawFadeZone(const FadeZone& fade_zone, gfx::Canvas* canvas) {
gfx::Point start_point; gfx::Point start_point;
gfx::Point end_point; gfx::Point end_point;
if (fade_zone_.is_horizontal) { if (fade_zone.is_horizontal) {
start_point = gfx::Point(fade_zone_.zone_rect.x(), 0); start_point = gfx::Point(fade_zone.zone_rect.x(), 0);
end_point = gfx::Point(fade_zone_.zone_rect.right(), 0); end_point = gfx::Point(fade_zone.zone_rect.right(), 0);
} else { } else {
start_point = gfx::Point(0, fade_zone_.zone_rect.y()); start_point = gfx::Point(0, fade_zone.zone_rect.y());
end_point = gfx::Point(0, fade_zone_.zone_rect.bottom()); end_point = gfx::Point(0, fade_zone.zone_rect.bottom());
} }
gfx::Canvas* canvas = recorder.canvas();
canvas->DrawColor(SK_ColorBLACK, SkBlendMode::kSrc);
cc::PaintFlags flags; cc::PaintFlags flags;
flags.setBlendMode(SkBlendMode::kSrc); flags.setBlendMode(SkBlendMode::kSrc);
flags.setAntiAlias(false); flags.setAntiAlias(false);
flags.setShader(gfx::CreateGradientShader( flags.setShader(gfx::CreateGradientShader(
start_point, end_point, start_point, end_point,
fade_zone_.fade_in ? SK_ColorTRANSPARENT : SK_ColorBLACK, fade_zone.fade_in ? SK_ColorTRANSPARENT : SK_ColorBLACK,
fade_zone_.fade_in ? SK_ColorBLACK : SK_ColorTRANSPARENT)); fade_zone.fade_in ? SK_ColorBLACK : SK_ColorTRANSPARENT));
canvas->DrawRect(fade_zone_.zone_rect, flags); canvas->DrawRect(fade_zone.zone_rect, flags);
} }
void OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) override {}
ui::Layer layer_; ui::Layer layer_;
FadeZone fade_zone_;
FadeZone start_fade_zone_;
FadeZone end_fade_zone_;
DISALLOW_COPY_AND_ASSIGN(GradientLayerDelegate); DISALLOW_COPY_AND_ASSIGN(GradientLayerDelegate);
}; };
...@@ -302,18 +324,17 @@ void ScrollableShelfView::OnFocusRingActivationChanged(bool activated) { ...@@ -302,18 +324,17 @@ void ScrollableShelfView::OnFocusRingActivationChanged(bool activated) {
if (activated) { if (activated) {
focus_ring_activated_ = true; focus_ring_activated_ = true;
SetPaneFocusAndFocusDefault(); SetPaneFocusAndFocusDefault();
// Clears the gradient shader when the focus ring shows.
FadeZone fade_zone = {/*zone_rect=*/gfx::Rect(), /*fade_in=*/false,
/*is_horizontal=*/false};
gradient_layer_delegate_->set_fade_zone(fade_zone);
gradient_layer_delegate_->layer()->SetBounds(layer()->bounds());
SchedulePaint();
} else { } else {
// Shows the gradient shader when the focus ring is disabled. // Shows the gradient shader when the focus ring is disabled.
focus_ring_activated_ = false; focus_ring_activated_ = false;
UpdateGradientZone();
} }
// Not needs to update the gradient areas. Returns early.
if (layout_strategy_ == kNotShowArrowButtons)
return;
UpdateGradientZoneState();
UpdateGradientZone();
} }
void ScrollableShelfView::ScrollToNewPage(bool forward) { void ScrollableShelfView::ScrollToNewPage(bool forward) {
...@@ -381,6 +402,17 @@ float ScrollableShelfView::CalculateClampedScrollOffset(float scroll) const { ...@@ -381,6 +402,17 @@ float ScrollableShelfView::CalculateClampedScrollOffset(float scroll) const {
} }
void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) { void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) {
during_scrolling_animation_ = true;
// Shows the gradient zones if needed.
UpdateGradientZoneState();
if (gradient_layer_delegate_->IsStartFadeZoneVisible() !=
should_show_start_gradient_zone_ ||
gradient_layer_delegate_->IsEndFadeZoneVisible() !=
should_show_end_gradient_zone_) {
UpdateGradientZone();
}
const gfx::Transform current_transform = shelf_view_->GetTransform(); const gfx::Transform current_transform = shelf_view_->GetTransform();
gfx::Transform reverse_transform = current_transform; gfx::Transform reverse_transform = current_transform;
if (ShouldAdaptToRTL()) if (ShouldAdaptToRTL())
...@@ -395,6 +427,7 @@ void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) { ...@@ -395,6 +427,7 @@ void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) {
animation_settings.SetTweenType(gfx::Tween::EASE_OUT); animation_settings.SetTweenType(gfx::Tween::EASE_OUT);
animation_settings.SetPreemptionStrategy( animation_settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
animation_settings.AddObserver(this);
shelf_view_->layer()->SetTransform(current_transform); shelf_view_->layer()->SetTransform(current_transform);
} }
...@@ -539,7 +572,9 @@ void ScrollableShelfView::Layout() { ...@@ -539,7 +572,9 @@ void ScrollableShelfView::Layout() {
shelf_container_bounds.Transpose(); shelf_container_bounds.Transpose();
} }
// Check the change in |right_arrow_|'s bounds or the visibility. const bool is_left_arrow_changed =
(left_arrow_->bounds() != left_arrow_bounds) ||
(!left_arrow_bounds.IsEmpty() && !left_arrow_->GetVisible());
const bool is_right_arrow_changed = const bool is_right_arrow_changed =
(right_arrow_->bounds() != right_arrow_bounds) || (right_arrow_->bounds() != right_arrow_bounds) ||
(!right_arrow_bounds.IsEmpty() && !right_arrow_->GetVisible()); (!right_arrow_bounds.IsEmpty() && !right_arrow_->GetVisible());
...@@ -557,11 +592,22 @@ void ScrollableShelfView::Layout() { ...@@ -557,11 +592,22 @@ void ScrollableShelfView::Layout() {
if (gradient_layer_delegate_->layer()->bounds() != layer()->bounds()) if (gradient_layer_delegate_->layer()->bounds() != layer()->bounds())
gradient_layer_delegate_->layer()->SetBounds(layer()->bounds()); gradient_layer_delegate_->layer()->SetBounds(layer()->bounds());
// Fade zones should be updated if:
// (1) Fade zone's visibility changes.
// (2) Fade zone should show and the arrow button's location changes.
UpdateGradientZoneState();
const bool should_update_end_fade_zone =
(should_show_end_gradient_zone_ !=
gradient_layer_delegate_->IsEndFadeZoneVisible()) ||
(should_show_end_gradient_zone_ && is_right_arrow_changed);
const bool should_update_start_fade_zone =
(should_show_start_gradient_zone_ !=
gradient_layer_delegate_->IsStartFadeZoneVisible()) ||
(should_show_start_gradient_zone_ && is_left_arrow_changed);
// Bounds of the gradient zone are relative to the location of arrow buttons. // Bounds of the gradient zone are relative to the location of arrow buttons.
// So updates the gradient zone after the bounds of arrow buttons are set. // So updates the gradient zone after the bounds of arrow buttons are set.
// The gradient zone is not painted when the focus ring shows in order to if (should_update_start_fade_zone || should_update_end_fade_zone)
// display the focus ring correctly.
if (is_right_arrow_changed && !focus_ring_activated_)
UpdateGradientZone(); UpdateGradientZone();
// Layout |shelf_container_view_|. // Layout |shelf_container_view_|.
...@@ -701,6 +747,11 @@ views::View* ScrollableShelfView::GetViewForEvent(const ui::Event& event) { ...@@ -701,6 +747,11 @@ views::View* ScrollableShelfView::GetViewForEvent(const ui::Event& event) {
return nullptr; return nullptr;
} }
void ScrollableShelfView::OnImplicitAnimationsCompleted() {
during_scrolling_animation_ = false;
Layout();
}
gfx::Insets ScrollableShelfView::CalculateEdgePadding() const { gfx::Insets ScrollableShelfView::CalculateEdgePadding() const {
// Display centering alignment // Display centering alignment
if (ShouldApplyDisplayCentering()) if (ShouldApplyDisplayCentering())
...@@ -964,28 +1015,23 @@ float ScrollableShelfView::CalculatePageScrollingOffset(bool forward) const { ...@@ -964,28 +1015,23 @@ float ScrollableShelfView::CalculatePageScrollingOffset(bool forward) const {
} }
void ScrollableShelfView::UpdateGradientZone() { void ScrollableShelfView::UpdateGradientZone() {
FadeZone fade_zone = {/*zone_rect=*/gfx::Rect(), /*fade_in=*/false, gradient_layer_delegate_->set_start_fade_zone(CalculateStartGradientZone());
/*is_horizontal=*/false}; gradient_layer_delegate_->set_end_fade_zone(CalculateEndGradientZone());
// Calculates the bounds of the gradient zone based on the arrow buttons'
// location.
if (right_arrow_->GetVisible())
fade_zone = CalculateEndGradientZone();
else if (left_arrow_->GetVisible())
fade_zone = CalculateStartGradientZone();
gradient_layer_delegate_->set_fade_zone(fade_zone);
SchedulePaint(); SchedulePaint();
} }
ScrollableShelfView::FadeZone ScrollableShelfView::CalculateStartGradientZone() ScrollableShelfView::FadeZone ScrollableShelfView::CalculateStartGradientZone()
const { const {
gfx::Rect zone_rect; gfx::Rect zone_rect;
bool fade_in; bool fade_in = false;
const int zone_length = GetFadeZoneLength(); const int zone_length = GetFadeZoneLength();
const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment(); const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment();
const gfx::Rect left_arrow_bounds = left_arrow_->bounds(); const gfx::Rect left_arrow_bounds = left_arrow_->bounds();
if (!should_show_start_gradient_zone_)
return FadeZone();
if (is_horizontal_alignment) { if (is_horizontal_alignment) {
int x; int x;
...@@ -1010,11 +1056,14 @@ ScrollableShelfView::FadeZone ScrollableShelfView::CalculateStartGradientZone() ...@@ -1010,11 +1056,14 @@ ScrollableShelfView::FadeZone ScrollableShelfView::CalculateStartGradientZone()
ScrollableShelfView::FadeZone ScrollableShelfView::CalculateEndGradientZone() ScrollableShelfView::FadeZone ScrollableShelfView::CalculateEndGradientZone()
const { const {
gfx::Rect zone_rect; gfx::Rect zone_rect;
bool fade_in; bool fade_in = false;
const int zone_length = GetFadeZoneLength(); const int zone_length = GetFadeZoneLength();
const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment(); const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment();
const gfx::Rect right_arrow_bounds = right_arrow_->bounds(); const gfx::Rect right_arrow_bounds = right_arrow_->bounds();
if (!should_show_end_gradient_zone_)
return FadeZone();
if (is_horizontal_alignment) { if (is_horizontal_alignment) {
int x; int x;
...@@ -1037,6 +1086,27 @@ ScrollableShelfView::FadeZone ScrollableShelfView::CalculateEndGradientZone() ...@@ -1037,6 +1086,27 @@ ScrollableShelfView::FadeZone ScrollableShelfView::CalculateEndGradientZone()
return {zone_rect, fade_in, is_horizontal_alignment}; return {zone_rect, fade_in, is_horizontal_alignment};
} }
void ScrollableShelfView::UpdateGradientZoneState() {
// The gradient zone is not painted when the focus ring shows in order to
// display the focus ring correctly.
if (focus_ring_activated_) {
should_show_start_gradient_zone_ = false;
should_show_end_gradient_zone_ = false;
return;
}
if (during_scrolling_animation_) {
should_show_start_gradient_zone_ = left_arrow_->GetVisible();
should_show_end_gradient_zone_ = right_arrow_->GetVisible();
return;
}
should_show_start_gradient_zone_ = layout_strategy_ == kShowLeftArrowButton ||
(layout_strategy_ == kShowButtons &&
scroll_status_ == kAlongMainAxisScroll);
should_show_end_gradient_zone_ = right_arrow_->GetVisible();
}
int ScrollableShelfView::GetActualScrollOffset() const { int ScrollableShelfView::GetActualScrollOffset() const {
int scroll_distance = GetShelf()->IsHorizontalAlignment() int scroll_distance = GetShelf()->IsHorizontalAlignment()
? scroll_offset_.x() ? scroll_offset_.x()
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "ash/shelf/shelf_container_view.h" #include "ash/shelf/shelf_container_view.h"
#include "ash/shelf/shelf_tooltip_delegate.h" #include "ash/shelf/shelf_tooltip_delegate.h"
#include "ash/shelf/shelf_view.h" #include "ash/shelf/shelf_view.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/views/animation/ink_drop_host_view.h" #include "ui/views/animation/ink_drop_host_view.h"
#include "ui/views/context_menu_controller.h" #include "ui/views/context_menu_controller.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
...@@ -27,7 +28,8 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -27,7 +28,8 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
public ShellObserver, public ShellObserver,
public ShelfButtonDelegate, public ShelfButtonDelegate,
public ShelfTooltipDelegate, public ShelfTooltipDelegate,
public views::ContextMenuController { public views::ContextMenuController,
public ui::ImplicitAnimationObserver {
public: public:
enum LayoutStrategy { enum LayoutStrategy {
// The arrow buttons are not shown. It means that there is enough space to // The arrow buttons are not shown. It means that there is enough space to
...@@ -169,6 +171,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -169,6 +171,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
base::string16 GetTitleForView(const views::View* view) const override; base::string16 GetTitleForView(const views::View* view) const override;
views::View* GetViewForEvent(const ui::Event& event) override; views::View* GetViewForEvent(const ui::Event& event) override;
// ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override;
// Returns the padding inset. Different Padding strategies for three scenarios // Returns the padding inset. Different Padding strategies for three scenarios
// (1) display centering alignment // (1) display centering alignment
// (2) scrollable shelf centering alignment // (2) scrollable shelf centering alignment
...@@ -214,6 +219,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -214,6 +219,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
FadeZone CalculateStartGradientZone() const; FadeZone CalculateStartGradientZone() const;
FadeZone CalculateEndGradientZone() const; FadeZone CalculateEndGradientZone() const;
// Updates the visibility of gradient zones.
void UpdateGradientZoneState();
// Returns the actual scroll offset on the view's main axis. When the left // Returns the actual scroll offset on the view's main axis. When the left
// arrow button shows, |shelf_view_| is translated due to the change in // arrow button shows, |shelf_view_| is translated due to the change in
// |shelf_container_view_|'s bounds. That translation offset is not included // |shelf_container_view_|'s bounds. That translation offset is not included
...@@ -278,6 +286,14 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -278,6 +286,14 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// ScrollableShelfView is enabled. // ScrollableShelfView is enabled.
bool focus_ring_activated_ = false; bool focus_ring_activated_ = false;
// Indicates that the view is during the scrolling animation.
bool during_scrolling_animation_ = false;
// Indicates whether the gradient zone before/after the shelf container view
// should show.
bool should_show_start_gradient_zone_ = false;
bool should_show_end_gradient_zone_ = false;
DISALLOW_COPY_AND_ASSIGN(ScrollableShelfView); DISALLOW_COPY_AND_ASSIGN(ScrollableShelfView);
}; };
......
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