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