wrench_menu.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1// Copyright 2013 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 CHROME_BROWSER_UI_VIEWS_TOOLBAR_WRENCH_MENU_H_
6#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_WRENCH_MENU_H_
7
8#include <map>
9#include <utility>
10
11#include "base/memory/scoped_ptr.h"
12#include "base/observer_list.h"
13#include "components/bookmarks/browser/base_bookmark_model_observer.h"
14#include "content/public/browser/notification_observer.h"
15#include "content/public/browser/notification_registrar.h"
16#include "ui/base/models/menu_model.h"
17#include "ui/views/controls/menu/menu_delegate.h"
18
19class BookmarkMenuDelegate;
20class Browser;
21class WrenchMenuObserver;
22
23namespace ui {
24class NativeTheme;
25}
26
27namespace views {
28class MenuButton;
29struct MenuConfig;
30class MenuItemView;
31class MenuRunner;
32class View;
33}  // namespace views
34
35// WrenchMenu adapts the WrenchMenuModel to view's menu related classes.
36class WrenchMenu : public views::MenuDelegate,
37                   public BaseBookmarkModelObserver,
38                   public content::NotificationObserver {
39 public:
40  // TODO: remove |use_new_menu| and |supports_new_separators|.
41  WrenchMenu(Browser* browser,
42             bool use_new_menu,
43             bool supports_new_separators);
44  virtual ~WrenchMenu();
45
46  void Init(ui::MenuModel* model);
47
48  // Shows the menu relative to the specified view.
49  void RunMenu(views::MenuButton* host);
50
51  // Whether the menu is currently visible to the user.
52  bool IsShowing();
53
54  bool use_new_menu() const { return use_new_menu_; }
55
56  void AddObserver(WrenchMenuObserver* observer);
57  void RemoveObserver(WrenchMenuObserver* observer);
58
59  // MenuDelegate overrides:
60  virtual const gfx::FontList* GetLabelFontList(int command_id) const OVERRIDE;
61  virtual bool GetShouldUseDisabledEmphasizedForegroundColor(
62      int command_id) const OVERRIDE;
63  virtual base::string16 GetTooltipText(int command_id,
64                                        const gfx::Point& p) const OVERRIDE;
65  virtual bool IsTriggerableEvent(views::MenuItemView* menu,
66                                  const ui::Event& e) OVERRIDE;
67  virtual bool GetDropFormats(
68      views::MenuItemView* menu,
69      int* formats,
70      std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
71  virtual bool AreDropTypesRequired(views::MenuItemView* menu) OVERRIDE;
72  virtual bool CanDrop(views::MenuItemView* menu,
73                       const ui::OSExchangeData& data) OVERRIDE;
74  virtual int GetDropOperation(views::MenuItemView* item,
75                               const ui::DropTargetEvent& event,
76                               DropPosition* position) OVERRIDE;
77  virtual int OnPerformDrop(views::MenuItemView* menu,
78                            DropPosition position,
79                            const ui::DropTargetEvent& event) OVERRIDE;
80  virtual bool ShowContextMenu(views::MenuItemView* source,
81                               int command_id,
82                               const gfx::Point& p,
83                               ui::MenuSourceType source_type) OVERRIDE;
84  virtual bool CanDrag(views::MenuItemView* menu) OVERRIDE;
85  virtual void WriteDragData(views::MenuItemView* sender,
86                             ui::OSExchangeData* data) OVERRIDE;
87  virtual int GetDragOperations(views::MenuItemView* sender) OVERRIDE;
88  virtual int GetMaxWidthForMenu(views::MenuItemView* menu) OVERRIDE;
89  virtual bool IsItemChecked(int command_id) const OVERRIDE;
90  virtual bool IsCommandEnabled(int command_id) const OVERRIDE;
91  virtual void ExecuteCommand(int command_id, int mouse_event_flags) OVERRIDE;
92  virtual bool GetAccelerator(int command_id,
93                              ui::Accelerator* accelerator) const OVERRIDE;
94  virtual void WillShowMenu(views::MenuItemView* menu) OVERRIDE;
95  virtual void WillHideMenu(views::MenuItemView* menu) OVERRIDE;
96
97  // BaseBookmarkModelObserver overrides:
98  virtual void BookmarkModelChanged() OVERRIDE;
99
100  // content::NotificationObserver overrides:
101  virtual void Observe(int type,
102                       const content::NotificationSource& source,
103                       const content::NotificationDetails& details) OVERRIDE;
104
105 private:
106  class CutCopyPasteView;
107  class RecentTabsMenuModelDelegate;
108  class ZoomView;
109
110  typedef std::pair<ui::MenuModel*,int> Entry;
111  typedef std::map<int,Entry> CommandIDToEntry;
112
113  // Populates |parent| with all the child menus in |model|. Recursively invokes
114  // |PopulateMenu| for any submenu.
115  void PopulateMenu(views::MenuItemView* parent,
116                    ui::MenuModel* model);
117
118  // Adds a new menu item to |parent| at |menu_index| to represent the item in
119  // |model| at |model_index|:
120  // - |menu_index|: position in |parent| to add the new item.
121  // - |model_index|: position in |model| to retrieve information about the
122  //   new menu item.
123  // - |height|: For button containing menu items, a |height| override can be
124  //   specified with a number bigger then 0.
125  // The returned item's MenuItemView::GetCommand() is the same as that of
126  // |model|->GetCommandIdAt(|model_index|).
127  views::MenuItemView* AddMenuItem(views::MenuItemView* parent,
128                                   int menu_index,
129                                   ui::MenuModel* model,
130                                   int model_index,
131                                   ui::MenuModel::ItemType menu_type,
132                                   int height);
133
134  // Invoked from the cut/copy/paste menus. Cancels the current active menu and
135  // activates the menu item in |model| at |index|.
136  void CancelAndEvaluate(ui::MenuModel* model, int index);
137
138  // Creates the bookmark menu if necessary. Does nothing if already created or
139  // the bookmark model isn't loaded.
140  void CreateBookmarkMenu();
141
142  // Returns the index of the MenuModel/index pair representing the |command_id|
143  // in |command_id_to_entry_|.
144  int ModelIndexFromCommandId(int command_id) const;
145
146  // The views menu. Owned by |menu_runner_|.
147  views::MenuItemView* root_;
148
149  scoped_ptr<views::MenuRunner> menu_runner_;
150
151  // Maps from the command ID in model to the model/index pair the item came
152  // from.
153  CommandIDToEntry command_id_to_entry_;
154
155  // Browser the menu is being shown for.
156  Browser* browser_;
157
158  // |CancelAndEvaluate| sets |selected_menu_model_| and |selected_index_|.
159  // If |selected_menu_model_| is non-null after the menu completes
160  // ActivatedAt is invoked. This is done so that ActivatedAt isn't invoked
161  // while the message loop is nested.
162  ui::MenuModel* selected_menu_model_;
163  int selected_index_;
164
165  // Used for managing the bookmark menu items.
166  scoped_ptr<BookmarkMenuDelegate> bookmark_menu_delegate_;
167
168  // Menu corresponding to IDC_BOOKMARKS_MENU.
169  views::MenuItemView* bookmark_menu_;
170
171  // Menu corresponding to IDC_FEEDBACK.
172  views::MenuItemView* feedback_menu_item_;
173
174  // Used for managing "Recent tabs" menu items.
175  scoped_ptr<RecentTabsMenuModelDelegate> recent_tabs_menu_model_delegate_;
176
177  content::NotificationRegistrar registrar_;
178
179  const bool use_new_menu_;
180
181  const bool supports_new_separators_;
182
183  ObserverList<WrenchMenuObserver> observer_list_;
184
185  DISALLOW_COPY_AND_ASSIGN(WrenchMenu);
186};
187
188#endif  // CHROME_BROWSER_UI_VIEWS_TOOLBAR_WRENCH_MENU_H_
189