Blink roll 174125:174137
[chromium-blink-merge.git] / ash / shelf / shelf_view.h
blob9f7c2ddf7c1a7f0516bbc34e4da94ff80ce8340e
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.
5 #ifndef ASH_SHELF_SHELF_VIEW_H_
6 #define ASH_SHELF_SHELF_VIEW_H_
8 #include <utility>
9 #include <vector>
11 #include "ash/shelf/shelf_button_host.h"
12 #include "ash/shelf/shelf_model_observer.h"
13 #include "ash/wm/gestures/shelf_gesture_handler.h"
14 #include "base/observer_list.h"
15 #include "ui/app_list/views/app_list_drag_and_drop_host.h"
16 #include "ui/views/animation/bounds_animator_observer.h"
17 #include "ui/views/context_menu_controller.h"
18 #include "ui/views/controls/button/button.h"
19 #include "ui/views/focus/focus_manager.h"
20 #include "ui/views/view.h"
22 namespace views {
23 class BoundsAnimator;
24 class MenuModelAdapter;
25 class MenuRunner;
26 class ViewModel;
29 namespace ash {
30 class ShelfDelegate;
31 class ShelfIconObserver;
32 class ShelfItemDelegateManager;
33 class ShelfModel;
34 struct ShelfItem;
35 class DragImageView;
36 class OverflowBubble;
37 class OverflowButton;
38 class ShelfButton;
39 class ShelfLayoutManager;
40 class ShelfTooltipManager;
42 namespace test {
43 class ShelfViewTestAPI;
46 extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM;
47 extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT;
48 extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT;
49 extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT;
51 class ASH_EXPORT ShelfView : public views::View,
52 public ShelfModelObserver,
53 public views::ButtonListener,
54 public ShelfButtonHost,
55 public views::ContextMenuController,
56 public views::FocusTraversable,
57 public views::BoundsAnimatorObserver,
58 public app_list::ApplicationDragAndDropHost {
59 public:
60 ShelfView(ShelfModel* model,
61 ShelfDelegate* delegate,
62 ShelfLayoutManager* manager);
63 virtual ~ShelfView();
65 ShelfTooltipManager* tooltip_manager() { return tooltip_.get(); }
67 ShelfLayoutManager* shelf_layout_manager() { return layout_manager_; }
69 ShelfModel* model() { return model_; }
71 void Init();
73 void OnShelfAlignmentChanged();
74 void SchedulePaintForAllButtons();
76 // Returns the ideal bounds of the specified item, or an empty rect if id
77 // isn't know.
78 gfx::Rect GetIdealBoundsOfItemIcon(ShelfID id);
80 // Repositions the icon for the specified item by the midpoint of the window.
81 void UpdatePanelIconPosition(ShelfID id, const gfx::Point& midpoint);
83 void AddIconObserver(ShelfIconObserver* observer);
84 void RemoveIconObserver(ShelfIconObserver* observer);
86 // Returns true if we're showing a menu.
87 bool IsShowingMenu() const;
89 // Returns true if overflow bubble is shown.
90 bool IsShowingOverflowBubble() const;
92 // Sets owner overflow bubble instance from which this shelf view pops
93 // out as overflow.
94 void set_owner_overflow_bubble(OverflowBubble* owner) {
95 owner_overflow_bubble_ = owner;
98 views::View* GetAppListButtonView() const;
100 // Returns true if the mouse cursor exits the area for launcher tooltip.
101 // There are thin gaps between launcher buttons but the tooltip shouldn't hide
102 // in the gaps, but the tooltip should hide if the mouse moved totally outside
103 // of the buttons area.
104 bool ShouldHideTooltip(const gfx::Point& cursor_location);
106 // Returns rectangle bounding all visible launcher items. Used screen
107 // coordinate system.
108 gfx::Rect GetVisibleItemsBoundsInScreen();
110 // Overridden from FocusTraversable:
111 virtual views::FocusSearch* GetFocusSearch() OVERRIDE;
112 virtual FocusTraversable* GetFocusTraversableParent() OVERRIDE;
113 virtual View* GetFocusTraversableParentView() OVERRIDE;
115 // Overridden from app_list::ApplicationDragAndDropHost:
116 virtual void CreateDragIconProxy(
117 const gfx::Point& location_in_screen_coordinates,
118 const gfx::ImageSkia& icon,
119 views::View* replaced_view,
120 const gfx::Vector2d& cursor_offset_from_center,
121 float scale_factor) OVERRIDE;
122 virtual void UpdateDragIconProxy(
123 const gfx::Point& location_in_screen_coordinates) OVERRIDE;
124 virtual void DestroyDragIconProxy() OVERRIDE;
125 virtual bool StartDrag(
126 const std::string& app_id,
127 const gfx::Point& location_in_screen_coordinates) OVERRIDE;
128 virtual bool Drag(const gfx::Point& location_in_screen_coordinates) OVERRIDE;
129 virtual void EndDrag(bool cancel) OVERRIDE;
131 // Return the view model for test purposes.
132 const views::ViewModel* const view_model_for_test() const {
133 return view_model_.get();
136 private:
137 friend class ash::test::ShelfViewTestAPI;
139 class FadeOutAnimationDelegate;
140 class StartFadeAnimationDelegate;
142 struct IdealBounds {
143 gfx::Rect overflow_bounds;
146 enum RemovableState {
147 REMOVABLE, // Item can be removed when dragged away.
148 DRAGGABLE, // Item can be dragged, but will snap always back to origin.
149 NOT_REMOVABLE, // Item is fixed and can never be removed.
152 // Returns true when this ShelfView is used for Overflow Bubble.
153 // In this mode, it does not show app list, panel and overflow button.
154 // Note:
155 // * When Shelf can contain only one item (overflow button) due to very
156 // small resolution screen, overflow bubble can show app list and panel
157 // button.
158 bool is_overflow_mode() const { return overflow_mode_; }
160 bool dragging() const {
161 return drag_pointer_ != NONE;
164 // Sets the bounds of each view to its ideal bounds.
165 void LayoutToIdealBounds();
167 // Update all button's visibility in overflow.
168 void UpdateAllButtonsVisibilityInOverflowMode();
170 // Calculates the ideal bounds. The bounds of each button corresponding to an
171 // item in the model is set in |view_model_|.
172 void CalculateIdealBounds(IdealBounds* bounds);
174 // Returns the index of the last view whose max primary axis coordinate is
175 // less than |max_value|. Returns -1 if nothing fits, or there are no views.
176 int DetermineLastVisibleIndex(int max_value) const;
178 // Returns the index of the first panel whose min primary axis coordinate is
179 // at least |min_value|. Returns the index past the last panel if none fit.
180 int DetermineFirstVisiblePanelIndex(int min_value) const;
182 // Animates the bounds of each view to its ideal bounds.
183 void AnimateToIdealBounds();
185 // Creates the view used to represent |item|.
186 views::View* CreateViewForItem(const ShelfItem& item);
188 // Fades |view| from an opacity of 0 to 1. This is when adding a new item.
189 void FadeIn(views::View* view);
191 // Invoked when the pointer has moved enough to trigger a drag. Sets
192 // internal state in preparation for the drag.
193 void PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event);
195 // Invoked when the mouse is dragged. Updates the models as appropriate.
196 void ContinueDrag(const ui::LocatedEvent& event);
198 // Handles ripping off an item from the shelf. Returns true when the item got
199 // removed.
200 bool HandleRipOffDrag(const ui::LocatedEvent& event);
202 // Finalize the rip off dragging by either |cancel| the action or validating.
203 void FinalizeRipOffDrag(bool cancel);
205 // Check if an item can be ripped off or not.
206 RemovableState RemovableByRipOff(int index);
208 // Returns true if |typea| and |typeb| should be in the same drag range.
209 bool SameDragType(ShelfItemType typea, ShelfItemType typeb) const;
211 // Returns the range (in the model) the item at the specified index can be
212 // dragged to.
213 std::pair<int, int> GetDragRange(int index);
215 // If there is a drag operation in progress it's canceled. If |modified_index|
216 // is valid, the new position of the corresponding item is returned.
217 int CancelDrag(int modified_index);
219 // Returns rectangle bounds used for drag insertion.
220 // Note:
221 // * When overflow button is visible, returns bounds from first item
222 // to overflow button.
223 // * When overflow button is visible and one or more panel items exists,
224 // returns bounds from first item to last panel item.
225 // * In the overflow mode, returns only bubble's bounds.
226 gfx::Rect GetBoundsForDragInsertInScreen();
228 // Common setup done for all children.
229 void ConfigureChildView(views::View* view);
231 // Toggles the overflow menu.
232 void ToggleOverflowBubble();
234 // Invoked after the fading out animation for item deletion is ended.
235 void OnFadeOutAnimationEnded();
237 // Fade in last visible item.
238 void StartFadeInLastVisibleItem();
240 // Updates the visible range of overflow items in |overflow_view|.
241 void UpdateOverflowRange(ShelfView* overflow_view);
243 // Overridden from views::View:
244 virtual gfx::Size GetPreferredSize() OVERRIDE;
245 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
246 virtual FocusTraversable* GetPaneFocusTraversable() OVERRIDE;
247 virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
249 // Overridden from ui::EventHandler:
250 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
252 // Overridden from ShelfModelObserver:
253 virtual void ShelfItemAdded(int model_index) OVERRIDE;
254 virtual void ShelfItemRemoved(int model_index, ShelfID id) OVERRIDE;
255 virtual void ShelfItemChanged(int model_index,
256 const ShelfItem& old_item) OVERRIDE;
257 virtual void ShelfItemMoved(int start_index, int target_index) OVERRIDE;
258 virtual void ShelfStatusChanged() OVERRIDE;
260 // Overridden from ShelfButtonHost:
261 virtual void PointerPressedOnButton(views::View* view,
262 Pointer pointer,
263 const ui::LocatedEvent& event) OVERRIDE;
264 virtual void PointerDraggedOnButton(views::View* view,
265 Pointer pointer,
266 const ui::LocatedEvent& event) OVERRIDE;
267 virtual void PointerReleasedOnButton(views::View* view,
268 Pointer pointer,
269 bool canceled) OVERRIDE;
270 virtual void MouseMovedOverButton(views::View* view) OVERRIDE;
271 virtual void MouseEnteredButton(views::View* view) OVERRIDE;
272 virtual void MouseExitedButton(views::View* view) OVERRIDE;
273 virtual base::string16 GetAccessibleName(const views::View* view) OVERRIDE;
275 // Overridden from views::ButtonListener:
276 virtual void ButtonPressed(views::Button* sender,
277 const ui::Event& event) OVERRIDE;
279 // Show the list of all running items for this |item|. It will return true
280 // when the menu was shown and false if there were no possible items to
281 // choose from. |source| specifies the view which is responsible for showing
282 // the menu, and the bubble will point towards it.
283 // The |event_flags| are the flags of the event which triggered this menu.
284 bool ShowListMenuForView(const ShelfItem& item,
285 views::View* source,
286 const ui::Event& event);
288 // Overridden from views::ContextMenuController:
289 virtual void ShowContextMenuForView(views::View* source,
290 const gfx::Point& point,
291 ui::MenuSourceType source_type) OVERRIDE;
293 // Show either a context or normal click menu of given |menu_model_adapter|.
294 // If |context_menu| is set, the displayed menu is a context menu and not
295 // a menu listing one or more running applications.
296 // The |click_point| is only used for |context_menu|'s.
297 void ShowMenu(scoped_ptr<views::MenuModelAdapter> menu_model_adapter,
298 views::View* source,
299 const gfx::Point& click_point,
300 bool context_menu,
301 ui::MenuSourceType source_type);
303 // Overridden from views::BoundsAnimatorObserver:
304 virtual void OnBoundsAnimatorProgressed(
305 views::BoundsAnimator* animator) OVERRIDE;
306 virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator) OVERRIDE;
308 // Returns false if the click which closed the previous menu is the click
309 // which triggered this event.
310 bool IsUsableEvent(const ui::Event& event);
312 // Convenience accessor to model_->items().
313 const ShelfItem* ShelfItemForView(const views::View* view) const;
315 // Returns true if a tooltip should be shown for |view|.
316 bool ShouldShowTooltipForView(const views::View* view) const;
318 // Get the distance from the given |coordinate| to the closest point on this
319 // launcher/shelf.
320 int CalculateShelfDistance(const gfx::Point& coordinate) const;
322 // The model; owned by Launcher.
323 ShelfModel* model_;
325 // Delegate; owned by Launcher.
326 ShelfDelegate* delegate_;
328 // Used to manage the set of active launcher buttons. There is a view per
329 // item in |model_|.
330 scoped_ptr<views::ViewModel> view_model_;
332 // Index of first visible launcher item.
333 int first_visible_index_;
335 // Last index of a launcher button that is visible
336 // (does not go into overflow).
337 int last_visible_index_;
339 scoped_ptr<views::BoundsAnimator> bounds_animator_;
341 OverflowButton* overflow_button_;
343 scoped_ptr<OverflowBubble> overflow_bubble_;
345 OverflowBubble* owner_overflow_bubble_;
347 scoped_ptr<ShelfTooltipManager> tooltip_;
349 // Pointer device that initiated the current drag operation. If there is no
350 // current dragging operation, this is NONE.
351 Pointer drag_pointer_;
353 // The view being dragged. This is set immediately when the mouse is pressed.
354 // |dragging_| is set only if the mouse is dragged far enough.
355 views::View* drag_view_;
357 // X coordinate of the mouse down event in |drag_view_|s coordinates.
358 int drag_offset_;
360 // Index |drag_view_| was initially at.
361 int start_drag_index_;
363 // Used for the context menu of a particular item.
364 ShelfID context_menu_id_;
366 scoped_ptr<views::FocusSearch> focus_search_;
368 scoped_ptr<views::MenuRunner> launcher_menu_runner_;
370 ObserverList<ShelfIconObserver> observers_;
372 // Amount content is inset on the left edge (or top edge for vertical
373 // alignment).
374 int leading_inset_;
376 ShelfGestureHandler gesture_handler_;
378 // True when an item being inserted or removed in the model cancels a drag.
379 bool cancelling_drag_model_changed_;
381 // Index of the last hidden launcher item. If there are no hidden items this
382 // will be equal to last_visible_index_ + 1.
383 int last_hidden_index_;
385 // The timestamp of the event which closed the last menu - or 0.
386 base::TimeDelta closing_event_time_;
388 // When this object gets deleted while a menu is shown, this pointed
389 // element will be set to false.
390 bool* got_deleted_;
392 // True if a drag and drop operation created/pinned the item in the launcher
393 // and it needs to be deleted/unpinned again if the operation gets cancelled.
394 bool drag_and_drop_item_pinned_;
396 // The ShelfItem which is currently used for a drag and a drop operation
397 // or 0 otherwise.
398 ShelfID drag_and_drop_shelf_id_;
400 // The application ID of the application which we drag and drop.
401 std::string drag_and_drop_app_id_;
403 // The original launcher item's size before the dragging operation.
404 gfx::Size pre_drag_and_drop_size_;
406 // The image proxy for drag operations when a drag and drop host exists and
407 // the item can be dragged outside the app grid.
408 scoped_ptr<ash::DragImageView> drag_image_;
410 // The cursor offset to the middle of the dragged item.
411 gfx::Vector2d drag_image_offset_;
413 // The view which gets replaced by our drag icon proxy.
414 views::View* drag_replaced_view_;
416 // True when the icon was dragged off the shelf.
417 bool dragged_off_shelf_;
419 // The rip off view when a snap back operation is underway.
420 views::View* snap_back_from_rip_off_view_;
422 // Holds ShelfItemDelegateManager.
423 ShelfItemDelegateManager* item_manager_;
425 // Holds ShelfLayoutManager.
426 ShelfLayoutManager* layout_manager_;
428 // True when this ShelfView is used for Overflow Bubble.
429 bool overflow_mode_;
431 // Holds a pointer to main ShelfView when a ShelfView is in overflow mode.
432 ShelfView* main_shelf_;
434 // True when ripped item from overflow bubble is entered into Shelf.
435 bool dragged_off_from_overflow_to_shelf_;
437 DISALLOW_COPY_AND_ASSIGN(ShelfView);
440 } // namespace ash
442 #endif // ASH_SHELF_SHELF_VIEW_H_