Commit aec33eab authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

Provide feedback for pinning app - part 1

To solve the issue 1012772, we need to implement an interface to
scroll the shelf view to show the icon for a given app id. This CL
provides the following helper functions:
(1) Calculates the offset distance of scrolling Shelf to the
previous/next page.
(2) Calculates the layout strategy for the given scroll distance.
(3) Calculates the first/last tappable app indices for the given
layout strategy and scroll offset.

No UI changes should be introduced by this CL.

Bug: 1012772
Change-Id: I3aa27d0fa035f9a9a3186bbe9963065afe465f89
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1762558Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715870}
parent aa63b9ce
...@@ -487,7 +487,7 @@ void ScrollableShelfView::OnFocusRingActivationChanged(bool activated) { ...@@ -487,7 +487,7 @@ void ScrollableShelfView::OnFocusRingActivationChanged(bool activated) {
} }
void ScrollableShelfView::ScrollToNewPage(bool forward) { void ScrollableShelfView::ScrollToNewPage(bool forward) {
float offset = CalculatePageScrollingOffset(forward); const float offset = CalculatePageScrollingOffset(forward, layout_strategy_);
if (GetShelf()->IsHorizontalAlignment()) if (GetShelf()->IsHorizontalAlignment())
ScrollByXOffset(offset, /*animating=*/true); ScrollByXOffset(offset, /*animating=*/true);
else else
...@@ -596,25 +596,25 @@ void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) { ...@@ -596,25 +596,25 @@ void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) {
shelf_view_->layer()->SetTransform(current_transform); shelf_view_->layer()->SetTransform(current_transform);
} }
void ScrollableShelfView::UpdateLayoutStrategy() { ScrollableShelfView::LayoutStrategy
if (CanFitAllAppsWithoutScrolling()) { ScrollableShelfView::CalculateLayoutStrategy(
layout_strategy_ = kNotShowArrowButtons; int scroll_distance_on_main_axis) const {
return; if (CanFitAllAppsWithoutScrolling())
} return kNotShowArrowButtons;
int scroll_length = GetShelf()->IsHorizontalAlignment() ? scroll_offset_.x() if (scroll_distance_on_main_axis == 0) {
: scroll_offset_.y();
if (scroll_length == 0) {
// No invisible shelf buttons at the left side. So hide the left button. // No invisible shelf buttons at the left side. So hide the left button.
layout_strategy_ = kShowRightArrowButton; return kShowRightArrowButton;
} else if (scroll_length == CalculateScrollUpperBound()) { }
if (scroll_distance_on_main_axis == CalculateScrollUpperBound()) {
// If there is no invisible shelf button at the right side, hide the right // If there is no invisible shelf button at the right side, hide the right
// button. // button.
layout_strategy_ = kShowLeftArrowButton; return kShowLeftArrowButton;
} else {
// There are invisible shelf buttons at both sides. So show two buttons.
layout_strategy_ = kShowButtons;
} }
// There are invisible shelf buttons at both sides. So show two buttons.
return kShowButtons;
} }
bool ScrollableShelfView::ShouldAdaptToRTL() const { bool ScrollableShelfView::ShouldAdaptToRTL() const {
...@@ -681,7 +681,7 @@ void ScrollableShelfView::Layout() { ...@@ -681,7 +681,7 @@ void ScrollableShelfView::Layout() {
else else
scroll_offset_.set_y(CalculateClampedScrollOffset(scroll_offset_.y())); scroll_offset_.set_y(CalculateClampedScrollOffset(scroll_offset_.y()));
UpdateLayoutStrategy(); layout_strategy_ = CalculateLayoutStrategy(CalculateMainAxisScrollDistance());
gfx::Size arrow_button_size(kArrowButtonSize, kArrowButtonSize); gfx::Size arrow_button_size(kArrowButtonSize, kArrowButtonSize);
gfx::Rect shelf_container_bounds = gfx::Rect(size()); gfx::Rect shelf_container_bounds = gfx::Rect(size());
...@@ -1221,7 +1221,7 @@ bool ScrollableShelfView::ProcessGestureEvent(const ui::GestureEvent& event) { ...@@ -1221,7 +1221,7 @@ bool ScrollableShelfView::ProcessGestureEvent(const ui::GestureEvent& event) {
? event.details().velocity_x() ? event.details().velocity_x()
: event.details().velocity_y(); : event.details().velocity_y();
float page_scrolling_offset = float page_scrolling_offset =
CalculatePageScrollingOffset(scroll_velocity < 0); CalculatePageScrollingOffset(scroll_velocity < 0, layout_strategy_);
if (is_horizontal_alignment) { if (is_horizontal_alignment) {
ScrollToXOffset( ScrollToXOffset(
scroll_offset_before_main_axis_scrolling_.x() + page_scrolling_offset, scroll_offset_before_main_axis_scrolling_.x() + page_scrolling_offset,
...@@ -1277,11 +1277,13 @@ void ScrollableShelfView::HandleMouseWheelEvent(ui::MouseWheelEvent* event) { ...@@ -1277,11 +1277,13 @@ void ScrollableShelfView::HandleMouseWheelEvent(ui::MouseWheelEvent* event) {
// contents. // contents.
float max_absolute_offset = float max_absolute_offset =
abs(x_offset) > abs(y_offset) ? x_offset : y_offset; abs(x_offset) > abs(y_offset) ? x_offset : y_offset;
ScrollByXOffset(CalculatePageScrollingOffset(max_absolute_offset < 0), ScrollByXOffset(
/*animating=*/true); CalculatePageScrollingOffset(max_absolute_offset < 0, layout_strategy_),
/*animating=*/true);
} else { } else {
ScrollByYOffset(CalculatePageScrollingOffset(event->y_offset() < 0), ScrollByYOffset(
/*animating=*/true); CalculatePageScrollingOffset(event->y_offset() < 0, layout_strategy_),
/*animating=*/true);
} }
} }
...@@ -1316,8 +1318,15 @@ void ScrollableShelfView::ScrollToYOffset(float y_target_offset, ...@@ -1316,8 +1318,15 @@ void ScrollableShelfView::ScrollToYOffset(float y_target_offset,
StartShelfScrollAnimation(diff); StartShelfScrollAnimation(diff);
} }
float ScrollableShelfView::CalculatePageScrollingOffset(bool forward) const { float ScrollableShelfView::CalculatePageScrollingOffset(
DCHECK_NE(kNotShowArrowButtons, layout_strategy_); bool forward,
LayoutStrategy layout_strategy) const {
// Returns zero if inputs are invalid.
const bool invalid = (layout_strategy == kNotShowArrowButtons) ||
(layout_strategy == kShowLeftArrowButton && forward) ||
(layout_strategy == kShowRightArrowButton && !forward);
if (invalid)
return 0;
// Implement the arrow button handler in the same way with the gesture // Implement the arrow button handler in the same way with the gesture
// scrolling. The key is to calculate the suitable scroll distance. // scrolling. The key is to calculate the suitable scroll distance.
...@@ -1327,7 +1336,7 @@ float ScrollableShelfView::CalculatePageScrollingOffset(bool forward) const { ...@@ -1327,7 +1336,7 @@ float ScrollableShelfView::CalculatePageScrollingOffset(bool forward) const {
// The available space for icons excluding the area taken by arrow button(s). // The available space for icons excluding the area taken by arrow button(s).
int space_excluding_arrow; int space_excluding_arrow;
if (layout_strategy_ == kShowRightArrowButton) { if (layout_strategy == kShowRightArrowButton) {
space_excluding_arrow = GetSpaceForIcons() - kArrowButtonGroupWidth; space_excluding_arrow = GetSpaceForIcons() - kArrowButtonGroupWidth;
// After scrolling, the left arrow button will show. Adapts the offset // After scrolling, the left arrow button will show. Adapts the offset
...@@ -1337,15 +1346,15 @@ float ScrollableShelfView::CalculatePageScrollingOffset(bool forward) const { ...@@ -1337,15 +1346,15 @@ float ScrollableShelfView::CalculatePageScrollingOffset(bool forward) const {
const int mod = space_excluding_arrow % GetUnit(); const int mod = space_excluding_arrow % GetUnit();
offset = space_excluding_arrow - mod - offset_for_extra_arrow; offset = space_excluding_arrow - mod - offset_for_extra_arrow;
} else if (layout_strategy_ == kShowButtons || } else if (layout_strategy == kShowButtons ||
layout_strategy_ == kShowLeftArrowButton) { layout_strategy == kShowLeftArrowButton) {
space_excluding_arrow = GetSpaceForIcons() - 2 * kArrowButtonGroupWidth; space_excluding_arrow = GetSpaceForIcons() - 2 * kArrowButtonGroupWidth;
const int mod = space_excluding_arrow % GetUnit(); const int mod = space_excluding_arrow % GetUnit();
offset = space_excluding_arrow - mod; offset = space_excluding_arrow - mod;
// Layout of kShowLeftArrowButton can be regarded as the layout of // Layout of kShowLeftArrowButton can be regarded as the layout of
// kShowButtons with extra offset. // kShowButtons with extra offset.
if (layout_strategy_ == kShowLeftArrowButton) { if (layout_strategy == kShowLeftArrowButton) {
const int extra_offset = const int extra_offset =
-ShelfConfig::Get()->button_spacing() - -ShelfConfig::Get()->button_spacing() -
(GetSpaceForIcons() - kArrowButtonGroupWidth) % GetUnit() + (GetSpaceForIcons() - kArrowButtonGroupWidth) % GetUnit() +
...@@ -1464,46 +1473,57 @@ void ScrollableShelfView::UpdateGradientZoneState() { ...@@ -1464,46 +1473,57 @@ void ScrollableShelfView::UpdateGradientZoneState() {
} }
int ScrollableShelfView::GetActualScrollOffset() const { int ScrollableShelfView::GetActualScrollOffset() const {
int scroll_distance = GetShelf()->IsHorizontalAlignment() int scroll_distance = CalculateMainAxisScrollDistance();
? scroll_offset_.x()
: scroll_offset_.y();
if (left_arrow_->GetVisible()) if (left_arrow_->GetVisible())
scroll_distance += (kArrowButtonGroupWidth - GetAppIconEndPadding()); scroll_distance += (kArrowButtonGroupWidth - GetAppIconEndPadding());
return scroll_distance; return scroll_distance;
} }
void ScrollableShelfView::UpdateTappableIconIndices() { void ScrollableShelfView::UpdateTappableIconIndices() {
if (layout_strategy_ == kNotShowArrowButtons) { const std::pair<int, int> tappable_indices = CalculateTappableIconIndices(
first_tappable_app_index_ = shelf_view_->first_visible_index(); layout_strategy_, CalculateMainAxisScrollDistance());
last_tappable_app_index_ = shelf_view_->last_visible_index(); first_tappable_app_index_ = tappable_indices.first;
return; last_tappable_app_index_ = tappable_indices.second;
}
std::pair<int, int> ScrollableShelfView::CalculateTappableIconIndices(
ScrollableShelfView::LayoutStrategy layout_strategy,
int scroll_distance_on_main_axis) const {
std::pair<int, int> tappable_icon_indices;
int& first_tappable_app_index = tappable_icon_indices.first;
int& last_tappable_app_index = tappable_icon_indices.second;
if (layout_strategy == ScrollableShelfView::kNotShowArrowButtons) {
first_tappable_app_index = shelf_view_->first_visible_index();
last_tappable_app_index = shelf_view_->last_visible_index();
return tappable_icon_indices;
} }
const int scroll_distance_on_main_axis = GetShelf()->IsHorizontalAlignment()
? scroll_offset_.x()
: scroll_offset_.y();
const int visible_size = GetShelf()->IsHorizontalAlignment() const int visible_size = GetShelf()->IsHorizontalAlignment()
? visible_space_.width() ? visible_space_.width()
: visible_space_.height(); : visible_space_.height();
if (layout_strategy_ == kShowRightArrowButton || if (layout_strategy == kShowRightArrowButton ||
layout_strategy_ == kShowButtons) { layout_strategy == kShowButtons) {
first_tappable_app_index_ = scroll_distance_on_main_axis / GetUnit() + first_tappable_app_index = scroll_distance_on_main_axis / GetUnit() +
(layout_strategy_ == kShowButtons ? 1 : 0); (layout_strategy == kShowButtons ? 1 : 0);
last_tappable_app_index_ = last_tappable_app_index =
first_tappable_app_index_ + visible_size / GetUnit(); first_tappable_app_index + visible_size / GetUnit();
const int end_of_last_tappable_app = last_tappable_app_index_ * GetUnit() + const int end_of_last_tappable_app = last_tappable_app_index * GetUnit() +
ShelfConfig::Get()->button_size() - ShelfConfig::Get()->button_size() -
scroll_distance_on_main_axis; scroll_distance_on_main_axis;
if (end_of_last_tappable_app > visible_size) if (end_of_last_tappable_app > visible_size)
last_tappable_app_index_--; last_tappable_app_index--;
} else { } else {
DCHECK_EQ(layout_strategy_, kShowLeftArrowButton); DCHECK_EQ(layout_strategy, kShowLeftArrowButton);
last_tappable_app_index_ = shelf_view_->last_visible_index(); last_tappable_app_index = shelf_view_->last_visible_index();
first_tappable_app_index_ = first_tappable_app_index =
last_tappable_app_index_ - visible_size / GetUnit() + 1; last_tappable_app_index - visible_size / GetUnit() + 1;
} }
return tappable_icon_indices;
} }
views::View* ScrollableShelfView::FindFirstFocusableChild() { views::View* ScrollableShelfView::FindFirstFocusableChild() {
...@@ -1576,9 +1596,7 @@ void ScrollableShelfView::AdjustOffset() { ...@@ -1576,9 +1596,7 @@ void ScrollableShelfView::AdjustOffset() {
int ScrollableShelfView::CalculateAdjustedOffset() const { int ScrollableShelfView::CalculateAdjustedOffset() const {
// Returns early when it does not need to adjust the shelf view's location. // Returns early when it does not need to adjust the shelf view's location.
const int scroll_distance = GetShelf()->IsHorizontalAlignment() const int scroll_distance = CalculateMainAxisScrollDistance();
? scroll_offset_.x()
: scroll_offset_.y();
if (scroll_distance >= CalculateScrollUpperBound()) if (scroll_distance >= CalculateScrollUpperBound())
return 0; return 0;
...@@ -1713,4 +1731,9 @@ bool ScrollableShelfView::ShouldDelegateScrollToShelf( ...@@ -1713,4 +1731,9 @@ bool ScrollableShelfView::ShouldDelegateScrollToShelf(
return std::abs(main_offset) < std::abs(cross_offset); return std::abs(main_offset) < std::abs(cross_offset);
} }
float ScrollableShelfView::CalculateMainAxisScrollDistance() const {
return GetShelf()->IsHorizontalAlignment() ? scroll_offset_.x()
: scroll_offset_.y();
}
} // namespace ash } // namespace ash
...@@ -150,8 +150,10 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -150,8 +150,10 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// Creates the animation for scrolling shelf by |scroll_distance|. // Creates the animation for scrolling shelf by |scroll_distance|.
void StartShelfScrollAnimation(float scroll_distance); void StartShelfScrollAnimation(float scroll_distance);
// Updates the layout strategy based on the available space. // Calculates the layout strategy based on the available space and scroll
void UpdateLayoutStrategy(); // distance.
LayoutStrategy CalculateLayoutStrategy(
int scroll_distance_on_main_axis) const;
// Returns whether the view should adapt to RTL. // Returns whether the view should adapt to RTL.
bool ShouldAdaptToRTL() const; bool ShouldAdaptToRTL() const;
...@@ -246,9 +248,11 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -246,9 +248,11 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
void ScrollToXOffset(float x_target_offset, bool animating); void ScrollToXOffset(float x_target_offset, bool animating);
void ScrollToYOffset(float y_target_offset, bool animating); void ScrollToYOffset(float y_target_offset, bool animating);
// Calculates the distance of scrolling to show a new page of shelf icons. // Calculates the scroll distance to show a new page of shelf icons for
// |forward| indicates whether the next page or previous page is shown. // the given layout strategy. |forward| indicates whether the next page or
float CalculatePageScrollingOffset(bool forward) const; // previous page is shown.
float CalculatePageScrollingOffset(bool forward,
LayoutStrategy layout_strategy) const;
// Updates the gradient zone. // Updates the gradient zone.
void UpdateGradientZone(); void UpdateGradientZone();
...@@ -270,6 +274,14 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -270,6 +274,14 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// Updates |first_tappable_app_index_| and |last_tappable_app_index_|. // Updates |first_tappable_app_index_| and |last_tappable_app_index_|.
void UpdateTappableIconIndices(); void UpdateTappableIconIndices();
// Calculates the indices of the first/last tappable app under the given
// layout strategy and offset along the main axis (that is the x-axis when
// shelf is horizontally aligned or the y-axis if the shelf is vertically
// aligned).
std::pair<int, int> CalculateTappableIconIndices(
LayoutStrategy layout_strategy,
int scroll_distance_on_main_axis) const;
views::View* FindFirstFocusableChild(); views::View* FindFirstFocusableChild();
views::View* FindLastFocusableChild(); views::View* FindLastFocusableChild();
...@@ -313,6 +325,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -313,6 +325,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// to the shelf. // to the shelf.
bool ShouldDelegateScrollToShelf(const ui::ScrollEvent& event) const; bool ShouldDelegateScrollToShelf(const ui::ScrollEvent& event) const;
// Calculates the scroll distance along the main axis.
float CalculateMainAxisScrollDistance() const;
LayoutStrategy layout_strategy_ = kNotShowArrowButtons; LayoutStrategy layout_strategy_ = kNotShowArrowButtons;
// Child views Owned by views hierarchy. // Child views Owned by views hierarchy.
......
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