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 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, 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 string16& label,
    155                       MenuItemType type);
    156   void AddMenuItem(int index,
    157                    int item_id,
    158                    const 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 string16& label);
    165   Menu* AddSubMenu(int index, int item_id, const 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 string16& label,
    173                               const gfx::ImageSkia& icon);
    174   virtual Menu* AddSubMenuWithIcon(int index,
    175                                    int item_id,
    176                                    const 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 string16& label);
    182   void AddMenuItemWithLabel(int index, int item_id, const string16& label);
    183 
    184   // This is a convenience for text label menu items where the label is
    185   // provided by the delegate.
    186   void AppendDelegateMenuItem(int item_id);
    187   void AddDelegateMenuItem(int index, int item_id);
    188 
    189   // Adds a separator to this menu
    190   void AppendSeparator();
    191   virtual void AddSeparator(int index) = 0;
    192 
    193   // Appends a menu item with an icon. This is for the menu item which
    194   // needs an icon. Calling this function forces the Menu class to draw
    195   // the menu, instead of relying on Windows.
    196   void AppendMenuItemWithIcon(int item_id,
    197                               const string16& label,
    198                               const gfx::ImageSkia& icon);
    199   virtual void AddMenuItemWithIcon(int index,
    200                                    int item_id,
    201                                    const string16& label,
    202                                    const gfx::ImageSkia& icon);
    203 
    204   // Enables or disables the item with the specified id.
    205   virtual void EnableMenuItemByID(int item_id, bool enabled) = 0;
    206   virtual void EnableMenuItemAt(int index, bool enabled) = 0;
    207 
    208   // Sets menu label at specified index.
    209   virtual void SetMenuLabel(int item_id, const string16& label) = 0;
    210 
    211   // Sets an icon for an item with a given item_id. Calling this function
    212   // also forces the Menu class to draw the menu, instead of relying on Windows.
    213   // Returns false if the item with |item_id| is not found.
    214   virtual bool SetIcon(const gfx::ImageSkia& icon, int item_id) = 0;
    215 
    216   // Shows the menu, blocks until the user dismisses the menu or selects an
    217   // item, and executes the command for the selected item (if any).
    218   // Warning: Blocking call. Will implicitly run a message loop.
    219   virtual void RunMenuAt(int x, int y) = 0;
    220 
    221   // Cancels the menu.
    222   virtual void Cancel() = 0;
    223 
    224   // Returns the number of menu items.
    225   virtual int ItemCount() = 0;
    226 
    227 #if defined(OS_WIN)
    228   // Returns the underlying menu handle
    229   virtual HMENU GetMenuHandle() const = 0;
    230 #endif  // defined(OS_WIN)
    231 
    232  protected:
    233   explicit Menu(Menu* parent);
    234 
    235   virtual void AddMenuItemInternal(int index,
    236                                    int item_id,
    237                                    const string16& label,
    238                                    const gfx::ImageSkia& icon,
    239                                    MenuItemType type) = 0;
    240 
    241  private:
    242   // The delegate that is being used to get information about the presentation.
    243   Delegate* delegate_;
    244 
    245   // How this popup menu should be aligned relative to the point it is run at.
    246   AnchorPoint anchor_;
    247 
    248   DISALLOW_COPY_AND_ASSIGN(Menu);
    249 };
    250 
    251 }  // namespace views
    252 
    253 #endif  // UI_VIEWS_CONTROLS_MENU_MENU_H_
    254