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