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