- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / controls / menu / submenu_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 UI_VIEWS_CONTROLS_MENU_SUBMENU_VIEW_H_
6 #define UI_VIEWS_CONTROLS_MENU_SUBMENU_VIEW_H_
7
8 #include <string>
9
10 #include "base/compiler_specific.h"
11 #include "ui/views/animation/scroll_animator.h"
12 #include "ui/views/controls/menu/menu_delegate.h"
13 #include "ui/views/view.h"
14
15 namespace views {
16
17 class MenuHost;
18 class MenuItemView;
19 class MenuScrollViewContainer;
20
21 // SubmenuView is the parent of all menu items.
22 //
23 // SubmenuView has the following responsibilities:
24 // . It positions and sizes all child views (any type of View may be added,
25 //   not just MenuItemViews).
26 // . Forwards the appropriate events to the MenuController. This allows the
27 //   MenuController to update the selection as the user moves the mouse around.
28 // . Renders the drop indicator during a drop operation.
29 // . Shows and hides the window (a NativeWidgetWin) when the menu is shown on
30 //   screen.
31 //
32 // SubmenuView is itself contained in a MenuScrollViewContainer.
33 // MenuScrollViewContainer handles showing as much of the SubmenuView as the
34 // screen allows. If the SubmenuView is taller than the screen, scroll buttons
35 // are provided that allow the user to see all the menu items.
36 class VIEWS_EXPORT SubmenuView : public View,
37                                  public ScrollDelegate {
38  public:
39   // The submenu's class name.
40   static const char kViewClassName[];
41
42   // Creates a SubmenuView for the specified menu item.
43   explicit SubmenuView(MenuItemView* parent);
44   virtual ~SubmenuView();
45
46   // Returns the number of child views that are MenuItemViews.
47   // MenuItemViews are identified by ID.
48   int GetMenuItemCount();
49
50   // Returns the MenuItemView at the specified index.
51   MenuItemView* GetMenuItemAt(int index);
52
53   // Positions and sizes the child views. This tiles the views vertically,
54   // giving each child the available width.
55   virtual void Layout() OVERRIDE;
56   virtual gfx::Size GetPreferredSize() OVERRIDE;
57
58   // Override from View.
59   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
60
61   // Painting.
62   virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE;
63
64   // Drag and drop methods. These are forwarded to the MenuController.
65   virtual bool GetDropFormats(
66       int* formats,
67       std::set<OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
68   virtual bool AreDropTypesRequired() OVERRIDE;
69   virtual bool CanDrop(const OSExchangeData& data) OVERRIDE;
70   virtual void OnDragEntered(const ui::DropTargetEvent& event) OVERRIDE;
71   virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE;
72   virtual void OnDragExited() OVERRIDE;
73   virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE;
74
75   // Scrolls on menu item boundaries.
76   virtual bool OnMouseWheel(const ui::MouseWheelEvent& e) OVERRIDE;
77
78   // Overridden from ui::EventHandler.
79   // Scrolls on menu item boundaries.
80   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
81
82   // Returns true if the menu is showing.
83   bool IsShowing();
84
85   // Shows the menu at the specified location. Coordinates are in screen
86   // coordinates. max_width gives the max width the view should be.
87   void ShowAt(Widget* parent, const gfx::Rect& bounds, bool do_capture);
88
89   // Resets the bounds of the submenu to |bounds|.
90   void Reposition(const gfx::Rect& bounds);
91
92   // Closes the menu, destroying the host.
93   void Close();
94
95   // Hides the hosting window.
96   //
97   // The hosting window is hidden first, then deleted (Close) when the menu is
98   // done running. This is done to avoid deletion ordering dependencies. In
99   // particular, during drag and drop (and when a modal dialog is shown as
100   // a result of choosing a context menu) it is possible that an event is
101   // being processed by the host, so that host is on the stack when we need to
102   // close the window. If we closed the window immediately (and deleted it),
103   // when control returned back to host we would crash as host was deleted.
104   void Hide();
105
106   // If mouse capture was grabbed, it is released. Does nothing if mouse was
107   // not captured.
108   void ReleaseCapture();
109
110   // Overriden from View to prevent tab from doing anything.
111   virtual bool SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) OVERRIDE;
112
113   // Returns the parent menu item we're showing children for.
114   MenuItemView* GetMenuItem() const;
115
116   // Set the drop item and position.
117   void SetDropMenuItem(MenuItemView* item,
118                        MenuDelegate::DropPosition position);
119
120   // Returns whether the selection should be shown for the specified item.
121   // The selection is NOT shown during drag and drop when the drop is over
122   // the menu.
123   bool GetShowSelection(MenuItemView* item);
124
125   // Returns the container for the SubmenuView.
126   MenuScrollViewContainer* GetScrollViewContainer();
127
128   // Invoked if the menu is prematurely destroyed. This can happen if the window
129   // closes while the menu is shown. If invoked the SubmenuView must drop all
130   // references to the MenuHost as the MenuHost is about to be deleted.
131   void MenuHostDestroyed();
132
133   // Max width of minor text (accelerator or subtitle) in child menu items. This
134   // doesn't include children's children, only direct children.
135   int max_minor_text_width() const { return max_minor_text_width_; }
136
137   // Minimum width of menu in pixels (default 0).  This becomes the smallest
138   // width returned by GetPreferredSize().
139   void set_minimum_preferred_width(int minimum_preferred_width) {
140     minimum_preferred_width_ = minimum_preferred_width;
141   }
142
143   // Automatically resize menu if a subview's preferred size changes.
144   bool resize_open_menu() const { return resize_open_menu_; }
145   void set_resize_open_menu(bool resize_open_menu) {
146     resize_open_menu_ = resize_open_menu;
147   }
148
149  protected:
150   // Overridden from View:
151   virtual const char* GetClassName() const OVERRIDE;
152
153   // View method. Overridden to schedule a paint. We do this so that when
154   // scrolling occurs, everything is repainted correctly.
155   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
156
157   virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;
158
159  private:
160   // Paints the drop indicator. This is only invoked if item is non-NULL and
161   // position is not DROP_NONE.
162   void PaintDropIndicator(gfx::Canvas* canvas,
163                           MenuItemView* item,
164                           MenuDelegate::DropPosition position);
165
166   void SchedulePaintForDropIndicator(MenuItemView* item,
167                                      MenuDelegate::DropPosition position);
168
169   // Calculates the location of th edrop indicator.
170   gfx::Rect CalculateDropIndicatorBounds(MenuItemView* item,
171                                          MenuDelegate::DropPosition position);
172
173   // Implementation of ScrollDelegate
174   virtual bool OnScroll(float dx, float dy) OVERRIDE;
175
176   // Parent menu item.
177   MenuItemView* parent_menu_item_;
178
179   // Widget subclass used to show the children. This is deleted when we invoke
180   // |DestroyMenuHost|, or |MenuHostDestroyed| is invoked back on us.
181   MenuHost* host_;
182
183   // If non-null, indicates a drop is in progress and drop_item is the item
184   // the drop is over.
185   MenuItemView* drop_item_;
186
187   // Position of the drop.
188   MenuDelegate::DropPosition drop_position_;
189
190   // Ancestor of the SubmenuView, lazily created.
191   MenuScrollViewContainer* scroll_view_container_;
192
193   // See description above getter.
194   int max_minor_text_width_;
195
196   // Minimum width returned in GetPreferredSize().
197   int minimum_preferred_width_;
198
199   // Reposition open menu when contained views change size.
200   bool resize_open_menu_;
201
202   // The submenu's scroll animator
203   scoped_ptr<ScrollAnimator> scroll_animator_;
204
205   DISALLOW_COPY_AND_ASSIGN(SubmenuView);
206 };
207
208 }  // namespace views
209
210 #endif  // UI_VIEWS_CONTROLS_MENU_SUBMENU_VIEW_H_