Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: chrome/browser/ui/views/toolbar/chevron_menu_button.cc

Issue 661493004: Add infrastructure for Chrome Actions (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/toolbar/chevron_menu_button.h" 5 #include "chrome/browser/ui/views/toolbar/chevron_menu_button.h"
6 6
7 #include "base/memory/scoped_vector.h" 7 #include "base/memory/scoped_vector.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/extensions/extension_action.h" 10 #include "chrome/browser/extensions/extension_action.h"
11 #include "chrome/browser/extensions/extension_action_icon_factory.h"
11 #include "chrome/browser/extensions/extension_context_menu_model.h" 12 #include "chrome/browser/extensions/extension_context_menu_model.h"
12 #include "chrome/browser/extensions/extension_toolbar_model.h" 13 #include "chrome/browser/extensions/extension_toolbar_model.h"
13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h" 15 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" 16 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
17 #include "chrome/browser/ui/views/extensions/extension_action_view_controller.h"
16 #include "chrome/browser/ui/views/toolbar/browser_action_view.h" 18 #include "chrome/browser/ui/views/toolbar/browser_action_view.h"
17 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" 19 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
18 #include "extensions/browser/extension_registry.h"
19 #include "extensions/common/extension.h" 20 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_set.h"
21 #include "ui/views/border.h" 21 #include "ui/views/border.h"
22 #include "ui/views/controls/button/label_button_border.h" 22 #include "ui/views/controls/button/label_button_border.h"
23 #include "ui/views/controls/menu/menu_delegate.h" 23 #include "ui/views/controls/menu/menu_delegate.h"
24 #include "ui/views/controls/menu/menu_item_view.h" 24 #include "ui/views/controls/menu/menu_item_view.h"
25 #include "ui/views/controls/menu/menu_runner.h" 25 #include "ui/views/controls/menu/menu_runner.h"
26 #include "ui/views/metrics.h" 26 #include "ui/views/metrics.h"
27 27
28 namespace { 28 namespace {
29 29
30 // In the browser actions container's chevron menu, a menu item view's icon 30 // In the browser actions container's chevron menu, a menu item view's icon
31 // comes from BrowserActionView::GetIconWithBadge() when the menu item view is 31 // comes from BrowserActionView::GetIconWithBadge() when the menu item view is
32 // created. But, the browser action's icon may not be loaded in time because it 32 // created. But, the browser action's icon may not be loaded in time because it
33 // is read from file system in another thread. 33 // is read from file system in another thread.
34 // The IconUpdater will update the menu item view's icon when the browser 34 // The IconUpdater will update the menu item view's icon when the browser
35 // action's icon has been updated. 35 // action's icon has been updated.
36 class IconUpdater : public BrowserActionView::IconObserver { 36 class IconUpdater : public ExtensionActionIconFactory::Observer {
37 public: 37 public:
38 IconUpdater(views::MenuItemView* menu_item_view, BrowserActionView* view) 38 IconUpdater(views::MenuItemView* menu_item_view,
39 ExtensionActionViewController* view_controller)
39 : menu_item_view_(menu_item_view), 40 : menu_item_view_(menu_item_view),
40 view_(view) { 41 view_controller_(view_controller) {
41 DCHECK(menu_item_view); 42 DCHECK(menu_item_view);
42 DCHECK(view); 43 DCHECK(view_controller);
43 view->set_icon_observer(this); 44 view_controller->set_icon_observer(this);
44 } 45 }
45 virtual ~IconUpdater() { 46 virtual ~IconUpdater() {
46 view_->set_icon_observer(NULL); 47 view_controller_->set_icon_observer(NULL);
47 } 48 }
48 49
49 // BrowserActionView::IconObserver: 50 // BrowserActionView::IconObserver:
50 virtual void OnIconUpdated(const gfx::ImageSkia& icon) override { 51 virtual void OnIconUpdated() override {
51 menu_item_view_->SetIcon(icon); 52 menu_item_view_->SetIcon(view_controller_->GetIconWithBadge());
52 } 53 }
53 54
54 private: 55 private:
55 // The menu item view whose icon might be updated. 56 // The menu item view whose icon might be updated.
56 views::MenuItemView* menu_item_view_; 57 views::MenuItemView* menu_item_view_;
57 58
58 // The view to be observed. When its icon changes, update the corresponding 59 // The view controller to be observed. When its icon changes, update the
59 // menu item view's icon. 60 // corresponding menu item view's icon.
60 BrowserActionView* view_; 61 ExtensionActionViewController* view_controller_;
61 62
62 DISALLOW_COPY_AND_ASSIGN(IconUpdater); 63 DISALLOW_COPY_AND_ASSIGN(IconUpdater);
63 }; 64 };
64 65
65 } // namespace 66 } // namespace
66 67
67 // This class handles the overflow menu for browser actions. 68 // This class handles the overflow menu for browser actions.
68 class ChevronMenuButton::MenuController : public views::MenuDelegate { 69 class ChevronMenuButton::MenuController : public views::MenuDelegate {
69 public: 70 public:
70 MenuController(ChevronMenuButton* owner, 71 MenuController(ChevronMenuButton* owner,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 menu_ = new views::MenuItemView(this); 153 menu_ = new views::MenuItemView(this);
153 menu_runner_.reset(new views::MenuRunner( 154 menu_runner_.reset(new views::MenuRunner(
154 menu_, for_drop_ ? views::MenuRunner::FOR_DROP : 0)); 155 menu_, for_drop_ ? views::MenuRunner::FOR_DROP : 0));
155 menu_->set_has_icons(true); 156 menu_->set_has_icons(true);
156 157
157 size_t command_id = 1; // Menu id 0 is reserved, start with 1. 158 size_t command_id = 1; // Menu id 0 is reserved, start with 1.
158 for (size_t i = start_index_; 159 for (size_t i = start_index_;
159 i < browser_actions_container_->num_browser_actions(); ++i) { 160 i < browser_actions_container_->num_browser_actions(); ++i) {
160 BrowserActionView* view = 161 BrowserActionView* view =
161 browser_actions_container_->GetBrowserActionViewAt(i); 162 browser_actions_container_->GetBrowserActionViewAt(i);
163 ExtensionActionViewController* view_controller =
164 static_cast<ExtensionActionViewController*>(view->view_controller());
162 views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon( 165 views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon(
163 command_id, 166 command_id,
164 base::UTF8ToUTF16(view->extension()->name()), 167 base::UTF8ToUTF16(view_controller->extension()->name()),
165 view->GetIconWithBadge()); 168 view_controller->GetIconWithBadge());
166 169
167 // Set the tooltip for this item. 170 // Set the tooltip for this item.
168 base::string16 tooltip = base::UTF8ToUTF16( 171 menu_->SetTooltip(
169 view->extension_action()->GetTitle( 172 view_controller->GetTooltip(view->GetCurrentWebContents()),
170 view->view_controller()->GetCurrentTabId())); 173 command_id);
171 menu_->SetTooltip(tooltip, command_id);
172 174
173 icon_updaters_.push_back(new IconUpdater(menu_item, view)); 175 icon_updaters_.push_back(new IconUpdater(menu_item, view_controller));
174 176
175 ++command_id; 177 ++command_id;
176 } 178 }
177 } 179 }
178 180
179 ChevronMenuButton::MenuController::~MenuController() { 181 ChevronMenuButton::MenuController::~MenuController() {
180 } 182 }
181 183
182 void ChevronMenuButton::MenuController::RunMenu(views::Widget* window) { 184 void ChevronMenuButton::MenuController::RunMenu(views::Widget* window) {
183 gfx::Rect bounds = owner_->bounds(); 185 gfx::Rect bounds = owner_->bounds();
(...skipping 20 matching lines...) Expand all
204 } 206 }
205 } 207 }
206 208
207 void ChevronMenuButton::MenuController::CloseMenu() { 209 void ChevronMenuButton::MenuController::CloseMenu() {
208 menu_->Cancel(); 210 menu_->Cancel();
209 } 211 }
210 212
211 bool ChevronMenuButton::MenuController::IsCommandEnabled(int id) const { 213 bool ChevronMenuButton::MenuController::IsCommandEnabled(int id) const {
212 BrowserActionView* view = 214 BrowserActionView* view =
213 browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1); 215 browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1);
214 return view->IsEnabled(view->view_controller()->GetCurrentTabId()); 216 return view->view_controller()->IsEnabled(view->GetCurrentWebContents());
215 } 217 }
216 218
217 void ChevronMenuButton::MenuController::ExecuteCommand(int id) { 219 void ChevronMenuButton::MenuController::ExecuteCommand(int id) {
218 browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1)-> 220 browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1)->
219 view_controller()->ExecuteActionByUser(); 221 view_controller()->ExecuteAction(true);
220 } 222 }
221 223
222 bool ChevronMenuButton::MenuController::ShowContextMenu( 224 bool ChevronMenuButton::MenuController::ShowContextMenu(
223 views::MenuItemView* source, 225 views::MenuItemView* source,
224 int id, 226 int id,
225 const gfx::Point& p, 227 const gfx::Point& p,
226 ui::MenuSourceType source_type) { 228 ui::MenuSourceType source_type) {
227 BrowserActionView* view = browser_actions_container_->GetBrowserActionViewAt( 229 BrowserActionView* view = browser_actions_container_->GetBrowserActionViewAt(
228 start_index_ + id - 1); 230 start_index_ + id - 1);
229 if (!view->extension()->ShowConfigureContextMenus()) 231 ExtensionActionViewController* view_controller =
232 static_cast<ExtensionActionViewController*>(view->view_controller());
233 if (!view_controller->extension()->ShowConfigureContextMenus())
230 return false; 234 return false;
231 235
232 scoped_refptr<ExtensionContextMenuModel> context_menu_contents = 236 scoped_refptr<ExtensionContextMenuModel> context_menu_contents =
233 new ExtensionContextMenuModel(view->extension(), 237 new ExtensionContextMenuModel(view_controller->extension(),
234 view->view_controller()->browser(), 238 view->browser(),
235 view->view_controller()); 239 view_controller);
236 views::MenuRunner context_menu_runner(context_menu_contents.get(), 240 views::MenuRunner context_menu_runner(context_menu_contents.get(),
237 views::MenuRunner::HAS_MNEMONICS | 241 views::MenuRunner::HAS_MNEMONICS |
238 views::MenuRunner::IS_NESTED | 242 views::MenuRunner::IS_NESTED |
239 views::MenuRunner::CONTEXT_MENU); 243 views::MenuRunner::CONTEXT_MENU);
240 244
241 // We can ignore the result as we delete ourself. 245 // We can ignore the result as we delete ourself.
242 // This blocks until the user chooses something or dismisses the menu. 246 // This blocks until the user chooses something or dismisses the menu.
243 if (context_menu_runner.RunMenuAt(owner_->GetWidget(), 247 if (context_menu_runner.RunMenuAt(owner_->GetWidget(),
244 NULL, 248 NULL,
245 gfx::Rect(p, gfx::Size()), 249 gfx::Rect(p, gfx::Size()),
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 size_t drop_index = IndexForId(menu->GetCommand()); 313 size_t drop_index = IndexForId(menu->GetCommand());
310 314
311 // When not dragging within the overflow menu (dragging an icon into the menu) 315 // When not dragging within the overflow menu (dragging an icon into the menu)
312 // subtract one to get the right index. 316 // subtract one to get the right index.
313 if (position == DROP_BEFORE && 317 if (position == DROP_BEFORE &&
314 drop_data.index() < browser_actions_container_->VisibleBrowserActions()) 318 drop_data.index() < browser_actions_container_->VisibleBrowserActions())
315 --drop_index; 319 --drop_index;
316 320
317 Profile* profile = browser_actions_container_->profile(); 321 Profile* profile = browser_actions_container_->profile();
318 // Move the extension in the model. 322 // Move the extension in the model.
319 const extensions::Extension* extension =
320 extensions::ExtensionRegistry::Get(profile)->
321 enabled_extensions().GetByID(drop_data.id());
322 extensions::ExtensionToolbarModel* toolbar_model = 323 extensions::ExtensionToolbarModel* toolbar_model =
323 extensions::ExtensionToolbarModel::Get(profile); 324 extensions::ExtensionToolbarModel::Get(profile);
324 toolbar_model->MoveExtensionIcon(extension, drop_index); 325 toolbar_model->MoveExtensionIcon(drop_data.id(), drop_index);
325 326
326 // If the extension was moved to the overflow menu from the main bar, notify 327 // If the extension was moved to the overflow menu from the main bar, notify
327 // the owner. 328 // the owner.
328 if (drop_data.index() < browser_actions_container_->VisibleBrowserActions()) 329 if (drop_data.index() < browser_actions_container_->VisibleBrowserActions())
329 browser_actions_container_->NotifyActionMovedToOverflow(); 330 browser_actions_container_->NotifyActionMovedToOverflow();
330 331
331 if (for_drop_) 332 if (for_drop_)
332 owner_->MenuDone(); 333 owner_->MenuDone();
333 return ui::DragDropTypes::DRAG_MOVE; 334 return ui::DragDropTypes::DRAG_MOVE;
334 } 335 }
335 336
336 bool ChevronMenuButton::MenuController::CanDrag(views::MenuItemView* menu) { 337 bool ChevronMenuButton::MenuController::CanDrag(views::MenuItemView* menu) {
337 return true; 338 return true;
338 } 339 }
339 340
340 void ChevronMenuButton::MenuController::WriteDragData( 341 void ChevronMenuButton::MenuController::WriteDragData(
341 views::MenuItemView* sender, OSExchangeData* data) { 342 views::MenuItemView* sender, OSExchangeData* data) {
342 size_t drag_index = IndexForId(sender->GetCommand()); 343 size_t drag_index = IndexForId(sender->GetCommand());
343 const extensions::Extension* extension = 344 BrowserActionDragData drag_data(
344 browser_actions_container_->GetBrowserActionViewAt(drag_index)-> 345 browser_actions_container_->GetIdAt(drag_index), drag_index);
345 extension();
346 BrowserActionDragData drag_data(extension->id(), drag_index);
347 drag_data.Write(browser_actions_container_->profile(), data); 346 drag_data.Write(browser_actions_container_->profile(), data);
348 } 347 }
349 348
350 int ChevronMenuButton::MenuController::GetDragOperations( 349 int ChevronMenuButton::MenuController::GetDragOperations(
351 views::MenuItemView* sender) { 350 views::MenuItemView* sender) {
352 return ui::DragDropTypes::DRAG_MOVE; 351 return ui::DragDropTypes::DRAG_MOVE;
353 } 352 }
354 353
355 size_t ChevronMenuButton::MenuController::IndexForId(int id) const { 354 size_t ChevronMenuButton::MenuController::IndexForId(int id) const {
356 // The index of the view being dragged (GetCommand gives a 1-based index into 355 // The index of the view being dragged (GetCommand gives a 1-based index into
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 void ChevronMenuButton::ShowOverflowMenu(bool for_drop) { 430 void ChevronMenuButton::ShowOverflowMenu(bool for_drop) {
432 DCHECK(!menu_controller_); 431 DCHECK(!menu_controller_);
433 menu_controller_.reset(new MenuController( 432 menu_controller_.reset(new MenuController(
434 this, browser_actions_container_, for_drop)); 433 this, browser_actions_container_, for_drop));
435 menu_controller_->RunMenu(GetWidget()); 434 menu_controller_->RunMenu(GetWidget());
436 } 435 }
437 436
438 void ChevronMenuButton::MenuDone() { 437 void ChevronMenuButton::MenuDone() {
439 menu_controller_.reset(); 438 menu_controller_.reset();
440 } 439 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698