1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef VIEWS_CONTROLS_MENU_SUBMENU_VIEW_H_
#define VIEWS_CONTROLS_MENU_SUBMENU_VIEW_H_
#include "views/controls/menu/menu_delegate.h"
#include "views/view.h"
namespace views {
class MenuHost;
class MenuItemView;
class MenuScrollViewContainer;
// SubmenuView is the parent of all menu items.
//
// SubmenuView has the following responsibilities:
// . It positions and sizes all child views (any type of View may be added,
// not just MenuItemViews).
// . Forwards the appropriate events to the MenuController. This allows the
// MenuController to update the selection as the user moves the mouse around.
// . Renders the drop indicator during a drop operation.
// . Shows and hides the window (a WidgetWin) when the menu is shown on
// screen.
//
// SubmenuView is itself contained in a MenuScrollViewContainer.
// MenuScrollViewContainer handles showing as much of the SubmenuView as the
// screen allows. If the SubmenuView is taller than the screen, scroll buttons
// are provided that allow the user to see all the menu items.
class SubmenuView : public View {
public:
// Creates a SubmenuView for the specified menu item.
explicit SubmenuView(MenuItemView* parent);
~SubmenuView();
// Returns the number of child views that are MenuItemViews.
// MenuItemViews are identified by ID.
int GetMenuItemCount();
// Returns the MenuItemView at the specified index.
MenuItemView* GetMenuItemAt(int index);
// Positions and sizes the child views. This tiles the views vertically,
// giving each child the available width.
virtual void Layout();
virtual gfx::Size GetPreferredSize();
// View method. Overriden to schedule a paint. We do this so that when
// scrolling occurs, everything is repainted correctly.
virtual void DidChangeBounds(const gfx::Rect& previous,
const gfx::Rect& current);
// Painting.
void PaintChildren(gfx::Canvas* canvas);
// Drag and drop methods. These are forwarded to the MenuController.
virtual bool GetDropFormats(
int* formats,
std::set<OSExchangeData::CustomFormat>* custom_formats);
virtual bool AreDropTypesRequired();
virtual bool CanDrop(const OSExchangeData& data);
virtual void OnDragEntered(const DropTargetEvent& event);
virtual int OnDragUpdated(const DropTargetEvent& event);
virtual void OnDragExited();
virtual int OnPerformDrop(const DropTargetEvent& event);
// Scrolls on menu item boundaries.
virtual bool OnMouseWheel(const MouseWheelEvent& e);
// Returns true if the menu is showing.
bool IsShowing();
// Shows the menu at the specified location. Coordinates are in screen
// coordinates. max_width gives the max width the view should be.
void ShowAt(gfx::NativeWindow parent, const gfx::Rect& bounds, bool do_capture);
// Resets the bounds of the submenu to |bounds|.
void Reposition(const gfx::Rect& bounds);
// Closes the menu, destroying the host.
void Close();
// Hides the hosting window.
//
// The hosting window is hidden first, then deleted (Close) when the menu is
// done running. This is done to avoid deletion ordering dependencies. In
// particular, during drag and drop (and when a modal dialog is shown as
// a result of choosing a context menu) it is possible that an event is
// being processed by the host, so that host is on the stack when we need to
// close the window. If we closed the window immediately (and deleted it),
// when control returned back to host we would crash as host was deleted.
void Hide();
// If mouse capture was grabbed, it is released. Does nothing if mouse was
// not captured.
void ReleaseCapture();
// Overriden from View to prevent tab from doing anything.
virtual bool SkipDefaultKeyEventProcessing(const KeyEvent& e);
// Returns the parent menu item we're showing children for.
MenuItemView* GetMenuItem() const { return parent_menu_item_; }
// Set the drop item and position.
void SetDropMenuItem(MenuItemView* item,
MenuDelegate::DropPosition position);
// Returns whether the selection should be shown for the specified item.
// The selection is NOT shown during drag and drop when the drop is over
// the menu.
bool GetShowSelection(MenuItemView* item);
// Returns the container for the SubmenuView.
MenuScrollViewContainer* GetScrollViewContainer();
// Returns the NativeWindow host of the menu, or NULL if not showing.
gfx::NativeWindow native_window() const;
// Padding around the edges of the submenu.
static const int kSubmenuBorderSize;
private:
// Paints the drop indicator. This is only invoked if item is non-NULL and
// position is not DROP_NONE.
void PaintDropIndicator(gfx::Canvas* canvas,
MenuItemView* item,
MenuDelegate::DropPosition position);
void SchedulePaintForDropIndicator(MenuItemView* item,
MenuDelegate::DropPosition position);
// Calculates the location of th edrop indicator.
gfx::Rect CalculateDropIndicatorBounds(MenuItemView* item,
MenuDelegate::DropPosition position);
// Parent menu item.
MenuItemView* parent_menu_item_;
// Widget subclass used to show the children.
MenuHost* host_;
// If non-null, indicates a drop is in progress and drop_item is the item
// the drop is over.
MenuItemView* drop_item_;
// Position of the drop.
MenuDelegate::DropPosition drop_position_;
// Ancestor of the SubmenuView, lazily created.
MenuScrollViewContainer* scroll_view_container_;
DISALLOW_COPY_AND_ASSIGN(SubmenuView);
};
} // namespace views
#endif // VIEWS_CONTROLS_MENU_SUBMENU_VIEW_H_
|