OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MASH_SHELF_SHELF_VIEW_H_ | 5 #ifndef MASH_SHELF_SHELF_VIEW_H_ |
6 #define MASH_SHELF_SHELF_VIEW_H_ | 6 #define MASH_SHELF_SHELF_VIEW_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <string> |
| 9 #include <utility> |
| 10 #include <vector> |
9 | 11 |
10 #include "base/macros.h" | 12 #include "base/macros.h" |
11 #include "mash/wm/public/interfaces/user_window_controller.mojom.h" | 13 #include "base/memory/scoped_ptr.h" |
12 #include "mojo/public/cpp/bindings/binding.h" | 14 #include "mash/shelf/shelf_button_host.h" |
| 15 #include "mash/shelf/shelf_model.h" |
| 16 #include "mash/shelf/shelf_model_observer.h" |
| 17 #include "mash/shelf/shelf_tooltip_manager.h" |
| 18 #include "mash/shelf/shelf_types.h" |
| 19 #include "ui/views/animation/bounds_animator_observer.h" |
| 20 #include "ui/views/context_menu_controller.h" |
13 #include "ui/views/controls/button/button.h" | 21 #include "ui/views/controls/button/button.h" |
14 #include "ui/views/widget/widget_delegate.h" | 22 #include "ui/views/focus/focus_manager.h" |
| 23 #include "ui/views/view.h" |
| 24 #include "ui/views/view_model.h" |
15 | 25 |
16 namespace mojo { | 26 namespace mojo { |
17 class ApplicationImpl; | 27 class ApplicationImpl; |
18 } | 28 } |
19 | 29 |
| 30 namespace ui { |
| 31 class MenuModel; |
| 32 } |
| 33 |
20 namespace views { | 34 namespace views { |
21 class LabelButton; | 35 class BoundsAnimator; |
| 36 class MenuRunner; |
22 } | 37 } |
23 | 38 |
24 namespace mash { | 39 namespace mash { |
25 namespace shelf { | 40 namespace shelf { |
26 | 41 |
27 // A rudimentary mash shelf, used to build up the required wm interfaces. | 42 class ShelfButton; |
28 class ShelfView : public views::WidgetDelegateView, | 43 |
| 44 namespace test { |
| 45 class ShelfViewTestAPI; |
| 46 } |
| 47 |
| 48 extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM; |
| 49 extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT; |
| 50 extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT; |
| 51 extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT; |
| 52 |
| 53 // TODO(msw): Restore missing features and testing from the ash shelf: |
| 54 // Alignment, overflow, applist, drag, background, hiding, pinning, panels, etc. |
| 55 class ShelfView : public views::View, |
| 56 public ShelfModelObserver, |
29 public views::ButtonListener, | 57 public views::ButtonListener, |
30 public mash::wm::mojom::UserWindowObserver { | 58 public ShelfButtonHost, |
| 59 public views::ContextMenuController, |
| 60 public views::FocusTraversable, |
| 61 public views::BoundsAnimatorObserver { |
31 public: | 62 public: |
32 explicit ShelfView(mojo::ApplicationImpl* app); | 63 explicit ShelfView(mojo::ApplicationImpl* app); |
33 ~ShelfView() override; | 64 ~ShelfView() override; |
34 | 65 |
| 66 mojo::ApplicationImpl* app() const { return app_; } |
| 67 |
| 68 void SetAlignment(ShelfAlignment alignment); |
| 69 |
| 70 void SchedulePaintForAllButtons(); |
| 71 |
| 72 // Returns the ideal bounds of the specified item, or an empty rect if id |
| 73 // isn't know. If the item is in an overflow shelf, the overflow icon location |
| 74 // will be returned. |
| 75 gfx::Rect GetIdealBoundsOfItemIcon(ShelfID id); |
| 76 |
| 77 // Repositions the icon for the specified item by the midpoint of the window. |
| 78 void UpdatePanelIconPosition(ShelfID id, const gfx::Point& midpoint); |
| 79 |
| 80 /* TODO(msw): Restore functionality: |
| 81 void AddIconObserver(ShelfIconObserver* observer); |
| 82 void RemoveIconObserver(ShelfIconObserver* observer);*/ |
| 83 |
| 84 // Returns true if we're showing a menu. |
| 85 bool IsShowingMenu() const; |
| 86 |
| 87 // Returns true if overflow bubble is shown. |
| 88 bool IsShowingOverflowBubble() const; |
| 89 |
| 90 // Sets owner overflow bubble instance from which this shelf view pops |
| 91 // out as overflow. |
| 92 /* TODO(msw): Restore functionality: |
| 93 void set_owner_overflow_bubble(OverflowBubble* owner) { |
| 94 owner_overflow_bubble_ = owner; |
| 95 }*/ |
| 96 |
| 97 views::View* GetAppListButtonView() const; |
| 98 |
| 99 // Returns true if the mouse cursor exits the area for launcher tooltip. |
| 100 // There are thin gaps between launcher buttons but the tooltip shouldn't hide |
| 101 // in the gaps, but the tooltip should hide if the mouse moved totally outside |
| 102 // of the buttons area. |
| 103 bool ShouldHideTooltip(const gfx::Point& cursor_location); |
| 104 |
| 105 // Returns rectangle bounding all visible launcher items. Used screen |
| 106 // coordinate system. |
| 107 gfx::Rect GetVisibleItemsBoundsInScreen(); |
| 108 |
| 109 // Overridden from FocusTraversable: |
| 110 views::FocusSearch* GetFocusSearch() override; |
| 111 FocusTraversable* GetFocusTraversableParent() override; |
| 112 View* GetFocusTraversableParentView() override; |
| 113 |
| 114 /* TODO(msw): Restore drag/drop functionality. |
| 115 // Overridden from app_list::ApplicationDragAndDropHost: |
| 116 void CreateDragIconProxy(const gfx::Point& location_in_screen_coordinates, |
| 117 const gfx::ImageSkia& icon, |
| 118 views::View* replaced_view, |
| 119 const gfx::Vector2d& cursor_offset_from_center, |
| 120 float scale_factor) override; |
| 121 void UpdateDragIconProxy( |
| 122 const gfx::Point& location_in_screen_coordinates) override; |
| 123 void DestroyDragIconProxy() override; |
| 124 bool StartDrag(const std::string& app_id, |
| 125 const gfx::Point& location_in_screen_coordinates) override; |
| 126 bool Drag(const gfx::Point& location_in_screen_coordinates) override; |
| 127 void EndDrag(bool cancel) override; |
| 128 */ |
| 129 |
| 130 // Return the view model for test purposes. |
| 131 const views::ViewModel* view_model_for_test() const { return &view_model_; } |
| 132 |
35 private: | 133 private: |
36 // Return the index in |open_window_buttons_| corresponding to |window_id|. | 134 friend class mash::shelf::test::ShelfViewTestAPI; |
37 size_t GetButtonIndexById(uint32_t window_id) const; | 135 |
| 136 class FadeOutAnimationDelegate; |
| 137 class StartFadeAnimationDelegate; |
| 138 |
| 139 enum RemovableState { |
| 140 REMOVABLE, // Item can be removed when dragged away. |
| 141 DRAGGABLE, // Item can be dragged, but will snap always back to origin. |
| 142 NOT_REMOVABLE, // Item is fixed and can never be removed. |
| 143 }; |
| 144 |
| 145 // Returns true when this ShelfView is used for Overflow Bubble. |
| 146 // In this mode, it does not show app list, panel and overflow button. |
| 147 // Note: |
| 148 // * When Shelf can contain only one item (overflow button) due to very |
| 149 // small resolution screen, overflow bubble can show app list and panel |
| 150 // button. |
| 151 bool is_overflow_mode() const { return overflow_mode_; } |
| 152 |
| 153 bool dragging() const { return drag_pointer_ != NONE; } |
| 154 |
| 155 // Sets the bounds of each view to its ideal bounds. |
| 156 void LayoutToIdealBounds(); |
| 157 |
| 158 // Update all button's visibility in overflow. |
| 159 void UpdateAllButtonsVisibilityInOverflowMode(); |
| 160 |
| 161 // Calculates the ideal bounds. The bounds of each button corresponding to an |
| 162 // item in the model is set in |view_model_|. Returns overflow button bounds. |
| 163 gfx::Rect CalculateIdealBounds(); |
| 164 |
| 165 // Returns the index of the last view whose max primary axis coordinate is |
| 166 // less than |max_value|. Returns -1 if nothing fits, or there are no views. |
| 167 int DetermineLastVisibleIndex(int max_value) const; |
| 168 |
| 169 // Returns the index of the first panel whose min primary axis coordinate is |
| 170 // at least |min_value|. Returns the index past the last panel if none fit. |
| 171 int DetermineFirstVisiblePanelIndex(int min_value) const; |
| 172 |
| 173 // Animates the bounds of each view to its ideal bounds. |
| 174 void AnimateToIdealBounds(); |
| 175 |
| 176 // Creates the view used to represent |item|. |
| 177 views::View* CreateViewForItem(const ShelfItem& item); |
| 178 |
| 179 // Fades |view| from an opacity of 0 to 1. This is when adding a new item. |
| 180 void FadeIn(views::View* view); |
| 181 |
| 182 // Invoked when the pointer has moved enough to trigger a drag. Sets |
| 183 // internal state in preparation for the drag. |
| 184 void PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event); |
| 185 |
| 186 // Invoked when the mouse is dragged. Updates the models as appropriate. |
| 187 void ContinueDrag(const ui::LocatedEvent& event); |
| 188 |
| 189 // Handles ripping off an item from the shelf. Returns true when the item got |
| 190 // removed. |
| 191 bool HandleRipOffDrag(const ui::LocatedEvent& event); |
| 192 |
| 193 // Finalize the rip off dragging by either |cancel| the action or validating. |
| 194 void FinalizeRipOffDrag(bool cancel); |
| 195 |
| 196 // Check if an item can be ripped off or not. |
| 197 RemovableState RemovableByRipOff(int index) const; |
| 198 |
| 199 // Returns true if |typea| and |typeb| should be in the same drag range. |
| 200 bool SameDragType(ShelfItemType typea, ShelfItemType typeb) const; |
| 201 |
| 202 // Returns the range (in the model) the item at the specified index can be |
| 203 // dragged to. |
| 204 std::pair<int, int> GetDragRange(int index); |
| 205 |
| 206 // If there is a drag operation in progress it's canceled. If |modified_index| |
| 207 // is valid, the new position of the corresponding item is returned. |
| 208 int CancelDrag(int modified_index); |
| 209 |
| 210 // Returns rectangle bounds used for drag insertion. |
| 211 // Note: |
| 212 // * When overflow button is visible, returns bounds from first item |
| 213 // to overflow button. |
| 214 // * When overflow button is visible and one or more panel items exists, |
| 215 // returns bounds from first item to last panel item. |
| 216 // * In the overflow mode, returns only bubble's bounds. |
| 217 gfx::Rect GetBoundsForDragInsertInScreen(); |
| 218 |
| 219 // Common setup done for all children. |
| 220 void ConfigureChildView(views::View* view); |
| 221 |
| 222 // Toggles the overflow menu. |
| 223 void ToggleOverflowBubble(); |
| 224 |
| 225 // Invoked after the fading out animation for item deletion is ended. |
| 226 void OnFadeOutAnimationEnded(); |
| 227 |
| 228 // Fade in last visible item. |
| 229 void StartFadeInLastVisibleItem(); |
| 230 |
| 231 // Updates the visible range of overflow items in |overflow_view|. |
| 232 void UpdateOverflowRange(ShelfView* overflow_view) const; |
38 | 233 |
39 // Overridden from views::View: | 234 // Overridden from views::View: |
40 void OnPaint(gfx::Canvas* canvas) override; | |
41 gfx::Size GetPreferredSize() const override; | 235 gfx::Size GetPreferredSize() const override; |
42 | 236 void OnBoundsChanged(const gfx::Rect& previous_bounds) override; |
43 // Overridden from views::WidgetDelegate: | 237 FocusTraversable* GetPaneFocusTraversable() override; |
44 views::View* GetContentsView() override; | 238 void GetAccessibleState(ui::AXViewState* state) override; |
| 239 |
| 240 /* TODO(msw): Restore functionality: |
| 241 // Overridden from ui::EventHandler: |
| 242 void OnGestureEvent(ui::GestureEvent* event) override;*/ |
| 243 |
| 244 // Overridden from ShelfModelObserver: |
| 245 void ShelfItemAdded(int model_index) override; |
| 246 void ShelfItemRemoved(int model_index, ShelfID id) override; |
| 247 void ShelfItemChanged(int model_index, const ShelfItem& old_item) override; |
| 248 void ShelfItemMoved(int start_index, int target_index) override; |
| 249 void ShelfStatusChanged() override; |
| 250 |
| 251 // Overridden from ShelfButtonHost: |
| 252 ShelfAlignment GetAlignment() const override; |
| 253 bool IsHorizontalAlignment() const override; |
| 254 void PointerPressedOnButton(views::View* view, |
| 255 Pointer pointer, |
| 256 const ui::LocatedEvent& event) override; |
| 257 void PointerDraggedOnButton(views::View* view, |
| 258 Pointer pointer, |
| 259 const ui::LocatedEvent& event) override; |
| 260 void PointerReleasedOnButton(views::View* view, |
| 261 Pointer pointer, |
| 262 bool canceled) override; |
| 263 void MouseMovedOverButton(views::View* view) override; |
| 264 void MouseEnteredButton(views::View* view) override; |
| 265 void MouseExitedButton(views::View* view) override; |
| 266 base::string16 GetAccessibleName(const views::View* view) override; |
45 | 267 |
46 // Overridden from views::ButtonListener: | 268 // Overridden from views::ButtonListener: |
47 void ButtonPressed(views::Button* sender, const ui::Event& event) override; | 269 void ButtonPressed(views::Button* sender, const ui::Event& event) override; |
48 | 270 |
49 // Overridden from mash::wm::mojom::UserWindowObserver: | 271 // Show the list of all running items for this |item|. It will return true |
50 void OnUserWindowObserverAdded( | 272 // when the menu was shown and false if there were no possible items to |
51 mojo::Array<mash::wm::mojom::UserWindowPtr> user_windows) override; | 273 // choose from. |source| specifies the view which is responsible for showing |
52 void OnUserWindowAdded(mash::wm::mojom::UserWindowPtr user_window) override; | 274 // the menu, and the bubble will point towards it. |
53 void OnUserWindowRemoved(uint32_t window_id) override; | 275 // The |event_flags| are the flags of the event which triggered this menu. |
54 void OnUserWindowTitleChanged(uint32_t window_id, | 276 bool ShowListMenuForView(const ShelfItem& item, |
55 const mojo::String& window_title) override; | 277 views::View* source, |
56 | 278 const ui::Event& event); |
57 std::vector<views::LabelButton*> open_window_buttons_; | 279 |
58 mash::wm::mojom::UserWindowControllerPtr user_window_controller_; | 280 // Overridden from views::ContextMenuController: |
59 mojo::Binding<mash::wm::mojom::UserWindowObserver> binding_; | 281 void ShowContextMenuForView(views::View* source, |
| 282 const gfx::Point& point, |
| 283 ui::MenuSourceType source_type) override; |
| 284 |
| 285 // Show either a context or normal click menu of given |menu_model|. |
| 286 // If |context_menu| is set, the displayed menu is a context menu and not |
| 287 // a menu listing one or more running applications. |
| 288 // The |click_point| is only used for |context_menu|'s. |
| 289 void ShowMenu(ui::MenuModel* menu_model, |
| 290 views::View* source, |
| 291 const gfx::Point& click_point, |
| 292 bool context_menu, |
| 293 ui::MenuSourceType source_type); |
| 294 |
| 295 // Overridden from views::BoundsAnimatorObserver: |
| 296 void OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) override; |
| 297 void OnBoundsAnimatorDone(views::BoundsAnimator* animator) override; |
| 298 |
| 299 // Returns true if the (press down) |event| is a repost event from an event |
| 300 // which just closed the menu of a shelf item. If it occurs on the same shelf |
| 301 // item, we should ignore the call. |
| 302 bool IsRepostEvent(const ui::Event& event); |
| 303 |
| 304 // Convenience accessor to model_->items(). |
| 305 const ShelfItem* ShelfItemForView(const views::View* view) const; |
| 306 |
| 307 // Returns true if a tooltip should be shown for |view|. |
| 308 bool ShouldShowTooltipForView(const views::View* view) const; |
| 309 |
| 310 // Get the distance from the given |coordinate| to the closest point on this |
| 311 // launcher/shelf. |
| 312 int CalculateShelfDistance(const gfx::Point& coordinate) const; |
| 313 |
| 314 // The shelf application instance. |
| 315 mojo::ApplicationImpl* app_; |
| 316 |
| 317 // The shelf model. |
| 318 ShelfModel model_; |
| 319 |
| 320 ShelfAlignment alignment_; |
| 321 |
| 322 // Used to manage the set of active launcher buttons. There is a view per |
| 323 // item in |model_|. |
| 324 views::ViewModel view_model_; |
| 325 |
| 326 // Index of first visible launcher item. |
| 327 int first_visible_index_; |
| 328 |
| 329 // Last index of a launcher button that is visible |
| 330 // (does not go into overflow). |
| 331 mutable int last_visible_index_; |
| 332 |
| 333 scoped_ptr<views::BoundsAnimator> bounds_animator_; |
| 334 |
| 335 /* TODO(msw): Restore the overflow button and bubble, etc. |
| 336 OverflowButton* overflow_button_; |
| 337 |
| 338 scoped_ptr<OverflowBubble> overflow_bubble_; |
| 339 |
| 340 OverflowBubble* owner_overflow_bubble_;*/ |
| 341 |
| 342 ShelfTooltipManager tooltip_; |
| 343 |
| 344 // Pointer device that initiated the current drag operation. If there is no |
| 345 // current dragging operation, this is NONE. |
| 346 Pointer drag_pointer_; |
| 347 |
| 348 // The view being dragged. This is set immediately when the mouse is pressed. |
| 349 // |dragging_| is set only if the mouse is dragged far enough. |
| 350 ShelfButton* drag_view_; |
| 351 |
| 352 // Position of the mouse down event in |drag_view_|'s coordinates. |
| 353 gfx::Point drag_origin_; |
| 354 |
| 355 // Index |drag_view_| was initially at. |
| 356 int start_drag_index_; |
| 357 |
| 358 // Used for the context menu of a particular item. |
| 359 ShelfID context_menu_id_; |
| 360 |
| 361 scoped_ptr<views::FocusSearch> focus_search_; |
| 362 |
| 363 scoped_ptr<ui::MenuModel> context_menu_model_; |
| 364 |
| 365 scoped_ptr<views::MenuRunner> launcher_menu_runner_; |
| 366 |
| 367 /* TODO(msw): Restore functionality: |
| 368 base::ObserverList<ShelfIconObserver> observers_;*/ |
| 369 |
| 370 // Amount content is inset on the left edge (or top edge for vertical |
| 371 // alignment). |
| 372 int leading_inset_; |
| 373 |
| 374 /* TODO(msw): Restore functionality: |
| 375 ShelfGestureHandler gesture_handler_;*/ |
| 376 |
| 377 // True when an item being inserted or removed in the model cancels a drag. |
| 378 bool cancelling_drag_model_changed_; |
| 379 |
| 380 // Index of the last hidden launcher item. If there are no hidden items this |
| 381 // will be equal to last_visible_index_ + 1. |
| 382 mutable int last_hidden_index_; |
| 383 |
| 384 // The timestamp of the event which closed the last menu - or 0. |
| 385 base::TimeDelta closing_event_time_; |
| 386 |
| 387 // When this object gets deleted while a menu is shown, this pointed |
| 388 // element will be set to false. |
| 389 bool* got_deleted_; |
| 390 |
| 391 // True if a drag and drop operation created/pinned the item in the launcher |
| 392 // and it needs to be deleted/unpinned again if the operation gets cancelled. |
| 393 bool drag_and_drop_item_pinned_; |
| 394 |
| 395 // The ShelfItem which is currently used for a drag and a drop operation |
| 396 // or 0 otherwise. |
| 397 ShelfID drag_and_drop_shelf_id_; |
| 398 |
| 399 // The application ID of the application which we drag and drop. |
| 400 std::string drag_and_drop_app_id_; |
| 401 |
| 402 // The original launcher item's size before the dragging operation. |
| 403 gfx::Size pre_drag_and_drop_size_; |
| 404 |
| 405 // The image proxy for drag operations when a drag and drop host exists and |
| 406 // the item can be dragged outside the app grid. |
| 407 /* TODO(msw): Restore functionality: |
| 408 scoped_ptr<ash::DragImageView> drag_image_;*/ |
| 409 |
| 410 // The cursor offset to the middle of the dragged item. |
| 411 gfx::Vector2d drag_image_offset_; |
| 412 |
| 413 // The view which gets replaced by our drag icon proxy. |
| 414 views::View* drag_replaced_view_; |
| 415 |
| 416 // True when the icon was dragged off the shelf. |
| 417 bool dragged_off_shelf_; |
| 418 |
| 419 // The rip off view when a snap back operation is underway. |
| 420 views::View* snap_back_from_rip_off_view_; |
| 421 |
| 422 /* TODO(msw): Restore functionality: |
| 423 // Holds ShelfItemDelegateManager. |
| 424 ShelfItemDelegateManager* item_manager_;*/ |
| 425 |
| 426 // True when this ShelfView is used for Overflow Bubble. |
| 427 bool overflow_mode_; |
| 428 |
| 429 // Holds a pointer to main ShelfView when a ShelfView is in overflow mode. |
| 430 ShelfView* main_shelf_; |
| 431 |
| 432 // True when ripped item from overflow bubble is entered into Shelf. |
| 433 bool dragged_off_from_overflow_to_shelf_; |
| 434 |
| 435 // True if the event is a repost event from a event which has just closed the |
| 436 // menu of the same shelf item. |
| 437 bool is_repost_event_; |
| 438 |
| 439 // Record the index for the last pressed shelf item. This variable is used to |
| 440 // check if a repost event occurs on the same shelf item as previous one. If |
| 441 // so, the repost event should be ignored. |
| 442 int last_pressed_index_; |
| 443 |
| 444 /* TODO(msw): Restore functionality: |
| 445 // Tracks UMA metrics based on shelf button press actions. |
| 446 ShelfButtonPressedMetricTracker shelf_button_pressed_metric_tracker_;*/ |
60 | 447 |
61 DISALLOW_COPY_AND_ASSIGN(ShelfView); | 448 DISALLOW_COPY_AND_ASSIGN(ShelfView); |
62 }; | 449 }; |
63 | 450 |
64 } // namespace shelf | 451 } // namespace shelf |
65 } // namespace mash | 452 } // namespace mash |
66 | 453 |
67 #endif // MASH_SHELF_SHELF_VIEW_H_ | 454 #endif // MASH_SHELF_SHELF_VIEW_H_ |
OLD | NEW |