scrollable_shelf_view.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef ASH_SHELF_SCROLLABLE_SHELF_VIEW_H_
  5. #define ASH_SHELF_SCROLLABLE_SHELF_VIEW_H_
  6. #include <memory>
  7. #include "ash/app_list/views/app_list_drag_and_drop_host.h"
  8. #include "ash/ash_export.h"
  9. #include "ash/controls/gradient_layer_delegate.h"
  10. #include "ash/drag_drop/drag_image_view.h"
  11. #include "ash/public/cpp/shelf_config.h"
  12. #include "ash/public/cpp/shelf_model.h"
  13. #include "ash/shelf/scroll_arrow_view.h"
  14. #include "ash/shelf/shelf.h"
  15. #include "ash/shelf/shelf_button_delegate.h"
  16. #include "ash/shelf/shelf_container_view.h"
  17. #include "ash/shelf/shelf_tooltip_delegate.h"
  18. #include "ash/shelf/shelf_view.h"
  19. #include "base/callback_helpers.h"
  20. #include "base/cancelable_callback.h"
  21. #include "base/time/time.h"
  22. #include "third_party/abseil-cpp/absl/types/optional.h"
  23. #include "ui/compositor/layer_animation_observer.h"
  24. #include "ui/views/animation/ink_drop_host_view.h"
  25. #include "ui/views/context_menu_controller.h"
  26. #include "ui/views/controls/button/button.h"
  27. #include "ui/views/widget/unique_widget_ptr.h"
  28. #include "ui/views/widget/widget.h"
  29. namespace views {
  30. class FocusSearch;
  31. }
  32. namespace ui {
  33. class PresentationTimeRecorder;
  34. }
  35. namespace ash {
  36. class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
  37. public ShelfView::Delegate,
  38. public ShellObserver,
  39. public ShelfConfig::Observer,
  40. public ShelfButtonDelegate,
  41. public ShelfTooltipDelegate,
  42. public views::ContextMenuController,
  43. public ui::ImplicitAnimationObserver {
  44. public:
  45. class TestObserver {
  46. public:
  47. virtual ~TestObserver() = default;
  48. virtual void OnPageFlipTimerFired() = 0;
  49. };
  50. enum LayoutStrategy {
  51. // The arrow buttons are not shown. It means that there is enough space to
  52. // accommodate all of shelf icons.
  53. kNotShowArrowButtons,
  54. // Only the left arrow button is shown.
  55. kShowLeftArrowButton,
  56. // Only the right arrow button is shown.
  57. kShowRightArrowButton,
  58. // Both buttons are shown.
  59. kShowButtons
  60. };
  61. ScrollableShelfView(ShelfModel* model, Shelf* shelf);
  62. ScrollableShelfView(const ScrollableShelfView&) = delete;
  63. ScrollableShelfView& operator=(const ScrollableShelfView&) = delete;
  64. ~ScrollableShelfView() override;
  65. void Init();
  66. // Called when the focus ring for ScrollableShelfView is enabled/disabled.
  67. // |activated| is true when enabling the focus ring.
  68. void OnFocusRingActivationChanged(bool activated);
  69. // Scrolls to a new page of shelf icons. |forward| indicates whether the next
  70. // page or previous page is shown.
  71. void ScrollToNewPage(bool forward);
  72. // AccessiblePaneView:
  73. views::FocusSearch* GetFocusSearch() override;
  74. views::FocusTraversable* GetFocusTraversableParent() override;
  75. views::View* GetFocusTraversableParentView() override;
  76. views::View* GetDefaultFocusableChild() override;
  77. // Returns the |available_space_|.
  78. gfx::Rect GetHotseatBackgroundBounds() const;
  79. // Returns whether the view should adapt to RTL.
  80. bool ShouldAdaptToRTL() const;
  81. // Returns whether the scrollable shelf's current size is equal to the target
  82. // size.
  83. bool NeedUpdateToTargetBounds() const;
  84. // Returns the icon's target bounds in screen. The returned bounds are
  85. // calculated with the hotseat's target bounds instead of the actual bounds.
  86. // It helps to get the icon's final location before the bounds animation on
  87. // hotseat ends.
  88. gfx::Rect GetTargetScreenBoundsOfItemIcon(const ShelfID& id) const;
  89. // Returns whether scrollable shelf should show app buttons with scrolling
  90. // when the view size is |target_size| and app button size is |button_size|.
  91. bool RequiresScrollingForItemSize(const gfx::Size& target_size,
  92. int button_size) const;
  93. // Sets padding insets. `padding_insets` should adapt to RTL for the
  94. // horizontal shelf.
  95. void SetEdgePaddingInsets(const gfx::Insets& padding_insets);
  96. // Returns the edge padding insets based on the scrollable shelf view's
  97. // target bounds or the current bounds, indicated by |use_target_bounds|. Note
  98. // that the returned value is mirrored for the horizontal shelf under RTL.
  99. gfx::Insets CalculateMirroredEdgePadding(bool use_target_bounds) const;
  100. views::View* GetShelfContainerViewForTest();
  101. bool ShouldAdjustForTest() const;
  102. void SetTestObserver(TestObserver* test_observer);
  103. // Returns true if any shelf corner button has ripple ring activated.
  104. bool IsAnyCornerButtonInkDropActivatedForTest() const;
  105. // Returns the maximum scroll distance for the current layout.
  106. float GetScrollUpperBoundForTest() const;
  107. // Returns whether `page_flip_timer_` is running.
  108. bool IsPageFlipTimerBusyForTest() const;
  109. ShelfView* shelf_view() { return shelf_view_; }
  110. ShelfContainerView* shelf_container_view() { return shelf_container_view_; }
  111. const ShelfContainerView* shelf_container_view() const {
  112. return shelf_container_view_;
  113. }
  114. ScrollArrowView* left_arrow() { return left_arrow_; }
  115. const ScrollArrowView* left_arrow() const { return left_arrow_; }
  116. ScrollArrowView* right_arrow() { return right_arrow_; }
  117. const ScrollArrowView* right_arrow() const { return right_arrow_; }
  118. LayoutStrategy layout_strategy_for_test() const { return layout_strategy_; }
  119. gfx::Vector2dF scroll_offset_for_test() const { return scroll_offset_; }
  120. absl::optional<size_t> first_tappable_app_index() const {
  121. return first_tappable_app_index_;
  122. }
  123. absl::optional<size_t> last_tappable_app_index() const {
  124. return last_tappable_app_index_;
  125. }
  126. void set_default_last_focusable_child(bool default_last_focusable_child) {
  127. default_last_focusable_child_ = default_last_focusable_child;
  128. }
  129. void set_page_flip_time_threshold(base::TimeDelta page_flip_time_threshold) {
  130. page_flip_time_threshold_ = page_flip_time_threshold;
  131. }
  132. const gfx::Rect& visible_space() const { return visible_space_; }
  133. const gfx::Insets& edge_padding_insets() const {
  134. return edge_padding_insets_;
  135. }
  136. void set_is_padding_configured_externally(
  137. bool is_padding_configured_externally) {
  138. is_padding_configured_externally_ = is_padding_configured_externally;
  139. }
  140. private:
  141. friend class ShelfTestApi;
  142. class ScrollableShelfArrowView;
  143. class ScopedActiveInkDropCountImpl;
  144. enum ScrollStatus {
  145. // Indicates whether the gesture scrolling is across the main axis.
  146. // That is, whether it is scrolling vertically for bottom shelf, or
  147. // whether it is scrolling horizontally for left/right shelf.
  148. kAcrossMainAxisScroll,
  149. // Indicates whether the gesture scrolling is along the main axis.
  150. // That is, whether it is scrolling horizontally for bottom shelf, or
  151. // whether it is scrolling vertically for left/right shelf.
  152. kAlongMainAxisScroll,
  153. // Not in scrolling.
  154. kNotInScroll
  155. };
  156. // Sum of the shelf button size and the gap between shelf buttons.
  157. int GetSumOfButtonSizeAndSpacing() const;
  158. // Decides whether the current first visible shelf icon of the scrollable
  159. // shelf should be hidden or fully shown when gesture scroll ends.
  160. int GetGestureDragThreshold() const;
  161. // Returns the maximum scroll distance based on the given space for icons.
  162. float CalculateScrollUpperBound(int available_space_for_icons) const;
  163. // Returns the clamped scroll offset.
  164. float CalculateClampedScrollOffset(float scroll,
  165. int available_space_for_icons) const;
  166. // Creates the animation for scrolling shelf by |scroll_distance|.
  167. void StartShelfScrollAnimation(float scroll_distance);
  168. // Calculates the layout strategy based on:
  169. // (1) scroll offset on the main axis.
  170. // (2) length of the available space to accommodate shelf icons.
  171. LayoutStrategy CalculateLayoutStrategy(float scroll_distance_on_main_axis,
  172. int available_length) const;
  173. Shelf* GetShelf();
  174. const Shelf* GetShelf() const;
  175. // views::View:
  176. gfx::Size CalculatePreferredSize() const override;
  177. void Layout() override;
  178. void ChildPreferredSizeChanged(views::View* child) override;
  179. const char* GetClassName() const override;
  180. void OnScrollEvent(ui::ScrollEvent* event) override;
  181. void OnMouseEvent(ui::MouseEvent* event) override;
  182. void OnGestureEvent(ui::GestureEvent* event) override;
  183. void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
  184. void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
  185. void ViewHierarchyChanged(
  186. const views::ViewHierarchyChangedDetails& details) override;
  187. void ScrollRectToVisible(const gfx::Rect& rect) override;
  188. std::unique_ptr<ui::Layer> RecreateLayer() override;
  189. // ShelfView::Delegate:
  190. void ScheduleScrollForItemDragIfNeeded(
  191. const gfx::Rect& location_in_screen) override;
  192. void CancelScrollForItemDrag() override;
  193. bool AreBoundsWithinVisibleSpace(
  194. const gfx::Rect& bounds_in_screem) const override;
  195. // ShelfButtonDelegate:
  196. void OnShelfButtonAboutToRequestFocusFromTabTraversal(ShelfButton* button,
  197. bool reverse) override;
  198. void ButtonPressed(views::Button* sender,
  199. const ui::Event& event,
  200. views::InkDrop* ink_drop) override;
  201. void HandleAccessibleActionScrollToMakeVisible(ShelfButton* button) override;
  202. std::unique_ptr<ScopedActiveInkDropCount> CreateScopedActiveInkDropCount(
  203. const ShelfButton* sender) override;
  204. void OnButtonWillBeRemoved() override;
  205. void OnAppButtonActivated(const ShelfButton* button) override;
  206. // ContextMenuController:
  207. void ShowContextMenuForViewImpl(views::View* source,
  208. const gfx::Point& point,
  209. ui::MenuSourceType source_type) override;
  210. // ShellObserver:
  211. void OnShelfAlignmentChanged(aura::Window* root_window,
  212. ShelfAlignment old_alignment) override;
  213. // ShelfConfig::Observer:
  214. void OnShelfConfigUpdated() override;
  215. // ShelfTooltipDelegate:
  216. bool ShouldShowTooltipForView(const views::View* view) const override;
  217. bool ShouldHideTooltip(const gfx::Point& cursor_location) const override;
  218. const std::vector<aura::Window*> GetOpenWindowsForView(
  219. views::View* view) override;
  220. std::u16string GetTitleForView(const views::View* view) const override;
  221. views::View* GetViewForEvent(const ui::Event& event) override;
  222. // ui::ImplicitAnimationObserver:
  223. void OnImplicitAnimationsCompleted() override;
  224. // Returns whether the left/right arrow button should show based on the
  225. // current layout strategy. Because Layout(), where the visibility of arrow
  226. // buttons is updated, may be called in asynchronous way, we should not use
  227. // arrow buttons' visibility directly.
  228. bool ShouldShowLeftArrow() const;
  229. bool ShouldShowRightArrow() const;
  230. // Returns the local bounds depending on which view bounds are used: actual
  231. // view bounds or target view bounds.
  232. gfx::Rect GetAvailableLocalBounds(bool use_target_bounds) const;
  233. // Calculates padding for display centering alignment depending on which view
  234. // bounds are used: actual view bounds or target view bounds. The returned
  235. // value is mirrored for the horizontal shelf under RTL.
  236. gfx::Insets CalculateMirroredPaddingForDisplayCentering(
  237. bool use_target_bounds) const;
  238. // Returns whether the received gesture event should be handled here.
  239. bool ShouldHandleGestures(const ui::GestureEvent& event);
  240. // Resets the attributes related with gesture scroll to their default values.
  241. void ResetScrollStatus();
  242. // Handles events for scrolling the shelf. Returns whether the event has been
  243. // consumed.
  244. bool ProcessGestureEvent(const ui::GestureEvent& event);
  245. void HandleMouseWheelEvent(ui::MouseWheelEvent* event);
  246. // Scrolls the view by distance of |x_offset| or |y_offset|. |animating|
  247. // indicates whether the animation displays. |x_offset| or |y_offset| has to
  248. // be float. Otherwise the slow gesture drag is neglected.
  249. void ScrollByXOffset(float x_offset, bool animating);
  250. void ScrollByYOffset(float y_offset, bool animating);
  251. // Scrolls the view to the target offset. |animating| indicates whether the
  252. // scroll animation is needed. Note that |target_offset| may be an illegal
  253. // value and may get adjusted in CalculateClampedScrollOffset function.
  254. void ScrollToMainOffset(float target_offset, bool animating);
  255. // Calculates the scroll distance to show a new page of shelf icons for
  256. // the given layout strategy. |forward| indicates whether the next page or
  257. // previous page is shown.
  258. float CalculatePageScrollingOffset(bool forward,
  259. LayoutStrategy layout_strategy) const;
  260. // Calculates the absolute value of page scroll distance.
  261. float CalculatePageScrollingOffsetInAbs(LayoutStrategy layout_strategy) const;
  262. // Calculates the target offset on the main axis after scrolling by
  263. // |scroll_distance| while the offset before scroll is |start_offset|.
  264. float CalculateTargetOffsetAfterScroll(float start_offset,
  265. float scroll_distance) const;
  266. // Calculates the bounds of the gradient zone before/after the shelf
  267. // container.
  268. GradientLayerDelegate::FadeZone CalculateStartGradientZone() const;
  269. GradientLayerDelegate::FadeZone CalculateEndGradientZone() const;
  270. // Updates the visibility of gradient zones.
  271. void UpdateGradientZoneState();
  272. // Updates the gradient zone if the gradient zone's target bounds are
  273. // different from the actual values.
  274. void MaybeUpdateGradientZone();
  275. void PaintGradientZone(
  276. const GradientLayerDelegate::FadeZone& start_gradient_zone,
  277. const GradientLayerDelegate::FadeZone& end_gradient_zone);
  278. bool ShouldApplyMaskLayerGradientZone() const;
  279. // Returns the actual scroll offset for the given scroll distance along the
  280. // main axis under the specific layout strategy. When the left arrow button
  281. // shows, |shelf_view_| is translated due to the change in
  282. // |shelf_container_view_|'s bounds. That translation offset is not included
  283. // in |scroll_offset_|.
  284. float GetActualScrollOffset(float main_axis_scroll_distance,
  285. LayoutStrategy layout_strategy) const;
  286. // Updates |first_tappable_app_index_| and |last_tappable_app_index_|.
  287. void UpdateTappableIconIndices();
  288. // Calculates the indices of the first/last tappable app under the given
  289. // layout strategy and offset along the main axis (that is the x-axis when
  290. // shelf is horizontally aligned or the y-axis if the shelf is vertically
  291. // aligned).
  292. std::pair<absl::optional<size_t>, absl::optional<size_t>>
  293. CalculateTappableIconIndices(LayoutStrategy layout_strategy,
  294. int scroll_distance_on_main_axis) const;
  295. views::View* FindFirstFocusableChild();
  296. views::View* FindLastFocusableChild();
  297. // Returns the available space on the main axis for shelf icons.
  298. int GetSpaceForIcons() const;
  299. // Returns whether |available_size| is able to accommodate all shelf icons
  300. // without scrolling. |icons_preferred_size| is the space required by shelf
  301. // icons.
  302. bool CanFitAllAppsWithoutScrolling(
  303. const gfx::Size& available_size,
  304. const gfx::Size& icons_preferred_size) const;
  305. // Returns whether scrolling should be handled. |is_gesture_fling| is true
  306. // when the scrolling is triggered by gesture fling event; when it is false,
  307. // the scrolling is triggered by touch pad or mouse wheel event.
  308. bool ShouldHandleScroll(const gfx::Vector2dF& offset,
  309. bool is_gesture_fling) const;
  310. // May initiate the scroll animation to ensure that the app icons are shown
  311. // correctly. Returns whether the animation is created.
  312. bool AdjustOffset();
  313. // Returns the offset by which the scroll distance along the main axis should
  314. // be adjusted to ensure the correct UI under the specific layout strategy.
  315. // Three parameters are needed: (1) scroll offset on the main axis (2) layout
  316. // strategy (3) available space for shelf icons.
  317. float CalculateAdjustmentOffset(int main_axis_scroll_distance,
  318. LayoutStrategy layout_strategy,
  319. int available_space_for_icons) const;
  320. int CalculateScrollDistanceAfterAdjustment(
  321. int main_axis_scroll_distance,
  322. LayoutStrategy layout_strategy) const;
  323. // Updates the available space for child views (such as the arrow button,
  324. // shelf view) which is smaller than the view's bounds due to paddings.
  325. void UpdateAvailableSpace();
  326. // Returns the clip rectangle of |shelf_container_view_| for the given layout
  327. // strategy. Note that |shelf_container_view_|'s bounds are the same with
  328. // ScrollableShelfView's. It is why we can use |visible_space_| directly
  329. // without coordinate transformation.
  330. gfx::Rect CalculateVisibleSpace(LayoutStrategy layout_strategy) const;
  331. // Calculates the padding insets which help to show the edging app icon's
  332. // ripple ring correctly.
  333. gfx::Insets CalculateRipplePaddingInsets() const;
  334. // Calculates the rounded corners for |shelf_container_view_|. It contributes
  335. // to cut off the child view out of the scrollable shelf's bounds, such as
  336. // ripple ring.
  337. gfx::RoundedCornersF CalculateShelfContainerRoundedCorners() const;
  338. // Scrolls to a new page if |drag_icon_| is dragged out of |visible_space_|
  339. // for enough time. The function is called when |page_flip_timer_| is fired.
  340. void OnPageFlipTimer();
  341. // Returns whether a scroll event should be handled by this view or delegated
  342. // to the shelf.
  343. bool ShouldDelegateScrollToShelf(const ui::ScrollEvent& event) const;
  344. // Calculates the scroll distance along the main axis.
  345. float CalculateMainAxisScrollDistance() const;
  346. // Updates |scroll_offset_| from |target_offset_| using shelf alignment.
  347. // |scroll_offset_| may need to update in following cases: (1) View bounds are
  348. // changed. (2) View is scrolled. (3) A shelf icon is added/removed.
  349. void UpdateScrollOffset(float target_offset);
  350. // Updates the available space, which may also trigger the change in scroll
  351. // offset and layout strategy.
  352. void UpdateAvailableSpaceAndScroll();
  353. // Returns the scroll offset assuming view bounds being the target bounds.
  354. int CalculateScrollOffsetForTargetAvailableSpace(
  355. const gfx::Rect& target_space) const;
  356. // Returns whether |sender|'s activated ink drop should be counted.
  357. bool ShouldCountActivatedInkDrop(const views::View* sender) const;
  358. // Enable/disable the rounded corners of the shelf container.
  359. void EnableShelfRoundedCorners(bool enable);
  360. // Update the number of corner buttons with ripple ring activated. |increase|
  361. // indicates whether the number increases or decreases.
  362. void OnActiveInkDropChange(bool increase);
  363. // Returns whether layer clip should be enabled.
  364. bool ShouldEnableLayerClip() const;
  365. // Enable/disable the layer clip on |shelf_container_view_|.
  366. void EnableLayerClipOnShelfContainerView(bool enable);
  367. // Calculates the length of space required by shelf icons to show without
  368. // scroll. Note that the return value includes the padding space between the
  369. // app icon and the end of scrollable shelf.
  370. int CalculateShelfIconsPreferredLength() const;
  371. LayoutStrategy layout_strategy_ = kNotShowArrowButtons;
  372. // Child views Owned by views hierarchy.
  373. ScrollArrowView* left_arrow_ = nullptr;
  374. ScrollArrowView* right_arrow_ = nullptr;
  375. ShelfContainerView* shelf_container_view_ = nullptr;
  376. // Available space to accommodate child views. It is mirrored for the
  377. // horizontal shelf under RTL.
  378. gfx::Rect available_space_;
  379. ShelfView* shelf_view_ = nullptr;
  380. // Defines the padding space inside the scrollable shelf. It is decided by the
  381. // current padding strategy. Note that `edge_padding_insets_` is mirrored
  382. // for the horizontal shelf under RTL.
  383. gfx::Insets edge_padding_insets_;
  384. // Indicates whether |edge_padding_insets_| is configured externally.
  385. // Usually |edge_padding_insets_| is calculated by ScrollableShelfView's
  386. // member function. However, in some animations, |edge_padding_insets_|
  387. // is set by animation progress to ensure the smooth bounds transition.
  388. bool is_padding_configured_externally_ = false;
  389. // Visible space of |shelf_container_view| in ScrollableShelfView's local
  390. // coordinates. Different from |available_space_|, |visible_space_| only
  391. // contains app icons and is mirrored for horizontal shelf under RTL.
  392. gfx::Rect visible_space_;
  393. gfx::Vector2dF scroll_offset_;
  394. ScrollStatus scroll_status_ = kNotInScroll;
  395. // Gesture states are preserved when the gesture scrolling along the main axis
  396. // (that is, whether it is scrolling horizontally for bottom shelf, or whether
  397. // it is scrolling horizontally for left/right shelf) gets started. They help
  398. // to handle the gesture fling event.
  399. gfx::Vector2dF scroll_offset_before_main_axis_scrolling_;
  400. LayoutStrategy layout_strategy_before_main_axis_scrolling_ =
  401. kNotShowArrowButtons;
  402. std::unique_ptr<GradientLayerDelegate> gradient_layer_delegate_;
  403. std::unique_ptr<views::FocusSearch> focus_search_;
  404. // The index of the first/last tappable app index.
  405. absl::optional<size_t> first_tappable_app_index_ = absl::nullopt;
  406. absl::optional<size_t> last_tappable_app_index_ = absl::nullopt;
  407. // The number of corner buttons whose ink drop is activated.
  408. int activated_corner_buttons_ = 0;
  409. // Whether this view should focus its last focusable child (instead of its
  410. // first) when focused.
  411. bool default_last_focusable_child_ = false;
  412. // Indicates whether the focus ring on shelf items contained by
  413. // ScrollableShelfView is enabled.
  414. bool focus_ring_activated_ = false;
  415. // Indicates that the view is during the scroll animation.
  416. bool during_scroll_animation_ = false;
  417. // Indicates whether the gradient zone before/after the shelf container view
  418. // should show.
  419. bool should_show_start_gradient_zone_ = false;
  420. bool should_show_end_gradient_zone_ = false;
  421. // Waiting time before flipping the page.
  422. base::TimeDelta page_flip_time_threshold_;
  423. TestObserver* test_observer_ = nullptr;
  424. // If page flip timer is active for shelf item drag, the last known drag item
  425. // bounds in screen coordinates.
  426. absl::optional<gfx::Rect> drag_item_bounds_in_screen_;
  427. base::OneShotTimer page_flip_timer_;
  428. // Indicates whether the layer clip should be applied to
  429. // |shelf_container_view_| in non-overflow mode.
  430. bool layer_clip_in_non_overflow_ = false;
  431. // Records the presentation time for the scrollable shelf dragging.
  432. std::unique_ptr<ui::PresentationTimeRecorder> presentation_time_recorder_;
  433. base::ScopedClosureRunner force_show_hotseat_resetter_;
  434. };
  435. } // namespace ash
  436. #endif // ASH_SHELF_SCROLLABLE_SHELF_VIEW_H_