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 {
~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_; }
private:
......@@ -120,33 +132,43 @@ class ScrollableShelfView::GradientLayerDelegate : public ui::LayerDelegate {
static_cast<float>(paint_recording_size.height()) / size.height(),
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 end_point;
if (fade_zone_.is_horizontal) {
start_point = gfx::Point(fade_zone_.zone_rect.x(), 0);
end_point = gfx::Point(fade_zone_.zone_rect.right(), 0);
if (fade_zone.is_horizontal) {
start_point = gfx::Point(fade_zone.zone_rect.x(), 0);
end_point = gfx::Point(fade_zone.zone_rect.right(), 0);
} else {
start_point = gfx::Point(0, fade_zone_.zone_rect.y());
end_point = gfx::Point(0, fade_zone_.zone_rect.bottom());
start_point = gfx::Point(0, fade_zone.zone_rect.y());
end_point = gfx::Point(0, fade_zone.zone_rect.bottom());
}
gfx::Canvas* canvas = recorder.canvas();
canvas->DrawColor(SK_ColorBLACK, SkBlendMode::kSrc);
cc::PaintFlags flags;
flags.setBlendMode(SkBlendMode::kSrc);
flags.setAntiAlias(false);
flags.setShader(gfx::CreateGradientShader(
start_point, end_point,
fade_zone_.fade_in ? SK_ColorTRANSPARENT : SK_ColorBLACK,
fade_zone_.fade_in ? SK_ColorBLACK : SK_ColorTRANSPARENT));
fade_zone.fade_in ? SK_ColorTRANSPARENT : SK_ColorBLACK,
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_;
FadeZone fade_zone_;
FadeZone start_fade_zone_;
FadeZone end_fade_zone_;
DISALLOW_COPY_AND_ASSIGN(GradientLayerDelegate);
};
......@@ -302,18 +324,17 @@ void ScrollableShelfView::OnFocusRingActivationChanged(bool activated) {
if (activated) {
focus_ring_activated_ = true;
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 {
// Shows the gradient shader when the focus ring is disabled.
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) {
......@@ -381,6 +402,17 @@ float ScrollableShelfView::CalculateClampedScrollOffset(float scroll) const {
}
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();
gfx::Transform reverse_transform = current_transform;
if (ShouldAdaptToRTL())
......@@ -395,6 +427,7 @@ void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) {
animation_settings.SetTweenType(gfx::Tween::EASE_OUT);
animation_settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
animation_settings.AddObserver(this);
shelf_view_->layer()->SetTransform(current_transform);
}
......@@ -539,7 +572,9 @@ void ScrollableShelfView::Layout() {
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 =
(right_arrow_->bounds() != right_arrow_bounds) ||
(!right_arrow_bounds.IsEmpty() && !right_arrow_->GetVisible());
......@@ -557,11 +592,22 @@ void ScrollableShelfView::Layout() {
if (gradient_layer_delegate_->layer()->bounds() != 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.
// 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
// display the focus ring correctly.
if (is_right_arrow_changed && !focus_ring_activated_)
if (should_update_start_fade_zone || should_update_end_fade_zone)
UpdateGradientZone();
// Layout |shelf_container_view_|.
......@@ -701,6 +747,11 @@ views::View* ScrollableShelfView::GetViewForEvent(const ui::Event& event) {
return nullptr;
}
void ScrollableShelfView::OnImplicitAnimationsCompleted() {
during_scrolling_animation_ = false;
Layout();
}
gfx::Insets ScrollableShelfView::CalculateEdgePadding() const {
// Display centering alignment
if (ShouldApplyDisplayCentering())
......@@ -964,28 +1015,23 @@ float ScrollableShelfView::CalculatePageScrollingOffset(bool forward) const {
}
void ScrollableShelfView::UpdateGradientZone() {
FadeZone fade_zone = {/*zone_rect=*/gfx::Rect(), /*fade_in=*/false,
/*is_horizontal=*/false};
gradient_layer_delegate_->set_start_fade_zone(CalculateStartGradientZone());
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();
}
ScrollableShelfView::FadeZone ScrollableShelfView::CalculateStartGradientZone()
const {
gfx::Rect zone_rect;
bool fade_in;
bool fade_in = false;
const int zone_length = GetFadeZoneLength();
const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment();
const gfx::Rect left_arrow_bounds = left_arrow_->bounds();
if (!should_show_start_gradient_zone_)
return FadeZone();
if (is_horizontal_alignment) {
int x;
......@@ -1010,11 +1056,14 @@ ScrollableShelfView::FadeZone ScrollableShelfView::CalculateStartGradientZone()
ScrollableShelfView::FadeZone ScrollableShelfView::CalculateEndGradientZone()
const {
gfx::Rect zone_rect;
bool fade_in;
bool fade_in = false;
const int zone_length = GetFadeZoneLength();
const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment();
const gfx::Rect right_arrow_bounds = right_arrow_->bounds();
if (!should_show_end_gradient_zone_)
return FadeZone();
if (is_horizontal_alignment) {
int x;
......@@ -1037,6 +1086,27 @@ ScrollableShelfView::FadeZone ScrollableShelfView::CalculateEndGradientZone()
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 scroll_distance = GetShelf()->IsHorizontalAlignment()
? scroll_offset_.x()
......
......@@ -13,6 +13,7 @@
#include "ash/shelf/shelf_container_view.h"
#include "ash/shelf/shelf_tooltip_delegate.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/context_menu_controller.h"
#include "ui/views/controls/button/button.h"
......@@ -27,7 +28,8 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
public ShellObserver,
public ShelfButtonDelegate,
public ShelfTooltipDelegate,
public views::ContextMenuController {
public views::ContextMenuController,
public ui::ImplicitAnimationObserver {
public:
enum LayoutStrategy {
// 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,
base::string16 GetTitleForView(const views::View* view) const override;
views::View* GetViewForEvent(const ui::Event& event) override;
// ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override;
// Returns the padding inset. Different Padding strategies for three scenarios
// (1) display centering alignment
// (2) scrollable shelf centering alignment
......@@ -214,6 +219,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
FadeZone CalculateStartGradientZone() 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
// arrow button shows, |shelf_view_| is translated due to the change in
// |shelf_container_view_|'s bounds. That translation offset is not included
......@@ -278,6 +286,14 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// ScrollableShelfView is enabled.
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);
};
......
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