Commit 982a5694 authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

Make the icon's final bounds be minimization's target bounds

The current minimization animation, which is triggered by going to
home screen from in-app shelf, uses the bounds of the icon
which corresponds to the active window to be minimized as the
animation's target bounds. However, hotseat's bounds change due to
entering the home screen. As a result, the target bounds are not the
final bounds.

This CL fixes the issue by providing an interface to calculate
the icon's bounds according to the hotseat's target bounds instead
of the actual bounds.

There are four ways to show the home screen from in-app shelf:
(1) Press the home button.
(2) Gesture fling up on the hotseat.
(3) Back gesture.
(4) Tap on the shelf icon.

In case (1), hotseat's target bounds have been set before starting
the window scaling animation. In other cases, target bounds are not
set yet. Thanks to https://crrev.com/c/1999443, case 3 and case 4 are
solved. The last one, case 2, will be fixed in the following CL.

Bug: 1030819
Change-Id: I63cafabe6527aba49e9f98e338f9f248284e1d0d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1996268
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#732416}
parent 8630c10d
...@@ -109,12 +109,9 @@ gfx::Transform WindowScaleAnimation::GetWindowTransformToShelf() { ...@@ -109,12 +109,9 @@ gfx::Transform WindowScaleAnimation::GetWindowTransformToShelf() {
gfx::Transform transform; gfx::Transform transform;
Shelf* shelf = Shelf::ForWindow(window_); Shelf* shelf = Shelf::ForWindow(window_);
gfx::Rect shelf_item_bounds =
const gfx::Rect shelf_item_bounds =
shelf->GetScreenBoundsOfItemIconForWindow(window_); shelf->GetScreenBoundsOfItemIconForWindow(window_);
// |shelf_item_bounds| is the item bounds in a extended hotseat (i.e., the
// hotseat state during dragging). Adjust it to the bounds in a shown
// hotseat (i.e., the hotseat state after dragging).
shelf_item_bounds.Offset(0, ShelfConfig::Get()->shelf_size());
if (!shelf_item_bounds.IsEmpty()) { if (!shelf_item_bounds.IsEmpty()) {
transform.Translate(shelf_item_bounds.x() - origin_without_transform.x(), transform.Translate(shelf_item_bounds.x() - origin_without_transform.x(),
......
...@@ -572,7 +572,8 @@ views::View* ScrollableShelfView::GetDefaultFocusableChild() { ...@@ -572,7 +572,8 @@ views::View* ScrollableShelfView::GetDefaultFocusableChild() {
// ring is enabled. // ring is enabled.
if (default_last_focusable_child_) { if (default_last_focusable_child_) {
ScrollToMainOffset(CalculateScrollUpperBound(), /*animating=*/true); ScrollToMainOffset(CalculateScrollUpperBound(GetSpaceForIcons()),
/*animating=*/true);
return FindLastFocusableChild(); return FindLastFocusableChild();
} else { } else {
ScrollToMainOffset(/*target_offset=*/0.f, /*animating=*/true); ScrollToMainOffset(/*target_offset=*/0.f, /*animating=*/true);
...@@ -588,13 +589,70 @@ bool ScrollableShelfView::ShouldAdaptToRTL() const { ...@@ -588,13 +589,70 @@ bool ScrollableShelfView::ShouldAdaptToRTL() const {
return base::i18n::IsRTL() && GetShelf()->IsHorizontalAlignment(); return base::i18n::IsRTL() && GetShelf()->IsHorizontalAlignment();
} }
gfx::Rect ScrollableShelfView::GetTargetScreenBoundsOfItemIcon(
const ShelfID& id) const {
DCHECK(GetShelf()->IsHorizontalAlignment());
// Calculates the available space for child views based on the target bounds.
const gfx::Insets edge_padding =
CalculateEdgePadding(/*use_target_bounds=*/true);
gfx::Rect target_space = GetAvailableLocalBounds(/*use_target_bounds=*/true);
target_space.Inset(edge_padding);
const int target_scroll_offset =
CalculateScrollOffsetForTargetAvailableSpace(target_space);
gfx::Rect icon_bounds = shelf_view_->view_model()->ideal_bounds(
shelf_view_->model()->ItemIndexByID(id));
// Transforms |icon_bounds| from shelf view's coordinates to scrollable shelf
// view's coordinates manually.
icon_bounds.Offset(
-target_scroll_offset + ShelfConfig::Get()->GetAppIconEndPadding(), 0);
// If the icon is invisible under the target view bounds, replaces the actual
// icon's bounds with the rectangle centering on the edge of |target_space|.
const gfx::Point icon_bounds_center = icon_bounds.CenterPoint();
if (icon_bounds_center.x() > target_space.right()) {
icon_bounds.Offset(target_space.right_center().OffsetFromOrigin() -
icon_bounds_center.OffsetFromOrigin());
} else if (icon_bounds_center.x() < target_space.x()) {
icon_bounds.Offset(target_space.left_center().OffsetFromOrigin() -
icon_bounds_center.OffsetFromOrigin());
}
// Hotseat's target bounds may differ from the actual bounds. So it has to
// transform the bounds manually from view's local coordinates to screen.
// Notes that the target bounds stored in shelf layout manager are adapted to
// RTL already while |icon_bounds| are not adjusted to RTL yet.
gfx::Rect hotseat_bounds_in_screen =
GetShelf()->shelf_layout_manager()->GetHotseatBounds();
if (ShouldAdaptToRTL()) {
// One simple way for transformation under RTL is: (1) Transforms hotseat
// target bounds from RTL to LTR. (2) Calculates the icon's bounds in screen
// under LTR. (3) Transforms the icon's bounds to RTL.
gfx::Rect display_bounds =
display::Screen::GetScreen()
->GetDisplayNearestWindow(GetWidget()->GetNativeView())
.bounds();
hotseat_bounds_in_screen.set_x(display_bounds.right() -
hotseat_bounds_in_screen.right());
icon_bounds.Offset(hotseat_bounds_in_screen.OffsetFromOrigin());
icon_bounds.set_x(display_bounds.right() - icon_bounds.right());
} else {
icon_bounds.Offset(hotseat_bounds_in_screen.OffsetFromOrigin());
}
return icon_bounds;
}
views::View* ScrollableShelfView::GetShelfContainerViewForTest() { views::View* ScrollableShelfView::GetShelfContainerViewForTest() {
return shelf_container_view_; return shelf_container_view_;
} }
bool ScrollableShelfView::ShouldAdjustForTest() const { bool ScrollableShelfView::ShouldAdjustForTest() const {
return CalculateAdjustmentOffset(CalculateMainAxisScrollDistance(), return CalculateAdjustmentOffset(CalculateMainAxisScrollDistance(),
layout_strategy_); layout_strategy_, GetSpaceForIcons());
} }
void ScrollableShelfView::SetTestObserver(TestObserver* test_observer) { void ScrollableShelfView::SetTestObserver(TestObserver* test_observer) {
...@@ -603,13 +661,14 @@ void ScrollableShelfView::SetTestObserver(TestObserver* test_observer) { ...@@ -603,13 +661,14 @@ void ScrollableShelfView::SetTestObserver(TestObserver* test_observer) {
test_observer_ = test_observer; test_observer_ = test_observer;
} }
int ScrollableShelfView::CalculateScrollUpperBound() const { int ScrollableShelfView::CalculateScrollUpperBound(
int available_space_for_icons) const {
if (layout_strategy_ == kNotShowArrowButtons) if (layout_strategy_ == kNotShowArrowButtons)
return 0; return 0;
// Calculate the length of the available space. // Calculate the length of the available space.
int available_length = int available_length = available_space_for_icons -
GetSpaceForIcons() - 2 * ShelfConfig::Get()->GetAppIconEndPadding(); 2 * ShelfConfig::Get()->GetAppIconEndPadding();
// Calculate the length of the preferred size. // Calculate the length of the preferred size.
const gfx::Size shelf_preferred_size( const gfx::Size shelf_preferred_size(
...@@ -621,8 +680,11 @@ int ScrollableShelfView::CalculateScrollUpperBound() const { ...@@ -621,8 +680,11 @@ int ScrollableShelfView::CalculateScrollUpperBound() const {
return std::max(0, preferred_length - available_length); return std::max(0, preferred_length - available_length);
} }
float ScrollableShelfView::CalculateClampedScrollOffset(float scroll) const { float ScrollableShelfView::CalculateClampedScrollOffset(
const float scroll_upper_bound = CalculateScrollUpperBound(); float scroll,
int available_space_for_icons) const {
const float scroll_upper_bound =
CalculateScrollUpperBound(available_space_for_icons);
scroll = base::ClampToRange(scroll, 0.0f, scroll_upper_bound); scroll = base::ClampToRange(scroll, 0.0f, scroll_upper_bound);
return scroll; return scroll;
} }
...@@ -652,9 +714,10 @@ void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) { ...@@ -652,9 +714,10 @@ void ScrollableShelfView::StartShelfScrollAnimation(float scroll_distance) {
} }
ScrollableShelfView::LayoutStrategy ScrollableShelfView::LayoutStrategy
ScrollableShelfView::CalculateLayoutStrategy( ScrollableShelfView::CalculateLayoutStrategy(int scroll_distance_on_main_axis,
int scroll_distance_on_main_axis) const { int space_for_icons,
if (CanFitAllAppsWithoutScrolling()) bool use_target_bounds) const {
if (CanFitAllAppsWithoutScrolling(use_target_bounds))
return kNotShowArrowButtons; return kNotShowArrowButtons;
if (scroll_distance_on_main_axis == 0) { if (scroll_distance_on_main_axis == 0) {
...@@ -662,7 +725,8 @@ ScrollableShelfView::CalculateLayoutStrategy( ...@@ -662,7 +725,8 @@ ScrollableShelfView::CalculateLayoutStrategy(
return kShowRightArrowButton; return kShowRightArrowButton;
} }
if (scroll_distance_on_main_axis == CalculateScrollUpperBound()) { if (scroll_distance_on_main_axis ==
CalculateScrollUpperBound(space_for_icons)) {
// 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.
return kShowLeftArrowButton; return kShowLeftArrowButton;
...@@ -672,19 +736,17 @@ ScrollableShelfView::CalculateLayoutStrategy( ...@@ -672,19 +736,17 @@ ScrollableShelfView::CalculateLayoutStrategy(
return kShowButtons; return kShowButtons;
} }
bool ScrollableShelfView::ShouldApplyDisplayCentering() const { bool ScrollableShelfView::ShouldApplyDisplayCentering(
if (!CanFitAllAppsWithoutScrolling()) bool use_target_bounds) const {
if (!CanFitAllAppsWithoutScrolling(use_target_bounds))
return false; return false;
const gfx::Rect display_bounds = const gfx::Rect display_bounds =
screen_util::GetDisplayBoundsWithShelf(GetWidget()->GetNativeWindow()); screen_util::GetDisplayBoundsWithShelf(GetWidget()->GetNativeWindow());
const int display_size_primary = GetShelf()->PrimaryAxisValue( const int display_size_primary = GetShelf()->PrimaryAxisValue(
display_bounds.width(), display_bounds.height()); display_bounds.width(), display_bounds.height());
StatusAreaWidget* status_widget = const int status_widget_size =
GetShelf()->shelf_widget()->status_area_widget(); GetStatusWidgetSizeOnPrimaryAxis(use_target_bounds);
const int status_widget_size = GetShelf()->PrimaryAxisValue(
status_widget->GetWindowBoundsInScreen().width(),
status_widget->GetWindowBoundsInScreen().height());
// An easy way to check whether the apps fit at the exact center of the // An easy way to check whether the apps fit at the exact center of the
// screen is to imagine that we have another status widget on the other // screen is to imagine that we have another status widget on the other
...@@ -930,10 +992,11 @@ void ScrollableShelfView::ScrollRectToVisible(const gfx::Rect& rect) { ...@@ -930,10 +992,11 @@ void ScrollableShelfView::ScrollRectToVisible(const gfx::Rect& rect) {
break; break;
main_axis_offset_after_scroll += page_scroll_distance; main_axis_offset_after_scroll += page_scroll_distance;
main_axis_offset_after_scroll = main_axis_offset_after_scroll = CalculateClampedScrollOffset(
CalculateClampedScrollOffset(main_axis_offset_after_scroll); main_axis_offset_after_scroll, GetSpaceForIcons());
layout_strategy_after_scroll = layout_strategy_after_scroll = CalculateLayoutStrategy(
CalculateLayoutStrategy(main_axis_offset_after_scroll); main_axis_offset_after_scroll, GetSpaceForIcons(),
/*use_target_bounds= =*/false);
main_axis_offset_after_scroll = CalculateScrollDistanceAfterAdjustment( main_axis_offset_after_scroll = CalculateScrollDistanceAfterAdjustment(
main_axis_offset_after_scroll, layout_strategy_after_scroll); main_axis_offset_after_scroll, layout_strategy_after_scroll);
visible_space_after_scroll = visible_space_after_scroll =
...@@ -1195,9 +1258,10 @@ bool ScrollableShelfView::ShouldShowRightArrow() const { ...@@ -1195,9 +1258,10 @@ bool ScrollableShelfView::ShouldShowRightArrow() const {
(layout_strategy_ == kShowButtons); (layout_strategy_ == kShowButtons);
} }
gfx::Insets ScrollableShelfView::CalculateEdgePadding() const { gfx::Insets ScrollableShelfView::CalculateEdgePadding(
bool use_target_bounds) const {
// Display centering alignment // Display centering alignment
if (ShouldApplyDisplayCentering()) if (ShouldApplyDisplayCentering(use_target_bounds))
return CalculatePaddingForDisplayCentering(); return CalculatePaddingForDisplayCentering();
const int icons_size = shelf_view_->GetSizeOfAppIcons( const int icons_size = shelf_view_->GetSizeOfAppIcons(
...@@ -1205,11 +1269,14 @@ gfx::Insets ScrollableShelfView::CalculateEdgePadding() const { ...@@ -1205,11 +1269,14 @@ gfx::Insets ScrollableShelfView::CalculateEdgePadding() const {
2 * ShelfConfig::Get()->GetAppIconEndPadding(); 2 * ShelfConfig::Get()->GetAppIconEndPadding();
const int base_padding = ShelfConfig::Get()->app_icon_group_margin(); const int base_padding = ShelfConfig::Get()->app_icon_group_margin();
const gfx::Rect available_local_bounds =
GetAvailableLocalBounds(use_target_bounds);
const int available_size_for_app_icons = const int available_size_for_app_icons =
(GetShelf()->IsHorizontalAlignment() ? width() : height()) - GetShelf()->PrimaryAxisValue(available_local_bounds.width(),
available_local_bounds.height()) -
2 * ShelfConfig::Get()->app_icon_group_margin(); 2 * ShelfConfig::Get()->app_icon_group_margin();
int gap = CanFitAllAppsWithoutScrolling() int gap = CanFitAllAppsWithoutScrolling(use_target_bounds)
? available_size_for_app_icons - icons_size // shelf centering ? available_size_for_app_icons - icons_size // shelf centering
: 0; // overflow : 0; // overflow
...@@ -1229,6 +1296,29 @@ gfx::Insets ScrollableShelfView::CalculateEdgePadding() const { ...@@ -1229,6 +1296,29 @@ gfx::Insets ScrollableShelfView::CalculateEdgePadding() const {
return padding_insets; return padding_insets;
} }
int ScrollableShelfView::GetStatusWidgetSizeOnPrimaryAxis(
bool use_target_bounds) const {
const gfx::Size status_widget_size =
use_target_bounds
? GetShelf()->shelf_layout_manager()->GetStatusAreaBounds().size()
: GetShelf()
->shelf_widget()
->status_area_widget()
->GetWindowBoundsInScreen()
.size();
return GetShelf()->PrimaryAxisValue(status_widget_size.width(),
status_widget_size.height());
}
gfx::Rect ScrollableShelfView::GetAvailableLocalBounds(
bool use_target_bounds) const {
return use_target_bounds ? gfx::Rect(GetShelf()
->shelf_layout_manager()
->GetHotseatBounds()
.size())
: GetLocalBounds();
}
gfx::Insets ScrollableShelfView::CalculatePaddingForDisplayCentering() const { gfx::Insets ScrollableShelfView::CalculatePaddingForDisplayCentering() const {
const int icons_size = shelf_view_->GetSizeOfAppIcons( const int icons_size = shelf_view_->GetSizeOfAppIcons(
shelf_view_->number_of_visible_apps(), false) + shelf_view_->number_of_visible_apps(), false) +
...@@ -1733,9 +1823,12 @@ int ScrollableShelfView::GetSpaceForIcons() const { ...@@ -1733,9 +1823,12 @@ int ScrollableShelfView::GetSpaceForIcons() const {
: available_space_.height(); : available_space_.height();
} }
bool ScrollableShelfView::CanFitAllAppsWithoutScrolling() const { bool ScrollableShelfView::CanFitAllAppsWithoutScrolling(
bool use_target_bounds) const {
const gfx::Rect available_rect = GetAvailableLocalBounds(use_target_bounds);
const int available_length = const int available_length =
(GetShelf()->IsHorizontalAlignment() ? width() : height()) - (GetShelf()->IsHorizontalAlignment() ? available_rect.width()
: available_rect.height()) -
2 * ShelfConfig::Get()->app_icon_group_margin(); 2 * ShelfConfig::Get()->app_icon_group_margin();
gfx::Size preferred_size = GetPreferredSize(); gfx::Size preferred_size = GetPreferredSize();
...@@ -1766,7 +1859,7 @@ bool ScrollableShelfView::ShouldHandleScroll(const gfx::Vector2dF& offset, ...@@ -1766,7 +1859,7 @@ bool ScrollableShelfView::ShouldHandleScroll(const gfx::Vector2dF& offset,
bool ScrollableShelfView::AdjustOffset() { bool ScrollableShelfView::AdjustOffset() {
const int offset = CalculateAdjustmentOffset( const int offset = CalculateAdjustmentOffset(
CalculateMainAxisScrollDistance(), layout_strategy_); CalculateMainAxisScrollDistance(), layout_strategy_, GetSpaceForIcons());
// 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.
if (!offset) if (!offset)
...@@ -1782,10 +1875,12 @@ bool ScrollableShelfView::AdjustOffset() { ...@@ -1782,10 +1875,12 @@ bool ScrollableShelfView::AdjustOffset() {
int ScrollableShelfView::CalculateAdjustmentOffset( int ScrollableShelfView::CalculateAdjustmentOffset(
int main_axis_scroll_distance, int main_axis_scroll_distance,
LayoutStrategy layout_strategy) const { LayoutStrategy layout_strategy,
int available_space_for_icons) 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.
if (layout_strategy == kNotShowArrowButtons || if (layout_strategy == kNotShowArrowButtons ||
main_axis_scroll_distance >= CalculateScrollUpperBound()) { main_axis_scroll_distance >=
CalculateScrollUpperBound(available_space_for_icons)) {
return 0; return 0;
} }
...@@ -1802,11 +1897,12 @@ int ScrollableShelfView::CalculateScrollDistanceAfterAdjustment( ...@@ -1802,11 +1897,12 @@ int ScrollableShelfView::CalculateScrollDistanceAfterAdjustment(
int main_axis_scroll_distance, int main_axis_scroll_distance,
LayoutStrategy layout_strategy) const { LayoutStrategy layout_strategy) const {
return main_axis_scroll_distance + return main_axis_scroll_distance +
CalculateAdjustmentOffset(main_axis_scroll_distance, layout_strategy); CalculateAdjustmentOffset(main_axis_scroll_distance, layout_strategy,
GetSpaceForIcons());
} }
void ScrollableShelfView::UpdateAvailableSpace() { void ScrollableShelfView::UpdateAvailableSpace() {
padding_insets_ = CalculateEdgePadding(); padding_insets_ = CalculateEdgePadding(/*use_target_bounds=*/false);
available_space_ = GetLocalBounds(); available_space_ = GetLocalBounds();
available_space_.Inset(padding_insets_); available_space_.Inset(padding_insets_);
if (ShouldAdaptToRTL()) if (ShouldAdaptToRTL())
...@@ -1832,7 +1928,7 @@ gfx::Rect ScrollableShelfView::CalculateVisibleSpace( ...@@ -1832,7 +1928,7 @@ gfx::Rect ScrollableShelfView::CalculateVisibleSpace(
const bool in_hotseat_tablet = const bool in_hotseat_tablet =
chromeos::switches::ShouldShowShelfHotseat() && IsInTabletMode(); chromeos::switches::ShouldShowShelfHotseat() && IsInTabletMode();
if (layout_strategy == kNotShowArrowButtons && !in_hotseat_tablet) if (layout_strategy == kNotShowArrowButtons && !in_hotseat_tablet)
return GetLocalBounds(); return GetAvailableLocalBounds(/*use_target_bounds=*/false);
const bool should_show_left_arrow = const bool should_show_left_arrow =
(layout_strategy == kShowLeftArrowButton) || (layout_strategy == kShowLeftArrowButton) ||
...@@ -1976,7 +2072,8 @@ float ScrollableShelfView::CalculateMainAxisScrollDistance() const { ...@@ -1976,7 +2072,8 @@ float ScrollableShelfView::CalculateMainAxisScrollDistance() const {
} }
void ScrollableShelfView::UpdateScrollOffset(float target_offset) { void ScrollableShelfView::UpdateScrollOffset(float target_offset) {
target_offset = CalculateClampedScrollOffset(target_offset); target_offset =
CalculateClampedScrollOffset(target_offset, GetSpaceForIcons());
if (GetShelf()->IsHorizontalAlignment()) if (GetShelf()->IsHorizontalAlignment())
scroll_offset_.set_x(target_offset); scroll_offset_.set_x(target_offset);
...@@ -1984,8 +2081,9 @@ void ScrollableShelfView::UpdateScrollOffset(float target_offset) { ...@@ -1984,8 +2081,9 @@ void ScrollableShelfView::UpdateScrollOffset(float target_offset) {
scroll_offset_.set_y(target_offset); scroll_offset_.set_y(target_offset);
// Calculating the layout strategy relies on |scroll_offset_|. // Calculating the layout strategy relies on |scroll_offset_|.
LayoutStrategy new_strategy = LayoutStrategy new_strategy = CalculateLayoutStrategy(
CalculateLayoutStrategy(CalculateMainAxisScrollDistance()); CalculateMainAxisScrollDistance(), GetSpaceForIcons(),
/*use_target_bounds=*/false);
const bool strategy_needs_update = (layout_strategy_ != new_strategy); const bool strategy_needs_update = (layout_strategy_ != new_strategy);
if (strategy_needs_update) { if (strategy_needs_update) {
...@@ -2004,4 +2102,24 @@ void ScrollableShelfView::UpdateAvailableSpaceAndScroll() { ...@@ -2004,4 +2102,24 @@ void ScrollableShelfView::UpdateAvailableSpaceAndScroll() {
UpdateScrollOffset(CalculateMainAxisScrollDistance()); UpdateScrollOffset(CalculateMainAxisScrollDistance());
} }
int ScrollableShelfView::CalculateScrollOffsetForTargetAvailableSpace(
const gfx::Rect& target_space) const {
// Ensures that the scroll offset is legal under the updated available space.
const int available_space_for_icons =
GetShelf()->PrimaryAxisValue(target_space.width(), target_space.height());
int target_scroll_offset = CalculateClampedScrollOffset(
CalculateMainAxisScrollDistance(), available_space_for_icons);
// Calculates the layout strategy based on the new scroll offset.
LayoutStrategy new_strategy =
CalculateLayoutStrategy(target_scroll_offset, available_space_for_icons,
/*use_target_bounds=*/true);
// Adjusts the scroll offset with the new strategy.
target_scroll_offset += CalculateAdjustmentOffset(
target_scroll_offset, new_strategy, available_space_for_icons);
return target_scroll_offset;
}
} // namespace ash } // namespace ash
...@@ -82,6 +82,12 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -82,6 +82,12 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// Returns whether the view should adapt to RTL. // Returns whether the view should adapt to RTL.
bool ShouldAdaptToRTL() const; bool ShouldAdaptToRTL() const;
// Returns the icon's target bounds in screen. The returned bounds are
// calculated with the hotseat's target bounds instead of the actual bounds.
// It helps to get the icon's final location before the bounds animation on
// hotseat ends.
gfx::Rect GetTargetScreenBoundsOfItemIcon(const ShelfID& id) const;
views::View* GetShelfContainerViewForTest(); views::View* GetShelfContainerViewForTest();
bool ShouldAdjustForTest() const; bool ShouldAdjustForTest() const;
...@@ -147,22 +153,28 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -147,22 +153,28 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
kNotInScroll kNotInScroll
}; };
// Returns the maximum scroll distance. // Returns the maximum scroll distance based on the given space for icons.
int CalculateScrollUpperBound() const; int CalculateScrollUpperBound(int available_space_for_icons) const;
// Returns the clamped scroll offset. // Returns the clamped scroll offset.
float CalculateClampedScrollOffset(float scroll) const; float CalculateClampedScrollOffset(float scroll,
int available_space_for_icons) const;
// 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);
// Calculates the layout strategy based on the available space and scroll // Calculates the layout strategy based on the three factors:
// distance. // (1) scroll offset on the main axis; (2) available space for shelf icons;
LayoutStrategy CalculateLayoutStrategy( // (3) Bounds of the scrollable shelf view: actual view bounds or target
int scroll_distance_on_main_axis) const; // bounds.
LayoutStrategy CalculateLayoutStrategy(int scroll_distance_on_main_axis,
int space_for_icons,
bool use_target_bounds) const;
// Returns whether the app icon layout should be centering alignment. // Returns whether the app icon layout should be centering alignment.
bool ShouldApplyDisplayCentering() const; // |use_target_bounds| indicates which view bounds are used for
// calculation: actual view bounds or target view bounds.
bool ShouldApplyDisplayCentering(bool use_target_bounds) const;
Shelf* GetShelf(); Shelf* GetShelf();
const Shelf* GetShelf() const; const Shelf* GetShelf() const;
...@@ -235,7 +247,15 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -235,7 +247,15 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// (1) display centering alignment // (1) display centering alignment
// (2) scrollable shelf centering alignment // (2) scrollable shelf centering alignment
// (3) overflow mode // (3) overflow mode
gfx::Insets CalculateEdgePadding() const; // |use_target_bounds| indicates which view bounds are used for
// calculation: actual view bounds or target view bounds.
gfx::Insets CalculateEdgePadding(bool use_target_bounds) const;
int GetStatusWidgetSizeOnPrimaryAxis(bool use_target_bounds) const;
// Returns the local bounds depending on which view bounds are used: actual
// view bounds or target view bounds.
gfx::Rect GetAvailableLocalBounds(bool use_target_bounds) const;
// Calculates padding for display centering alignment. // Calculates padding for display centering alignment.
gfx::Insets CalculatePaddingForDisplayCentering() const; gfx::Insets CalculatePaddingForDisplayCentering() const;
...@@ -312,7 +332,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -312,7 +332,9 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
int GetSpaceForIcons() const; int GetSpaceForIcons() const;
// Returns whether there is available space to accommodate all shelf icons. // Returns whether there is available space to accommodate all shelf icons.
bool CanFitAllAppsWithoutScrolling() const; // |use_target_bounds| indicates which view bounds are used for
// calculation: actual view bounds or target view bounds.
bool CanFitAllAppsWithoutScrolling(bool use_target_bounds) const;
// Returns whether scrolling should be handled. |is_gesture_fling| is true // Returns whether scrolling should be handled. |is_gesture_fling| is true
// when the scrolling is triggered by gesture fling event; when it is false, // when the scrolling is triggered by gesture fling event; when it is false,
...@@ -326,8 +348,11 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -326,8 +348,11 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// Returns the offset by which the scroll distance along the main axis should // Returns the offset by which the scroll distance along the main axis should
// be adjusted to ensure the correct UI under the specific layout strategy. // be adjusted to ensure the correct UI under the specific layout strategy.
// Three parameters are needed: (1) scroll offset on the main axis (2) layout
// strategy (3) available space for shelf icons.
int CalculateAdjustmentOffset(int main_axis_scroll_distance, int CalculateAdjustmentOffset(int main_axis_scroll_distance,
LayoutStrategy layout_strategy) const; LayoutStrategy layout_strategy,
int available_space_for_icons) const;
int CalculateScrollDistanceAfterAdjustment( int CalculateScrollDistanceAfterAdjustment(
int main_axis_scroll_distance, int main_axis_scroll_distance,
...@@ -374,6 +399,10 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -374,6 +399,10 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// offset and layout strategy. // offset and layout strategy.
void UpdateAvailableSpaceAndScroll(); void UpdateAvailableSpaceAndScroll();
// Returns the scroll offset assuming view bounds being the target bounds.
int CalculateScrollOffsetForTargetAvailableSpace(
const gfx::Rect& target_space) const;
LayoutStrategy layout_strategy_ = kNotShowArrowButtons; LayoutStrategy layout_strategy_ = kNotShowArrowButtons;
// Child views Owned by views hierarchy. // Child views Owned by views hierarchy.
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "ash/shelf/login_shelf_view.h" #include "ash/shelf/login_shelf_view.h"
#include "ash/shelf/overflow_bubble.h" #include "ash/shelf/overflow_bubble.h"
#include "ash/shelf/overflow_bubble_view.h" #include "ash/shelf/overflow_bubble_view.h"
#include "ash/shelf/scrollable_shelf_view.h"
#include "ash/shelf/shelf.h" #include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_background_animator_observer.h" #include "ash/shelf/shelf_background_animator_observer.h"
#include "ash/shelf/shelf_layout_manager.h" #include "ash/shelf/shelf_layout_manager.h"
...@@ -630,6 +631,12 @@ gfx::Rect ShelfWidget::GetScreenBoundsOfItemIconForWindow( ...@@ -630,6 +631,12 @@ gfx::Rect ShelfWidget::GetScreenBoundsOfItemIconForWindow(
if (id.IsNull()) if (id.IsNull())
return gfx::Rect(); return gfx::Rect();
if (chromeos::switches::ShouldShowShelfHotseat()) {
return hotseat_widget()
->scrollable_shelf_view()
->GetTargetScreenBoundsOfItemIcon(id);
}
gfx::Rect bounds( gfx::Rect bounds(
hotseat_widget()->GetShelfView()->GetIdealBoundsOfItemIcon(id)); hotseat_widget()->GetShelfView()->GetIdealBoundsOfItemIcon(id));
gfx::Point screen_origin; gfx::Point screen_origin;
......
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