- add sources.
[platform/framework/web/crosswalk.git] / src / ash / shelf / shelf_view.h
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 <utility>
9 #include <vector>
10
11 #include "ash/launcher/launcher_button_host.h"
12 #include "ash/launcher/launcher_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"
21
22 namespace views {
23 class BoundsAnimator;
24 class MenuModelAdapter;
25 class MenuRunner;
26 class ViewModel;
27 }
28
29 namespace ash {
30
31 namespace test {
32 class ShelfViewTestAPI;
33 }
34
35 class LauncherDelegate;
36 struct LauncherItem;
37 class LauncherItemDelegateManager;
38 class LauncherModel;
39 class ShelfIconObserver;
40
41 namespace internal {
42
43 class DragImageView;
44 class LauncherButton;
45 class OverflowBubble;
46 class OverflowButton;
47 class ShelfLayoutManager;
48 class ShelfTooltipManager;
49
50 class ASH_EXPORT ShelfView : public views::View,
51                              public LauncherModelObserver,
52                              public views::ButtonListener,
53                              public LauncherButtonHost,
54                              public views::ContextMenuController,
55                              public views::FocusTraversable,
56                              public views::BoundsAnimatorObserver,
57                              public app_list::ApplicationDragAndDropHost {
58  public:
59   ShelfView(LauncherModel* model,
60             LauncherDelegate* delegate,
61             ShelfLayoutManager* shelf_layout_manager);
62   virtual ~ShelfView();
63
64   ShelfTooltipManager* tooltip_manager() { return tooltip_.get(); }
65
66   ShelfLayoutManager* shelf_layout_manager() { return layout_manager_; }
67
68   LauncherModel* model() { return model_; }
69
70   void Init();
71
72   void OnShelfAlignmentChanged();
73   void SchedulePaintForAllButtons();
74
75   // Returns the ideal bounds of the specified item, or an empty rect if id
76   // isn't know.
77   gfx::Rect GetIdealBoundsOfItemIcon(LauncherID id);
78
79   // Repositions the icon for the specified item by the midpoint of the window.
80   void UpdatePanelIconPosition(LauncherID id, const gfx::Point& midpoint);
81
82   void AddIconObserver(ShelfIconObserver* observer);
83   void RemoveIconObserver(ShelfIconObserver* observer);
84
85   // Returns true if we're showing a menu.
86   bool IsShowingMenu() const;
87
88   // Returns true if overflow bubble is shown.
89   bool IsShowingOverflowBubble() const;
90
91   // Sets owner overflow bubble instance from which this shelf view pops
92   // out as overflow.
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   virtual views::FocusSearch* GetFocusSearch() OVERRIDE;
111   virtual FocusTraversable* GetFocusTraversableParent() OVERRIDE;
112   virtual View* GetFocusTraversableParentView() OVERRIDE;
113
114   // Overridden from app_list::ApplicationDragAndDropHost:
115   virtual void CreateDragIconProxy(
116       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   virtual void UpdateDragIconProxy(
122       const gfx::Point& location_in_screen_coordinates) OVERRIDE;
123   virtual void DestroyDragIconProxy() OVERRIDE;
124   virtual bool StartDrag(
125       const std::string& app_id,
126       const gfx::Point& location_in_screen_coordinates) OVERRIDE;
127   virtual bool Drag(const gfx::Point& location_in_screen_coordinates) OVERRIDE;
128   virtual void EndDrag(bool cancel) OVERRIDE;
129
130   // Return the view model for test purposes.
131   const views::ViewModel* const view_model_for_test() const {
132     return view_model_.get();
133   }
134
135  private:
136   friend class ash::test::ShelfViewTestAPI;
137
138   class FadeOutAnimationDelegate;
139   class StartFadeAnimationDelegate;
140
141   struct IdealBounds {
142     gfx::Rect overflow_bounds;
143   };
144
145   enum RemovableState {
146     REMOVABLE,     // Item can be removed when dragged away.
147     DRAGGABLE,     // Item can be dragged, but will snap always back to origin.
148     NOT_REMOVABLE, // Item is fixed and can never be removed.
149   };
150
151   bool is_overflow_mode() const {
152     return first_visible_index_ > 0;
153   }
154
155   bool dragging() const {
156     return drag_pointer_ != NONE;
157   }
158
159   // Sets the bounds of each view to its ideal bounds.
160   void LayoutToIdealBounds();
161
162   // Calculates the ideal bounds. The bounds of each button corresponding to an
163   // item in the model is set in |view_model_|.
164   void CalculateIdealBounds(IdealBounds* bounds);
165
166   // Returns the index of the last view whose max primary axis coordinate is
167   // less than |max_value|. Returns -1 if nothing fits, or there are no views.
168   int DetermineLastVisibleIndex(int max_value) const;
169
170   // Returns the index of the first panel whose min primary axis coordinate is
171   // at least |min_value|. Returns the index past the last panel if none fit.
172   int DetermineFirstVisiblePanelIndex(int min_value) const;
173
174   // Animates the bounds of each view to its ideal bounds.
175   void AnimateToIdealBounds();
176
177   // Creates the view used to represent |item|.
178   views::View* CreateViewForItem(const LauncherItem& item);
179
180   // Fades |view| from an opacity of 0 to 1. This is when adding a new item.
181   void FadeIn(views::View* view);
182
183   // Invoked when the pointer has moved enough to trigger a drag. Sets
184   // internal state in preparation for the drag.
185   void PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event);
186
187   // Invoked when the mouse is dragged. Updates the models as appropriate.
188   void ContinueDrag(const ui::LocatedEvent& event);
189
190   // Handles ripping off an item from the shelf. Returns true when the item got
191   // removed.
192   bool HandleRipOffDrag(const ui::LocatedEvent& event);
193
194   // Finalize the rip off dragging by either |cancel| the action or validating.
195   void FinalizeRipOffDrag(bool cancel);
196
197   // Check if an item can be ripped off or not.
198   RemovableState RemovableByRipOff(int index);
199
200   // Returns true if |typea| and |typeb| should be in the same drag range.
201   bool SameDragType(LauncherItemType typea, LauncherItemType typeb) const;
202
203   // Returns the range (in the model) the item at the specified index can be
204   // dragged to.
205   std::pair<int, int> GetDragRange(int index);
206
207   // If there is a drag operation in progress it's canceled. If |modified_index|
208   // is valid, the new position of the corresponding item is returned.
209   int CancelDrag(int modified_index);
210
211   // Common setup done for all children.
212   void ConfigureChildView(views::View* view);
213
214   // Toggles the overflow menu.
215   void ToggleOverflowBubble();
216
217   // Update first launcher button's padding. This method adds padding to the
218   // first button to include the leading inset. It needs to be called once on
219   // button creation and every time when shelf alignment is changed.
220   void UpdateFirstButtonPadding();
221
222   // Invoked after the fading out animation for item deletion is ended.
223   void OnFadeOutAnimationEnded();
224
225   // Fade in last visible item.
226   void StartFadeInLastVisibleItem();
227
228   // Updates the visible range of overflow items in |overflow_view|.
229   void UpdateOverflowRange(ShelfView* overflow_view);
230
231   // Overridden from views::View:
232   virtual gfx::Size GetPreferredSize() OVERRIDE;
233   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
234   virtual FocusTraversable* GetPaneFocusTraversable() OVERRIDE;
235   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
236
237   // Overridden from ui::EventHandler:
238   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
239
240   // Overridden from LauncherModelObserver:
241   virtual void LauncherItemAdded(int model_index) OVERRIDE;
242   virtual void LauncherItemRemoved(int model_index, LauncherID id) OVERRIDE;
243   virtual void LauncherItemChanged(int model_index,
244                                    const ash::LauncherItem& old_item) OVERRIDE;
245   virtual void LauncherItemMoved(int start_index, int target_index) OVERRIDE;
246   virtual void LauncherStatusChanged() OVERRIDE;
247
248   // Overridden from LauncherButtonHost:
249   virtual void PointerPressedOnButton(
250       views::View* view,
251       Pointer pointer,
252       const ui::LocatedEvent& event) OVERRIDE;
253   virtual void PointerDraggedOnButton(
254       views::View* view,
255       Pointer pointer,
256       const ui::LocatedEvent& event) OVERRIDE;
257   virtual void PointerReleasedOnButton(views::View* view,
258                                        Pointer pointer,
259                                        bool canceled) OVERRIDE;
260   virtual void MouseMovedOverButton(views::View* view) OVERRIDE;
261   virtual void MouseEnteredButton(views::View* view) OVERRIDE;
262   virtual void MouseExitedButton(views::View* view) OVERRIDE;
263   virtual base::string16 GetAccessibleName(const views::View* view) OVERRIDE;
264
265   // Overridden from views::ButtonListener:
266   virtual void ButtonPressed(views::Button* sender,
267                              const ui::Event& event) OVERRIDE;
268
269   // Show the list of all running items for this |item|. It will return true
270   // when the menu was shown and false if there were no possible items to
271   // choose from. |source| specifies the view which is responsible for showing
272   // the menu, and the bubble will point towards it.
273   // The |event_flags| are the flags of the event which triggered this menu.
274   bool ShowListMenuForView(const LauncherItem& item,
275                            views::View* source,
276                            const ui::Event& event);
277
278   // Overridden from views::ContextMenuController:
279   virtual void ShowContextMenuForView(views::View* source,
280                                       const gfx::Point& point,
281                                       ui::MenuSourceType source_type) OVERRIDE;
282
283   // Show either a context or normal click menu of given |menu_model_adapter|.
284   // If |context_menu| is set, the displayed menu is a context menu and not
285   // a menu listing one or more running applications.
286   // The |click_point| is only used for |context_menu|'s.
287   void ShowMenu(scoped_ptr<views::MenuModelAdapter> menu_model_adapter,
288                 views::View* source,
289                 const gfx::Point& click_point,
290                 bool context_menu,
291                 ui::MenuSourceType source_type);
292
293   // Overridden from views::BoundsAnimatorObserver:
294   virtual void OnBoundsAnimatorProgressed(
295       views::BoundsAnimator* animator) OVERRIDE;
296   virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator) OVERRIDE;
297
298   // Returns false if the click which closed the previous menu is the click
299   // which triggered this event.
300   bool IsUsableEvent(const ui::Event& event);
301
302   // Convenience accessor to model_->items().
303   const LauncherItem* LauncherItemForView(const views::View* view) const;
304
305   // Returns true if a tooltip should be shown for |view|.
306   bool ShouldShowTooltipForView(const views::View* view) const;
307
308   // Get the distance from the given |coordinate| to the closest point on this
309   // launcher/shelf.
310   int CalculateShelfDistance(const gfx::Point& coordinate) const;
311
312   // The model; owned by Launcher.
313   LauncherModel* model_;
314
315   // Delegate; owned by Launcher.
316   LauncherDelegate* delegate_;
317
318   // Used to manage the set of active launcher buttons. There is a view per
319   // item in |model_|.
320   scoped_ptr<views::ViewModel> view_model_;
321
322   // Index of first visible launcher item. When it it greater than 0,
323   // ShelfView is hosted in an overflow bubble. In this mode, it does not
324   // show app list, panel, and overflow button.
325   int first_visible_index_;
326
327   // Last index of a launcher button that is visible
328   // (does not go into overflow).
329   int last_visible_index_;
330
331   scoped_ptr<views::BoundsAnimator> bounds_animator_;
332
333   OverflowButton* overflow_button_;
334
335   scoped_ptr<OverflowBubble> overflow_bubble_;
336
337   OverflowBubble* owner_overflow_bubble_;
338
339   scoped_ptr<ShelfTooltipManager> tooltip_;
340
341   // Pointer device that initiated the current drag operation. If there is no
342   // current dragging operation, this is NONE.
343   Pointer drag_pointer_;
344
345   // The view being dragged. This is set immediately when the mouse is pressed.
346   // |dragging_| is set only if the mouse is dragged far enough.
347   views::View* drag_view_;
348
349   // X coordinate of the mouse down event in |drag_view_|s coordinates.
350   int drag_offset_;
351
352   // Index |drag_view_| was initially at.
353   int start_drag_index_;
354
355   // Used for the context menu of a particular item.
356   LauncherID context_menu_id_;
357
358   scoped_ptr<views::FocusSearch> focus_search_;
359
360   scoped_ptr<views::MenuRunner> launcher_menu_runner_;
361
362   ObserverList<ShelfIconObserver> observers_;
363
364   // Amount content is inset on the left edge (or top edge for vertical
365   // alignment).
366   int leading_inset_;
367
368   ShelfGestureHandler gesture_handler_;
369
370   // True when an item being inserted or removed in the model cancels a drag.
371   bool cancelling_drag_model_changed_;
372
373   // Index of the last hidden launcher item. If there are no hidden items this
374   // will be equal to last_visible_index_ + 1.
375   int last_hidden_index_;
376
377   // The timestamp of the event which closed the last menu - or 0.
378   base::TimeDelta closing_event_time_;
379
380   // When this object gets deleted while a menu is shown, this pointed
381   // element will be set to false.
382   bool* got_deleted_;
383
384   // True if a drag and drop operation created/pinned the item in the launcher
385   // and it needs to be deleted/unpinned again if the operation gets cancelled.
386   bool drag_and_drop_item_pinned_;
387
388   // The launcher item which is currently used for a drag and a drop operation
389   // or 0 otherwise.
390   LauncherID drag_and_drop_launcher_id_;
391
392   // The application ID of the application which we drag and drop.
393   std::string drag_and_drop_app_id_;
394
395   // The original launcher item's size before the dragging operation.
396   gfx::Size pre_drag_and_drop_size_;
397
398   // The image proxy for drag operations when a drag and drop host exists and
399   // the item can be dragged outside the app grid.
400   scoped_ptr<ash::internal::DragImageView> drag_image_;
401
402   // The cursor offset to the middle of the dragged item.
403   gfx::Vector2d drag_image_offset_;
404
405   // The view which gets replaced by our drag icon proxy.
406   views::View* drag_replaced_view_;
407
408   // True when the icon was dragged off the shelf.
409   bool dragged_off_shelf_;
410
411   // The rip off view when a snap back operation is underway.
412   views::View* snap_back_from_rip_off_view_;
413
414   // Holds LauncherItemDelegateManager.
415   LauncherItemDelegateManager* item_manager_;
416
417   // Holds ShelfLayoutManager.
418   ShelfLayoutManager* layout_manager_;
419
420   DISALLOW_COPY_AND_ASSIGN(ShelfView);
421 };
422
423 }  // namespace internal
424 }  // namespace ash
425
426 #endif  // ASH_SHELF_SHELF_VIEW_H_