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_BASE_MODELS_SIMPLE_MENU_MODEL_H_ 6 #define UI_BASE_MODELS_SIMPLE_MENU_MODEL_H_ 7 8 #include <vector> 9 10 #include "base/memory/weak_ptr.h" 11 #include "base/strings/string16.h" 12 #include "ui/base/models/menu_model.h" 13 14 namespace gfx { 15 class Image; 16 } 17 18 namespace ui { 19 20 class ButtonMenuItemModel; 21 22 // A simple MenuModel implementation with an imperative API for adding menu 23 // items. This makes it easy to construct fixed menus. Menus populated by 24 // dynamic data sources may be better off implementing MenuModel directly. 25 // The breadth of MenuModel is not exposed through this API. 26 class UI_EXPORT SimpleMenuModel : public MenuModel { 27 public: 28 class UI_EXPORT Delegate { 29 public: 30 // Methods for determining the state of specific command ids. 31 virtual bool IsCommandIdChecked(int command_id) const = 0; 32 virtual bool IsCommandIdEnabled(int command_id) const = 0; 33 virtual bool IsCommandIdVisible(int command_id) const; 34 35 // Gets the accelerator for the specified command id. Returns true if the 36 // command id has a valid accelerator, false otherwise. 37 virtual bool GetAcceleratorForCommandId( 38 int command_id, 39 ui::Accelerator* accelerator) = 0; 40 41 // Some command ids have labels, sublabels and icons that change over time. 42 virtual bool IsItemForCommandIdDynamic(int command_id) const; 43 virtual base::string16 GetLabelForCommandId(int command_id) const; 44 virtual base::string16 GetSublabelForCommandId(int command_id) const; 45 // Gets the icon for the item with the specified id, returning true if there 46 // is an icon, false otherwise. 47 virtual bool GetIconForCommandId(int command_id, 48 gfx::Image* icon) const; 49 50 // Notifies the delegate that the item with the specified command id was 51 // visually highlighted within the menu. 52 virtual void CommandIdHighlighted(int command_id); 53 54 // Performs the action associates with the specified command id. 55 // The passed |event_flags| are the flags from the event which issued this 56 // command and they can be examined to find modifier keys. 57 virtual void ExecuteCommand(int command_id, int event_flags) = 0; 58 59 // Notifies the delegate that the menu is about to show. 60 virtual void MenuWillShow(SimpleMenuModel* source); 61 62 // Notifies the delegate that the menu has closed. 63 virtual void MenuClosed(SimpleMenuModel* source); 64 65 protected: 66 virtual ~Delegate() {} 67 }; 68 69 // The Delegate can be NULL, though if it is items can't be checked or 70 // disabled. 71 explicit SimpleMenuModel(Delegate* delegate); 72 virtual ~SimpleMenuModel(); 73 74 // Methods for adding items to the model. 75 void AddItem(int command_id, const base::string16& label); 76 void AddItemWithStringId(int command_id, int string_id); 77 void AddCheckItem(int command_id, const base::string16& label); 78 void AddCheckItemWithStringId(int command_id, int string_id); 79 void AddRadioItem(int command_id, const base::string16& label, int group_id); 80 void AddRadioItemWithStringId(int command_id, int string_id, int group_id); 81 82 // Adds a separator of the specified type to the model. 83 // - Adding a separator after another separator is always invalid if they 84 // differ in type, but silently ignored if they are both NORMAL. 85 // - Adding a separator to an empty model is invalid, unless they are NORMAL 86 // or SPACING. NORMAL separators are silently ignored if the model is empty. 87 void AddSeparator(MenuSeparatorType separator_type); 88 89 // Removes separators until the model's last entry is not a separator, or the 90 // model is empty. 91 void RemoveTrailingSeparators(); 92 93 // These three methods take pointers to various sub-models. These models 94 // should be owned by the same owner of this SimpleMenuModel. 95 void AddButtonItem(int command_id, ButtonMenuItemModel* model); 96 void AddSubMenu(int command_id, 97 const base::string16& label, 98 MenuModel* model); 99 void AddSubMenuWithStringId(int command_id, int string_id, MenuModel* model); 100 101 // Methods for inserting items into the model. 102 void InsertItemAt(int index, int command_id, const base::string16& label); 103 void InsertItemWithStringIdAt(int index, int command_id, int string_id); 104 void InsertSeparatorAt(int index, MenuSeparatorType separator_type); 105 void InsertCheckItemAt(int index, 106 int command_id, 107 const base::string16& label); 108 void InsertCheckItemWithStringIdAt(int index, int command_id, int string_id); 109 void InsertRadioItemAt(int index, 110 int command_id, 111 const base::string16& label, 112 int group_id); 113 void InsertRadioItemWithStringIdAt( 114 int index, int command_id, int string_id, int group_id); 115 void InsertSubMenuAt(int index, 116 int command_id, 117 const base::string16& label, 118 MenuModel* model); 119 void InsertSubMenuWithStringIdAt( 120 int index, int command_id, int string_id, MenuModel* model); 121 122 // Sets the icon for the item at |index|. 123 void SetIcon(int index, const gfx::Image& icon); 124 125 // Sets the sublabel for the item at |index|. 126 void SetSublabel(int index, const base::string16& sublabel); 127 128 // Clears all items. Note that it does not free MenuModel of submenu. 129 void Clear(); 130 131 // Returns the index of the item that has the given |command_id|. Returns 132 // -1 if not found. 133 int GetIndexOfCommandId(int command_id); 134 135 // Overridden from MenuModel: 136 virtual bool HasIcons() const OVERRIDE; 137 virtual int GetItemCount() const OVERRIDE; 138 virtual ItemType GetTypeAt(int index) const OVERRIDE; 139 virtual ui::MenuSeparatorType GetSeparatorTypeAt(int index) const OVERRIDE; 140 virtual int GetCommandIdAt(int index) const OVERRIDE; 141 virtual base::string16 GetLabelAt(int index) const OVERRIDE; 142 virtual base::string16 GetSublabelAt(int index) const OVERRIDE; 143 virtual bool IsItemDynamicAt(int index) const OVERRIDE; 144 virtual bool GetAcceleratorAt(int index, 145 ui::Accelerator* accelerator) const OVERRIDE; 146 virtual bool IsItemCheckedAt(int index) const OVERRIDE; 147 virtual int GetGroupIdAt(int index) const OVERRIDE; 148 virtual bool GetIconAt(int index, gfx::Image* icon) OVERRIDE; 149 virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt( 150 int index) const OVERRIDE; 151 virtual bool IsEnabledAt(int index) const OVERRIDE; 152 virtual bool IsVisibleAt(int index) const OVERRIDE; 153 virtual void HighlightChangedTo(int index) OVERRIDE; 154 virtual void ActivatedAt(int index) OVERRIDE; 155 virtual void ActivatedAt(int index, int event_flags) OVERRIDE; 156 virtual MenuModel* GetSubmenuModelAt(int index) const OVERRIDE; 157 virtual void MenuWillShow() OVERRIDE; 158 virtual void MenuClosed() OVERRIDE; 159 virtual void SetMenuModelDelegate( 160 ui::MenuModelDelegate* menu_model_delegate) OVERRIDE; 161 virtual MenuModelDelegate* GetMenuModelDelegate() const OVERRIDE; 162 163 protected: 164 void set_delegate(Delegate* delegate) { delegate_ = delegate; } 165 Delegate* delegate() { return delegate_; } 166 167 private: 168 struct Item; 169 170 typedef std::vector<Item> ItemVector; 171 172 // Returns |index|. 173 int ValidateItemIndex(int index) const; 174 175 // Functions for inserting items into |items_|. 176 void AppendItem(const Item& item); 177 void InsertItemAtIndex(const Item& item, int index); 178 void ValidateItem(const Item& item); 179 180 // Notify the delegate that the menu is closed. 181 void OnMenuClosed(); 182 183 ItemVector items_; 184 185 Delegate* delegate_; 186 187 MenuModelDelegate* menu_model_delegate_; 188 189 base::WeakPtrFactory<SimpleMenuModel> method_factory_; 190 191 DISALLOW_COPY_AND_ASSIGN(SimpleMenuModel); 192 }; 193 194 } // namespace ui 195 196 #endif // UI_BASE_MODELS_SIMPLE_MENU_MODEL_H_ 197