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_
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"
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
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
{
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 // Positions and sizes the child views. This tiles the views vertically,
56 // giving each child the available width.
57 void Layout() override
;
58 gfx::Size
GetPreferredSize() const override
;
60 // Override from View.
61 void GetAccessibleState(ui::AXViewState
* state
) override
;
62 ui::TextInputClient
* GetTextInputClient() override
;
65 void PaintChildren(const ui::PaintContext
& context
) override
;
67 // Drag and drop methods. These are forwarded to the MenuController.
70 std::set
<OSExchangeData::CustomFormat
>* custom_formats
) override
;
71 bool AreDropTypesRequired() override
;
72 bool CanDrop(const OSExchangeData
& data
) override
;
73 void OnDragEntered(const ui::DropTargetEvent
& event
) override
;
74 int OnDragUpdated(const ui::DropTargetEvent
& event
) override
;
75 void OnDragExited() override
;
76 int OnPerformDrop(const ui::DropTargetEvent
& event
) override
;
78 // Scrolls on menu item boundaries.
79 bool OnMouseWheel(const ui::MouseWheelEvent
& e
) override
;
81 // Overridden from ui::EventHandler.
82 // Scrolls on menu item boundaries.
83 void OnGestureEvent(ui::GestureEvent
* event
) override
;
85 // Overridden from PrefixDelegate.
86 int GetRowCount() override
;
87 int GetSelectedRow() override
;
88 void SetSelectedRow(int row
) override
;
89 base::string16
GetTextForRow(int row
) override
;
91 // Returns true if the menu is showing.
94 // Shows the menu at the specified location. Coordinates are in screen
95 // coordinates. max_width gives the max width the view should be.
96 void ShowAt(Widget
* parent
, const gfx::Rect
& bounds
, bool do_capture
);
98 // Resets the bounds of the submenu to |bounds|.
99 void Reposition(const gfx::Rect
& bounds
);
101 // Closes the menu, destroying the host.
104 // Hides the hosting window.
106 // The hosting window is hidden first, then deleted (Close) when the menu is
107 // done running. This is done to avoid deletion ordering dependencies. In
108 // particular, during drag and drop (and when a modal dialog is shown as
109 // a result of choosing a context menu) it is possible that an event is
110 // being processed by the host, so that host is on the stack when we need to
111 // close the window. If we closed the window immediately (and deleted it),
112 // when control returned back to host we would crash as host was deleted.
115 // If mouse capture was grabbed, it is released. Does nothing if mouse was
117 void ReleaseCapture();
119 // Overriden from View to prevent tab from doing anything.
120 bool SkipDefaultKeyEventProcessing(const ui::KeyEvent
& e
) override
;
122 // Returns the parent menu item we're showing children for.
123 MenuItemView
* GetMenuItem() const;
125 // Set the drop item and position.
126 void SetDropMenuItem(MenuItemView
* item
,
127 MenuDelegate::DropPosition position
);
129 // Returns whether the selection should be shown for the specified item.
130 // The selection is NOT shown during drag and drop when the drop is over
132 bool GetShowSelection(MenuItemView
* item
);
134 // Returns the container for the SubmenuView.
135 MenuScrollViewContainer
* GetScrollViewContainer();
137 // Invoked if the menu is prematurely destroyed. This can happen if the window
138 // closes while the menu is shown. If invoked the SubmenuView must drop all
139 // references to the MenuHost as the MenuHost is about to be deleted.
140 void MenuHostDestroyed();
142 // Max width of minor text (accelerator or subtitle) in child menu items. This
143 // doesn't include children's children, only direct children.
144 int max_minor_text_width() const { return max_minor_text_width_
; }
146 // Minimum width of menu in pixels (default 0). This becomes the smallest
147 // width returned by GetPreferredSize().
148 void set_minimum_preferred_width(int minimum_preferred_width
) {
149 minimum_preferred_width_
= minimum_preferred_width
;
152 // Automatically resize menu if a subview's preferred size changes.
153 bool resize_open_menu() const { return resize_open_menu_
; }
154 void set_resize_open_menu(bool resize_open_menu
) {
155 resize_open_menu_
= resize_open_menu
;
159 // Overridden from View:
160 const char* GetClassName() const override
;
162 // View method. Overridden to schedule a paint. We do this so that when
163 // scrolling occurs, everything is repainted correctly.
164 void OnBoundsChanged(const gfx::Rect
& previous_bounds
) override
;
166 void ChildPreferredSizeChanged(View
* child
) override
;
169 void SchedulePaintForDropIndicator(MenuItemView
* item
,
170 MenuDelegate::DropPosition position
);
172 // Calculates the location of th edrop indicator.
173 gfx::Rect
CalculateDropIndicatorBounds(MenuItemView
* item
,
174 MenuDelegate::DropPosition position
);
176 // Implementation of ScrollDelegate
177 bool OnScroll(float dx
, float dy
) override
;
180 MenuItemView
* parent_menu_item_
;
182 // Widget subclass used to show the children. This is deleted when we invoke
183 // |DestroyMenuHost|, or |MenuHostDestroyed| is invoked back on us.
186 // If non-null, indicates a drop is in progress and drop_item is the item
188 MenuItemView
* drop_item_
;
190 // Position of the drop.
191 MenuDelegate::DropPosition drop_position_
;
193 // Ancestor of the SubmenuView, lazily created.
194 MenuScrollViewContainer
* scroll_view_container_
;
196 // See description above getter.
197 mutable int max_minor_text_width_
;
199 // Minimum width returned in GetPreferredSize().
200 int minimum_preferred_width_
;
202 // Reposition open menu when contained views change size.
203 bool resize_open_menu_
;
205 // The submenu's scroll animator
206 scoped_ptr
<ScrollAnimator
> scroll_animator_
;
208 // Difference between current position and cumulative deltas passed to
210 // TODO(tdresser): This should be removed when raw pixel scrolling for views
211 // is enabled. See crbug.com/329354.
212 float roundoff_error_
;
214 PrefixSelector prefix_selector_
;
216 DISALLOW_COPY_AND_ASSIGN(SubmenuView
);
221 #endif // UI_VIEWS_CONTROLS_MENU_SUBMENU_VIEW_H_