• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_MENU_H_
6 #define UI_VIEWS_CONTROLS_MENU_MENU_H_
7 
8 #include <string>
9 
10 #include "base/basictypes.h"
11 #include "base/strings/string16.h"
12 #include "ui/gfx/native_widget_types.h"
13 #include "ui/views/views_export.h"
14 
15 namespace gfx {
16 class ImageSkia;
17 class Point;
18 }
19 
20 namespace ui {
21 class Accelerator;
22 }
23 
24 namespace views {
25 
26 class VIEWS_EXPORT Menu {
27  public:
28   /////////////////////////////////////////////////////////////////////////////
29   //
30   // Delegate Interface
31   //
32   //  Classes implement this interface to tell the menu system more about each
33   //  item as it is created.
34   //
35   /////////////////////////////////////////////////////////////////////////////
36   class VIEWS_EXPORT Delegate {
37    public:
~Delegate()38     virtual ~Delegate() {}
39 
40     // Whether or not an item should be shown as checked.
41     virtual bool IsItemChecked(int id) const;
42 
43     // Whether or not an item should be shown as the default (using bold).
44     // There can only be one default menu item.
45     virtual bool IsItemDefault(int id) const;
46 
47     // The string shown for the menu item.
48     virtual base::string16 GetLabel(int id) const;
49 
50     // The delegate needs to implement this function if it wants to display
51     // the shortcut text next to each menu item. If there is an accelerator
52     // for a given item id, the implementor must return it.
53     virtual bool GetAcceleratorInfo(int id, ui::Accelerator* accel);
54 
55     // The icon shown for the menu item.
56     virtual const gfx::ImageSkia& GetIcon(int id) const;
57 
58     // The number of items to show in the menu
59     virtual int GetItemCount() const;
60 
61     // Whether or not an item is a separator.
62     virtual bool IsItemSeparator(int id) const;
63 
64     // Shows the context menu with the specified id. This is invoked when the
65     // user does the appropriate gesture to show a context menu. The id
66     // identifies the id of the menu to show the context menu for.
67     // is_mouse_gesture is true if this is the result of a mouse gesture.
68     // If this is not the result of a mouse gesture |p| is the recommended
69     // location to display the content menu at. In either case, |p| is in
70     // screen coordinates.
ShowContextMenu(Menu * source,int id,const gfx::Point & p,bool is_mouse_gesture)71     virtual void ShowContextMenu(Menu* source,
72                                  int id,
73                                  const gfx::Point& p,
74                                  bool is_mouse_gesture) {
75     }
76 
77     // Whether an item has an icon.
78     virtual bool HasIcon(int id) const;
79 
80     // Notification that the menu is about to be popped up.
MenuWillShow()81     virtual void MenuWillShow() {
82     }
83 
84     // Whether to create a right-to-left menu. The default implementation
85     // returns true if the locale's language is a right-to-left language (such
86     // as Hebrew) and false otherwise. This is generally the right behavior
87     // since there is no reason to show left-to-right menus for right-to-left
88     // locales. However, subclasses can override this behavior so that the menu
89     // is a right-to-left menu only if the view's layout is right-to-left
90     // (since the view can use a different layout than the locale's language
91     // layout).
92     virtual bool IsRightToLeftUILayout() const;
93 
94     // Controller
95     virtual bool SupportsCommand(int id) const;
96     virtual bool IsCommandEnabled(int id) const;
97     virtual bool GetContextualLabel(int id, base::string16* out) const;
ExecuteCommand(int id)98     virtual void ExecuteCommand(int id) {
99     }
100 
101    protected:
102     // Returns an empty icon.
103     const gfx::ImageSkia& GetEmptyIcon() const;
104   };
105 
106   // How this popup should align itself relative to the point it is run at.
107   enum AnchorPoint {
108     TOPLEFT,
109     TOPRIGHT
110   };
111 
112   // Different types of menu items
113   enum MenuItemType {
114     NORMAL,
115     CHECKBOX,
116     RADIO,
117     SEPARATOR
118   };
119 
120   // Construct a Menu using the specified controller to determine command
121   // state.
122   // delegate     A Menu::Delegate implementation that provides more
123   //              information about the Menu presentation.
124   // anchor       An alignment hint for the popup menu.
125   // owner        The window that the menu is being brought up relative
126   //              to. Not actually used for anything but must not be
127   //              NULL.
128   Menu(Delegate* delegate, AnchorPoint anchor);
129   Menu();
130   virtual ~Menu();
131 
132   static Menu* Create(Delegate* delegate,
133                       AnchorPoint anchor,
134                       gfx::NativeView parent);
135 
136   // Creates a new menu with the contents of the system menu for the given
137   // parent window. The caller owns the returned pointer.
138   static Menu* GetSystemMenu(gfx::NativeWindow parent);
139 
set_delegate(Delegate * delegate)140   void set_delegate(Delegate* delegate) { delegate_ = delegate; }
delegate()141   Delegate* delegate() const { return delegate_; }
142 
anchor()143   AnchorPoint anchor() const { return anchor_; }
144 
145   // Adds an item to this menu.
146   // item_id    The id of the item, used to identify it in delegate callbacks
147   //            or (if delegate is NULL) to identify the command associated
148   //            with this item with the controller specified in the ctor. Note
149   //            that this value should not be 0 as this has a special meaning
150   //            ("NULL command, no item selected")
151   // label      The text label shown.
152   // type       The type of item.
153   void AppendMenuItem(int item_id,
154                       const base::string16& label,
155                       MenuItemType type);
156   void AddMenuItem(int index,
157                    int item_id,
158                    const base::string16& label,
159                    MenuItemType type);
160 
161   // Append a submenu to this menu.
162   // The returned pointer is owned by this menu.
163   Menu* AppendSubMenu(int item_id,
164                       const base::string16& label);
165   Menu* AddSubMenu(int index, int item_id, const base::string16& label);
166 
167   // Append a submenu with an icon to this menu
168   // The returned pointer is owned by this menu.
169   // Unless the icon is empty, calling this function forces the Menu class
170   // to draw the menu, instead of relying on Windows.
171   Menu* AppendSubMenuWithIcon(int item_id,
172                               const base::string16& label,
173                               const gfx::ImageSkia& icon);
174   virtual Menu* AddSubMenuWithIcon(int index,
175                                    int item_id,
176                                    const base::string16& label,
177                                    const gfx::ImageSkia& icon) = 0;
178 
179   // This is a convenience for standard text label menu items where the label
180   // is provided with this call.
181   void AppendMenuItemWithLabel(int item_id, const base::string16& label);
182   void AddMenuItemWithLabel(int index,
183                             int item_id,
184                             const base::string16& label);
185 
186   // This is a convenience for text label menu items where the label is
187   // provided by the delegate.
188   void AppendDelegateMenuItem(int item_id);
189   void AddDelegateMenuItem(int index, int item_id);
190 
191   // Adds a separator to this menu
192   void AppendSeparator();
193   virtual void AddSeparator(int index) = 0;
194 
195   // Appends a menu item with an icon. This is for the menu item which
196   // needs an icon. Calling this function forces the Menu class to draw
197   // the menu, instead of relying on Windows.
198   void AppendMenuItemWithIcon(int item_id,
199                               const base::string16& label,
200                               const gfx::ImageSkia& icon);
201   virtual void AddMenuItemWithIcon(int index,
202                                    int item_id,
203                                    const base::string16& label,
204                                    const gfx::ImageSkia& icon);
205 
206   // Enables or disables the item with the specified id.
207   virtual void EnableMenuItemByID(int item_id, bool enabled) = 0;
208   virtual void EnableMenuItemAt(int index, bool enabled) = 0;
209 
210   // Sets menu label at specified index.
211   virtual void SetMenuLabel(int item_id, const base::string16& label) = 0;
212 
213   // Sets an icon for an item with a given item_id. Calling this function
214   // also forces the Menu class to draw the menu, instead of relying on Windows.
215   // Returns false if the item with |item_id| is not found.
216   virtual bool SetIcon(const gfx::ImageSkia& icon, int item_id) = 0;
217 
218   // Shows the menu, blocks until the user dismisses the menu or selects an
219   // item, and executes the command for the selected item (if any).
220   // Warning: Blocking call. Will implicitly run a message loop.
221   virtual void RunMenuAt(int x, int y) = 0;
222 
223   // Cancels the menu.
224   virtual void Cancel() = 0;
225 
226   // Returns the number of menu items.
227   virtual int ItemCount() = 0;
228 
229 #if defined(OS_WIN)
230   // Returns the underlying menu handle
231   virtual HMENU GetMenuHandle() const = 0;
232 #endif  // defined(OS_WIN)
233 
234  protected:
235   explicit Menu(Menu* parent);
236 
237   virtual void AddMenuItemInternal(int index,
238                                    int item_id,
239                                    const base::string16& label,
240                                    const gfx::ImageSkia& icon,
241                                    MenuItemType type) = 0;
242 
243  private:
244   // The delegate that is being used to get information about the presentation.
245   Delegate* delegate_;
246 
247   // How this popup menu should be aligned relative to the point it is run at.
248   AnchorPoint anchor_;
249 
250   DISALLOW_COPY_AND_ASSIGN(Menu);
251 };
252 
253 }  // namespace views
254 
255 #endif  // UI_VIEWS_CONTROLS_MENU_MENU_H_
256