1 // Copyright (c) 2012 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 
5 #ifndef ASH_SHELF_SHELF_VIEW_H_
6 #define ASH_SHELF_SHELF_VIEW_H_
7 
8 #include <memory>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include "ash/app_list/views/app_list_drag_and_drop_host.h"
14 #include "ash/ash_export.h"
15 #include "ash/public/cpp/app_list/app_list_types.h"
16 #include "ash/public/cpp/shelf_config.h"
17 #include "ash/public/cpp/shelf_item_delegate.h"
18 #include "ash/public/cpp/shelf_model_observer.h"
19 #include "ash/public/cpp/tablet_mode_observer.h"
20 #include "ash/shelf/shelf.h"
21 #include "ash/shelf/shelf_button_delegate.h"
22 #include "ash/shelf/shelf_button_pressed_metric_tracker.h"
23 #include "ash/shelf/shelf_tooltip_delegate.h"
24 #include "ash/shell_observer.h"
25 #include "base/macros.h"
26 #include "base/memory/weak_ptr.h"
27 #include "base/optional.h"
28 #include "base/timer/timer.h"
29 #include "third_party/skia/include/core/SkColor.h"
30 #include "ui/compositor/throughput_tracker.h"
31 #include "ui/views/accessibility/view_accessibility.h"
32 #include "ui/views/accessible_pane_view.h"
33 #include "ui/views/animation/bounds_animator_observer.h"
34 #include "ui/views/animation/ink_drop_state.h"
35 #include "ui/views/context_menu_controller.h"
36 #include "ui/views/controls/button/button.h"
37 #include "ui/views/controls/menu/menu_types.h"
38 #include "ui/views/focus/focus_manager.h"
39 #include "ui/views/view_model.h"
40 #include "ui/views/widget/unique_widget_ptr.h"
41 
42 namespace ui {
43 class SimpleMenuModel;
44 }
45 
46 namespace display {
47 class ScopedDisplayForNewWindows;
48 }
49 
50 namespace views {
51 class BoundsAnimator;
52 class MenuRunner;
53 class Separator;
54 }  // namespace views
55 
56 namespace ash {
57 class DragImageView;
58 class ShelfAppButton;
59 class ShelfButton;
60 class ShelfModel;
61 struct ShelfItem;
62 class ShelfMenuModelAdapter;
63 class ShelfWidget;
64 
65 enum ShelfAlignmentUmaEnumValue {
66   SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM,
67   SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT,
68   SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT,
69   // Must be last entry in enum.
70   SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT,
71 };
72 
73 // ShelfView contains the shelf items visible within an active user session.
74 // ShelfView and LoginShelfView should never be shown together.
75 
76 class ASH_EXPORT ShelfView : public views::AccessiblePaneView,
77                              public ShelfButtonDelegate,
78                              public ShelfModelObserver,
79                              public ShellObserver,
80                              public views::ContextMenuController,
81                              public views::BoundsAnimatorObserver,
82                              public ApplicationDragAndDropHost,
83                              public ShelfTooltipDelegate,
84                              public TabletModeObserver {
85  public:
86   ShelfView(ShelfModel* model,
87             Shelf* shelf,
88             ApplicationDragAndDropHost* drag_and_drop_host,
89             ShelfButtonDelegate* delegate);
90   ~ShelfView() override;
91 
shelf()92   Shelf* shelf() const { return shelf_; }
model()93   ShelfModel* model() const { return model_; }
94 
95   // Returns the size occupied by |count| app buttons. |button_size| indicates
96   // the size of each app button.
97   static int GetSizeOfAppButtons(int count, int button_size);
98 
99   // Initializes shelf view elements.
100   void Init();
101 
102   // Returns the ideal bounds of the specified item, or an empty rect if id
103   // isn't know. If the item is in an overflow shelf, the overflow icon location
104   // will be returned.
105   gfx::Rect GetIdealBoundsOfItemIcon(const ShelfID& id);
106 
107   // Returns true if we're showing a menu. Note the menu could be either the
108   // context menu or the application select menu.
109   bool IsShowingMenu() const;
110 
111   // Returns true if we're showing a menu for |view|. |view| could be a
112   // ShelfAppButton or the ShelfView.
113   bool IsShowingMenuForView(const views::View* view) const;
114 
115   // Updates the union of all the shelf item bounds shown by this shelf view.
116   // This is used to determine the common area where the mouse can hover
117   // for showing tooltips without stuttering over gaps.
118   void UpdateVisibleShelfItemBoundsUnion();
119 
120   // ShelfTooltipDelegate:
121   bool ShouldShowTooltipForView(const views::View* view) const override;
122   bool ShouldHideTooltip(const gfx::Point& cursor_location) const override;
123   const std::vector<aura::Window*> GetOpenWindowsForView(
124       views::View* view) override;
125   base::string16 GetTitleForView(const views::View* view) const override;
126   views::View* GetViewForEvent(const ui::Event& event) override;
127 
128   // Returns rectangle bounding all visible launcher items. Used screen
129   // coordinate system.
130   gfx::Rect GetVisibleItemsBoundsInScreen();
131 
132   // views::View:
133   gfx::Size CalculatePreferredSize() const override;
134   void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
135   FocusTraversable* GetPaneFocusTraversable() override;
136   bool OnKeyPressed(const ui::KeyEvent& event) override;
137   void OnMouseEvent(ui::MouseEvent* event) override;
138   const char* GetClassName() const override;
139 
140   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
141   View* GetTooltipHandlerForPoint(const gfx::Point& point) override;
142 
143   // ShelfButtonDelegate:
144   void OnShelfButtonAboutToRequestFocusFromTabTraversal(ShelfButton* button,
145                                                         bool reverse) override;
146   void ButtonPressed(views::Button* sender,
147                      const ui::Event& event,
148                      views::InkDrop* ink_drop) override;
149 
150   // FocusTraversable:
151   views::FocusSearch* GetFocusSearch() override;
152 
153   // AccessiblePaneView:
154   views::View* GetDefaultFocusableChild() override;
155 
156   // Overridden from views::ContextMenuController:
157   void ShowContextMenuForViewImpl(views::View* source,
158                                   const gfx::Point& point,
159                                   ui::MenuSourceType source_type) override;
160 
161   // ash::TabletModeObserver:
162   void OnTabletModeStarted() override;
163   void OnTabletModeEnded() override;
164 
165   // Called from ScrollableShelfView when shelf config is updated.
166   void OnShelfConfigUpdated();
167 
168   // Returns true if |event| on the shelf item is going to activate the
169   // ShelfItem associated with |view|. Used to determine whether a pending ink
170   // drop should be shown or not.
171   bool ShouldEventActivateButton(views::View* view, const ui::Event& event);
172 
173   // ApplicationDragAndDropHost:
174   void CreateDragIconProxyByLocationWithNoAnimation(
175       const gfx::Point& origin_in_screen_coordinates,
176       const gfx::ImageSkia& icon,
177       views::View* replaced_view,
178       float scale_factor,
179       int blur_radius) override;
180 
181   void UpdateDragIconProxy(
182       const gfx::Point& location_in_screen_coordinates) override;
183 
184   void UpdateDragIconProxyByLocation(
185       const gfx::Point& origin_in_screen_coordinates) override;
186 
187   void DestroyDragIconProxy() override;
188 
189   // Transfers ownership of |drag_image_widget_|, and cleans up DragIconProxy
190   // state.
191   views::UniqueWidgetPtr RetrieveDragIconProxyAndClearDragProxyState();
192 
193   bool ShouldStartDrag(
194       const std::string& app_id,
195       const gfx::Point& location_in_screen_coordinates) const override;
196   bool StartDrag(const std::string& app_id,
197                  const gfx::Point& location_in_screen_coordinates) override;
198   bool Drag(const gfx::Point& location_in_screen_coordinates) override;
199   void EndDrag(bool cancel) override;
200 
201   // Swaps the given button with the next one if |with_next| is true, or with
202   // the previous one if |with_next| is false.
203   void SwapButtons(views::View* button_to_swap, bool with_next);
204 
205   // The ShelfAppButtons use the Pointer interface to enable item reordering.
206   enum Pointer { NONE, DRAG_AND_DROP, MOUSE, TOUCH };
207   void PointerPressedOnButton(views::View* view,
208                               Pointer pointer,
209                               const ui::LocatedEvent& event);
210   void PointerDraggedOnButton(views::View* view,
211                               Pointer pointer,
212                               const ui::LocatedEvent& event);
213   void PointerReleasedOnButton(views::View* view,
214                                Pointer pointer,
215                                bool canceled);
216 
217   // Returns whether |item| should belong in the pinned section of the shelf.
218   bool IsItemPinned(const ShelfItem& item) const;
219 
220   // Returns whether |item| should be visible or hidden.
221   bool IsItemVisible(const ShelfItem& item) const;
222 
223   // Update the layout when entering or exiting tablet mode. Have the owning
224   // widget call this instead of observing changes ourselves to ensure this
225   // happens after the tablet related changes in ShelfController.
226   void OnTabletModeChanged();
227 
228   // True if the current |drag_view_| is the given |drag_view|.
229   bool IsDraggedView(const views::View* drag_view) const;
230 
231   // These three methods return the first or last focuable child of the whole
232   // shelf view.
233   views::View* FindFirstOrLastFocusableChild(bool last);
234   views::View* FindFirstFocusableChild();
235   views::View* FindLastFocusableChild();
236 
237   // Handles the gesture event. Returns true if |event| has been consumed.
238   bool HandleGestureEvent(const ui::GestureEvent* event);
239 
240   // Different from ShouldShowTooltipForView, |view| here must be a child view.
241   bool ShouldShowTooltipForChildView(const views::View* child_view) const;
242 
243   // Returns the ShelfAppButton associated with |id|.
244   ShelfAppButton* GetShelfAppButton(const ShelfID& id);
245 
246   // Updates the visibility of the views of the shelf items and the
247   // |visible_views_indices_|.
248   void UpdateShelfItemViewsVisibility();
249 
250   // If there is animation associated with |view| in |bounds_animator_|,
251   // stops the animation.
252   void StopAnimatingViewIfAny(views::View* view);
253 
254   // Whether ShelfView is handling a drag and drop.
255   bool IsShelfViewHandlingDragAndDrop() const;
256 
257   // Returns the the shelf button size.
258   int GetButtonSize() const;
259 
260   // Returns the size of a shelf button icon.
261   int GetButtonIconSize() const;
262 
263   // Returns the size of the shelf item ripple ring.
264   int GetShelfItemRippleSize() const;
265 
266   // If |app_icons_layout_offset_| is outdated, re-layout children to ideal
267   // bounds.
268   void LayoutIfAppIconsOffsetUpdates();
269 
270   // Returns the app button whose context menu is shown. Returns nullptr if no
271   // app buttons have a context menu showing.
272   ShelfAppButton* GetShelfItemViewWithContextMenu();
273 
274   // Modifies the announcement view to verbalize that the focused app button has
275   // new updates, based on the item having a notification badge.
276   void AnnounceShelfItemNotificationBadge(views::View* button);
277 
278   // Return the view model for test purposes.
view_model_for_test()279   const views::ViewModel* view_model_for_test() const {
280     return view_model_.get();
281   }
282 
set_default_last_focusable_child(bool default_last_focusable_child)283   void set_default_last_focusable_child(bool default_last_focusable_child) {
284     default_last_focusable_child_ = default_last_focusable_child;
285   }
286 
drag_view()287   ShelfAppButton* drag_view() { return drag_view_; }
288 
visible_views_indices()289   const std::vector<int>& visible_views_indices() const {
290     return visible_views_indices_;
291   }
number_of_visible_apps()292   int number_of_visible_apps() const { return visible_views_indices_.size(); }
shelf_widget()293   ShelfWidget* shelf_widget() const { return shelf_->shelf_widget(); }
view_model()294   views::ViewModel* view_model() { return view_model_.get(); }
view_model()295   const views::ViewModel* view_model() const { return view_model_.get(); }
dragged_off_shelf()296   bool dragged_off_shelf() const { return dragged_off_shelf_; }
drag_and_drop_shelf_id()297   ShelfID drag_and_drop_shelf_id() const { return drag_and_drop_shelf_id_; }
298 
first_visible_button_for_testing()299   views::View* first_visible_button_for_testing() {
300     DCHECK(!visible_views_indices_.empty());
301     return view_model_->view_at(visible_views_indices_[0]);
302   }
303 
shelf_menu_model_adapter_for_testing()304   ShelfMenuModelAdapter* shelf_menu_model_adapter_for_testing() {
305     return shelf_menu_model_adapter_.get();
306   }
307 
308  private:
309   friend class ShelfViewTestAPI;
310 
311   class FadeInAnimationDelegate;
312   class FadeOutAnimationDelegate;
313   class StartFadeAnimationDelegate;
314 
315   enum RemovableState {
316     REMOVABLE,      // Item can be removed when dragged away.
317     DRAGGABLE,      // Item can be dragged, but will snap always back to origin.
318     NOT_REMOVABLE,  // Item is fixed and can never be removed.
319   };
320 
321   // Minimum distance before drag starts.
322   static const int kMinimumDragDistance;
323 
324   // Common setup done for all children views. |layer_type| specifies the type
325   // of layer for the |view|. Use ui::LAYER_NOT_DRAWN if the content of the view
326   // do not have to be painted (e.g. a container for views that have its own
327   // texture layer).
328   static void ConfigureChildView(views::View* view, ui::LayerType layer_type);
329 
dragging()330   bool dragging() const { return drag_pointer_ != NONE; }
331 
332   // Calculates the ideal bounds of shelf elements.
333   // The bounds of each button corresponding to an item in the model is set in
334   // |view_model_|.
335   void CalculateIdealBounds();
336 
337   // Creates the view used to represent given shelf |item|.
338   // Returns unowned pointer (view is owned by the view hierarchy).
339   views::View* CreateViewForItem(const ShelfItem& item);
340 
341   // Returns the size that's actually available for app icons. Size occupied
342   // by the home button and back button plus all appropriate margins is
343   // not available for app icons.
344   int GetAvailableSpaceForAppIcons() const;
345 
346   // Updates the index of the separator and save it to |separator_index_|.
347   void UpdateSeparatorIndex();
348 
349   // Sets the bounds of each view to its ideal bounds.
350   void LayoutToIdealBounds();
351 
352   void LayoutBackAndHomeButtons();
353 
354   // Returns the index of the last view whose max primary axis coordinate is
355   // less than |max_value|. Returns -1 if nothing fits, or there are no views.
356   int IndexOfLastItemThatFitsSize(int max_value) const;
357 
358   // Animates the bounds of each view to its ideal bounds.
359   void AnimateToIdealBounds();
360 
361   // Fades |view| from an opacity of 0 to 1. This is when adding a new item.
362   void FadeIn(views::View* view);
363 
364   // Invoked when the pointer has moved enough to trigger a drag. Sets
365   // internal state in preparation for the drag.
366   void PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event);
367 
368   // Invoked when the mouse is dragged. Updates the models as appropriate.
369   void ContinueDrag(const ui::LocatedEvent& event);
370 
371   // Scroll the view to show more content in the direction of the user's drag.
372   void ScrollForUserDrag(int offset);
373 
374   // Increase the speed of an existing scroll.
375   void SpeedUpDragScrolling();
376 
377   // Reorder |drag_view_| according to the latest dragging coordinate.
378   void MoveDragViewTo(int primary_axis_coordinate);
379 
380   // Creates a drag proxy icon which can escape the given view.
381   // The proxy should get created using the |icon| with a magnification of
382   // |scale_factor| at a center location of |location_in_screen_coordinates.
383   // Use |replaced_view| to find the screen which is used.
384   // The |cursor_offset_from_center| is the offset from the mouse cursor to
385   // the center of the item.
386   // |animate_visibility| indicates whether the icon visibility changes should
387   // be animated.
388   void CreateDragIconProxy(const gfx::Point& location_in_screen_coordinates,
389                            const gfx::ImageSkia& icon,
390                            views::View* replaced_view,
391                            const gfx::Vector2d& cursor_offset_from_center,
392                            float scale_factor,
393                            bool animate_visibility);
394 
395   // Handles ripping off an item from the shelf.
396   void HandleRipOffDrag(const ui::LocatedEvent& event);
397 
398   // Finalize the rip off dragging by either |cancel| the action or validating.
399   void FinalizeRipOffDrag(bool cancel);
400 
401   // Check if an item can be ripped off or not.
402   RemovableState RemovableByRipOff(int index) const;
403 
404   // Returns true if |typea| and |typeb| should be in the same drag range.
405   bool SameDragType(ShelfItemType typea, ShelfItemType typeb) const;
406 
407   // Returns true if focus should move out of the ShelfView view tree.
408   bool ShouldFocusOut(bool reverse, views::View* button);
409 
410   // Returns the range (in the model) the item at the specified index can be
411   // dragged to.
412   std::pair<int, int> GetDragRange(int index);
413 
414   // Checks if the item at |dragged_item_index| should be pinned or unpinned on
415   // pointer release.
416   bool ShouldUpdateDraggedViewPinStatus(int dragged_item_index);
417 
418   // Checks if |dragged_view| is allowed to be dragged across the separator to
419   // perform pinning and unpinning. Note that this function doesn't check if the
420   // separator exists.
421   bool CanDragAcrossSeparator(views::View* dragged_view) const;
422 
423   // If there is a drag operation in progress it's canceled. If |modified_index|
424   // is valid, the new position of the corresponding item is returned.
425   int CancelDrag(int modified_index);
426 
427   // Returns rectangle bounds used for drag insertion.
428   gfx::Rect GetBoundsForDragInsertInScreen();
429 
430   // Invoked after the fading in animation for item addition is ended.
431   void OnFadeInAnimationEnded();
432 
433   // Invoked after the fading out animation for item deletion is ended.
434   void OnFadeOutAnimationEnded();
435 
436   // Gets the menu anchor rect for menus. |source| is the view that is
437   // asking for a menu, |location| is the location of the event, |context_menu|
438   // is whether the menu is for a context or application menu.
439   gfx::Rect GetMenuAnchorRect(const views::View& source,
440                               const gfx::Point& location,
441                               bool context_menu) const;
442 
443   void AnnounceShelfAlignment();
444   void AnnounceShelfAutohideBehavior();
445   void AnnouncePinUnpinEvent(const ShelfItem& item, bool pinned);
446   void AnnounceSwapEvent(const ShelfItem& first_item,
447                          const ShelfItem& second_item);
448 
449   // Overridden from ui::EventHandler:
450   void OnGestureEvent(ui::GestureEvent* event) override;
451 
452   // Overridden from ShelfModelObserver:
453   void ShelfItemAdded(int model_index) override;
454   void ShelfItemRemoved(int model_index, const ShelfItem& old_item) override;
455   void ShelfItemChanged(int model_index, const ShelfItem& old_item) override;
456   void ShelfItemsUpdatedForDeskChange() override;
457   void ShelfItemMoved(int start_index, int target_index) override;
458   void ShelfItemDelegateChanged(const ShelfID& id,
459                                 ShelfItemDelegate* old_delegate,
460                                 ShelfItemDelegate* delegate) override;
461   void ShelfItemStatusChanged(const ShelfID& id) override;
462   void ShelfItemRippedOff() override;
463   void ShelfItemReturnedFromRipOff(int index) override;
464 
465   // Overridden from ShellObserver:
466   void OnShelfAlignmentChanged(aura::Window* root_window,
467                                ShelfAlignment old_alignment) override;
468   void OnShelfAutoHideBehaviorChanged(aura::Window* root_window) override;
469 
470   // Shows a shelf context menu with the given |model|, or a default menu.
471   void ShowShelfContextMenu(const ShelfID& shelf_id,
472                             const gfx::Point& point,
473                             views::View* source,
474                             ui::MenuSourceType source_type,
475                             std::unique_ptr<ui::SimpleMenuModel> model);
476 
477   // Handles the result of an item selection, records the |action| taken and
478   // optionally shows an application menu with the given |menu_items|.
479   void AfterItemSelected(const ShelfItem& item,
480                          views::Button* sender,
481                          std::unique_ptr<ui::Event> event,
482                          views::InkDrop* ink_drop,
483                          ShelfAction action,
484                          ShelfItemDelegate::AppMenuItems menu_items);
485 
486   // Show either a context or normal click menu of given |menu_model|.
487   // If |context_menu| is set, the displayed menu is a context menu and not
488   // a menu listing one or more running applications.
489   // The |click_point| is only used for |context_menu|'s.
490   void ShowMenu(std::unique_ptr<ui::SimpleMenuModel> menu_model,
491                 views::View* source,
492                 const gfx::Point& click_point,
493                 bool context_menu,
494                 ui::MenuSourceType source_type);
495 
496   // Callback for MenuRunner.
497   void OnMenuClosed(views::View* source);
498 
499   // Overridden from views::BoundsAnimatorObserver:
500   void OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) override;
501   void OnBoundsAnimatorDone(views::BoundsAnimator* animator) override;
502 
503   // Returns true if the (press down) |event| is a repost event from an event
504   // which just closed the menu of a shelf item. If it occurs on the same shelf
505   // item, we should ignore the call.
506   bool IsRepostEvent(const ui::Event& event);
507 
508   // Returns true if the given |item| is supposed to be shown to the user.
509   bool ShouldShowShelfItem(const ShelfItem& item);
510 
511   // Convenience accessor to model_->items().
512   const ShelfItem* ShelfItemForView(const views::View* view) const;
513 
514   // Get the distance from the given |coordinate| to the closest point on this
515   // launcher/shelf.
516   int CalculateShelfDistance(const gfx::Point& coordinate) const;
517 
518   bool CanPrepareForDrag(Pointer pointer, const ui::LocatedEvent& event);
519 
520   // Set background blur to the dragged image. |size| is the image size.
521   void SetDragImageBlur(const gfx::Size& size, int blur_radius);
522 
523   bool ShouldHandleGestures(const ui::GestureEvent& event) const;
524 
525   void DestroyScopedDisplay();
526 
527   // Different from GetTitleForView, |view| here must be a child view.
528   base::string16 GetTitleForChildView(const views::View* view) const;
529 
530   int CalculateAppIconsLayoutOffset() const;
531 
532   // Get the |drag_image_widget_| content view as DragImageView.
533   DragImageView* GetDragImage();
534 
535   // Returns the bounds of the given |child| view taken into account RTL layouts
536   // and on-going bounds animations on |child|.
537   gfx::Rect GetChildViewTargetMirroredBounds(const views::View* child) const;
538 
539   // The model; owned by Launcher.
540   ShelfModel* model_;
541 
542   // The shelf controller; owned by RootWindowController.
543   Shelf* shelf_;
544 
545   // Used to manage the set of active launcher buttons. There is a view per
546   // item in |model_|.
547   std::unique_ptr<views::ViewModel> view_model_;
548 
549   // The indices of the views in |view_model_| that are visible.
550   std::vector<int> visible_views_indices_;
551 
552   std::unique_ptr<views::BoundsAnimator> bounds_animator_;
553 
554   // Pointer device that initiated the current drag operation. If there is no
555   // current dragging operation, this is NONE.
556   Pointer drag_pointer_ = NONE;
557 
558   // The view being dragged. This is set immediately when the mouse is pressed.
559   // |dragging_| is set only if the mouse is dragged far enough.
560   ShelfAppButton* drag_view_ = nullptr;
561 
562   // The view showing a context menu. This can be either a ShelfView or
563   // ShelfAppButton.
564   views::View* menu_owner_ = nullptr;
565 
566   // A reference to the view used as a separator between pinned and unpinned
567   // items.
568   views::Separator* separator_ = nullptr;
569 
570   // Index of |separator_|. It is set to -1 if it is invisible.
571   int separator_index_ = -1;
572 
573   // Used in |drag_view_relative_to_ideal_bounds_| to represent the relative
574   // position between |drag_view_| and its ideal bounds in shelf.
575   enum class RelativePosition {
576     // Set if |drag_view_| is not available or the relative position is not
577     // calculated yet.
578     kNotAvailable,
579     // Set if |drag_view_| is to the left of its ideal bounds.
580     kLeft,
581     // Set if |drag_view_| is to the right of its ideal bounds.
582     kRight
583   };
584 
585   // The |drag_view_|'s current position relative to its ideal bounds.
586   RelativePosition drag_view_relative_to_ideal_bounds_ =
587       RelativePosition::kNotAvailable;
588 
589   // Position of the mouse down event in |drag_view_|'s coordinates.
590   gfx::Point drag_origin_;
591 
592   // Index |drag_view_| was initially at.
593   int start_drag_index_ = -1;
594 
595   // Used for the context menu of a particular item.
596   ShelfID context_menu_id_;
597 
598   std::unique_ptr<views::FocusSearch> focus_search_;
599 
600   // Responsible for building and running all menus.
601   std::unique_ptr<ShelfMenuModelAdapter> shelf_menu_model_adapter_;
602 
603   // Created when a shelf icon is pressed, so that new windows will be on the
604   // same display as the press event.
605   std::unique_ptr<display::ScopedDisplayForNewWindows>
606       scoped_display_for_new_windows_;
607 
608   // True when an item being inserted or removed in the model cancels a drag.
609   bool cancelling_drag_model_changed_ = false;
610 
611   // The item with an in-flight async request for a context menu or selection
612   // (which shows a shelf item application menu if multiple windows are open).
613   // Used to avoid multiple concurrent menu requests. The value is null if none.
614   ShelfID item_awaiting_response_;
615 
616   // The callback for in-flight async request for a context menu.
617   // Used to cancel the request if context menu should be
618   // cancelled, for example if shelf item drag starts.
619   base::CancelableOnceCallback<void(std::unique_ptr<ui::SimpleMenuModel> model)>
620       context_menu_callback_;
621 
622   // The timestamp of the event which closed the last menu - or 0.
623   base::TimeTicks closing_event_time_;
624 
625   // True if a drag and drop operation created/pinned the item in the launcher
626   // and it needs to be deleted/unpinned again if the operation gets cancelled.
627   bool drag_and_drop_item_pinned_ = false;
628 
629   // The ShelfItem currently used for drag and drop; empty if none.
630   ShelfID drag_and_drop_shelf_id_;
631 
632   // The original launcher item's size before the dragging operation.
633   gfx::Size pre_drag_and_drop_size_;
634 
635   // The image proxy for drag operations when a drag and drop host exists and
636   // the item can be dragged outside the app grid.
637   views::UniqueWidgetPtr drag_image_widget_;
638 
639   // The cursor offset to the middle of the dragged item.
640   gfx::Vector2d drag_image_offset_;
641 
642   // The view which gets replaced by our drag icon proxy.
643   views::View* drag_replaced_view_ = nullptr;
644 
645   // True when the icon was dragged off the shelf.
646   bool dragged_off_shelf_ = false;
647 
648   // The rip off view when a snap back operation is underway.
649   ShelfAppButton* snap_back_from_rip_off_view_ = nullptr;
650 
651   // True if the event is a repost event from a event which has just closed the
652   // menu of the same shelf item.
653   bool is_repost_event_on_same_item_ = false;
654 
655   // Record the index for the last pressed shelf item. This variable is used to
656   // check if a repost event occurs on the same shelf item as previous one. If
657   // so, the repost event should be ignored.
658   int last_pressed_index_ = -1;
659 
660   // Tracks UMA metrics based on shelf button press actions.
661   ShelfButtonPressedMetricTracker shelf_button_pressed_metric_tracker_;
662 
663   // The union of all visible shelf item bounds. Used for showing tooltips in
664   // a continuous manner.
665   gfx::Rect visible_shelf_item_bounds_union_;
666 
667   // A view used to make accessibility announcements (changes in the shelf's
668   // alignment or auto-hide state).
669   views::View* announcement_view_ = nullptr;  // Owned by ShelfView
670 
671   // For dragging: -1 if scrolling back, 1 if scrolling forward, 0 if neither.
672   int drag_scroll_dir_ = 0;
673 
674   // Used to periodically call ScrollForUserDrag.
675   base::RepeatingTimer scrolling_timer_;
676 
677   // Used to call SpeedUpDragScrolling.
678   base::OneShotTimer speed_up_drag_scrolling_;
679 
680   // Whether this view should focus its last focusable child (instead of its
681   // first) when focused.
682   bool default_last_focusable_child_ = false;
683 
684   // Indicates the starting position of shelf items on the main axis. (Main
685   // axis is x-axis when the shelf is horizontally aligned; otherwise, it
686   // becomes y-axis)
687   int app_icons_layout_offset_ = 0;
688 
689   // When the scrollable shelf is enabled, |drag_and_drop_host_| should be
690   // ScrollableShelfView.
691   ApplicationDragAndDropHost* drag_and_drop_host_ = nullptr;
692 
693   // When the scrollable shelf is enabled, |shelf_button_delegate_| should
694   // be ScrollableShelfView.
695   ShelfButtonDelegate* shelf_button_delegate_ = nullptr;
696 
697   std::unique_ptr<FadeInAnimationDelegate> fade_in_animation_delegate_;
698 
699   // Tracks the icon move animation.
700   base::Optional<ui::ThroughputTracker> move_animation_tracker_;
701 
702   // Tracks the icon fade-out animation.
703   base::Optional<ui::ThroughputTracker> fade_out_animation_tracker_;
704 
705   // Called when showing shelf context menu.
706   base::RepeatingClosure context_menu_shown_callback_;
707 
708   base::WeakPtrFactory<ShelfView> weak_factory_{this};
709 
710   DISALLOW_COPY_AND_ASSIGN(ShelfView);
711 };
712 
713 }  // namespace ash
714 
715 #endif  // ASH_SHELF_SHELF_VIEW_H_
716