Home | History | Annotate | Download | only in models
      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