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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
// Copyright (c) 2010 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_
#pragma once
#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;
// Invoked if the menu is prematurely destroyed. This can happen if the window
// closes while the menu is shown. If invoked the SubmenuView must drop all
// references to the MenuHost as the MenuHost is about to be deleted.
void MenuHostDestroyed();
// Max width of accelerators in child menu items. This doesn't include
// children's children, only direct children.
int max_accelerator_width() const { return max_accelerator_width_; }
// 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. This is deleted when we invoke
// |DestroyMenuHost|, or |MenuHostDestroyed| is invoked back on us.
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_;
// See description above getter.
int max_accelerator_width_;
DISALLOW_COPY_AND_ASSIGN(SubmenuView);
};
} // namespace views
#endif // VIEWS_CONTROLS_MENU_SUBMENU_VIEW_H_
|