Home | History | Annotate | Download | only in menu
      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:
     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.
     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.
     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;
     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 
    140   void set_delegate(Delegate* delegate) { delegate_ = delegate; }
    141   Delegate* delegate() const { return delegate_; }
    142 
    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