OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/extensions/browser_action_overflow_menu_contro
ller.h" | 5 #include "chrome/browser/ui/views/extensions/browser_action_overflow_menu_contro
ller.h" |
6 | 6 |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "chrome/browser/extensions/extension_action.h" | 9 #include "chrome/browser/extensions/extension_action.h" |
10 #include "chrome/browser/extensions/extension_action_manager.h" | 10 #include "chrome/browser/extensions/extension_action_manager.h" |
11 #include "chrome/browser/extensions/extension_context_menu_model.h" | 11 #include "chrome/browser/extensions/extension_context_menu_model.h" |
12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
13 #include "chrome/browser/ui/browser_list.h" | 13 #include "chrome/browser/ui/browser_list.h" |
14 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" | 14 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" |
15 #include "chrome/browser/ui/views/toolbar/browser_action_view.h" | 15 #include "chrome/browser/ui/views/toolbar/browser_action_view.h" |
16 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" | 16 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" |
17 #include "extensions/common/extension.h" | 17 #include "extensions/common/extension.h" |
18 #include "ui/gfx/canvas.h" | 18 #include "ui/gfx/canvas.h" |
19 #include "ui/views/controls/menu/menu_item_view.h" | 19 #include "ui/views/controls/menu/menu_item_view.h" |
20 #include "ui/views/controls/menu/menu_runner.h" | 20 #include "ui/views/controls/menu/menu_runner.h" |
21 #include "ui/views/controls/menu/submenu_view.h" | 21 #include "ui/views/controls/menu/submenu_view.h" |
22 #include "ui/views/widget/widget.h" | 22 #include "ui/views/widget/widget.h" |
23 | 23 |
24 // In the browser actions container's chevron menu, a menu item view's icon | 24 // In the browser actions container's chevron menu, a menu item view's icon |
25 // comes from BrowserActionView::GetIconWithBadge() (which comes from the | 25 // comes from BrowserActionView::GetIconWithBadge() when the menu item view is |
26 // browser action button's icon) when the menu item view is created. But, the | 26 // created. But, the browser action's icon may not be loaded in time because it |
27 // browser action button's icon may not be loaded in time because it is read | 27 // is read from file system in another thread. |
28 // from file system in another thread. | |
29 // The IconUpdater will update the menu item view's icon when the browser | 28 // The IconUpdater will update the menu item view's icon when the browser |
30 // action button's icon has been updated. | 29 // action's icon has been updated. |
31 class IconUpdater : public BrowserActionButton::IconObserver { | 30 class IconUpdater : public BrowserActionView::IconObserver { |
32 public: | 31 public: |
33 IconUpdater(views::MenuItemView* menu_item_view, BrowserActionButton* button) | 32 IconUpdater(views::MenuItemView* menu_item_view, BrowserActionView* view) |
34 : menu_item_view_(menu_item_view), | 33 : menu_item_view_(menu_item_view), |
35 button_(button) { | 34 view_(view) { |
36 DCHECK(menu_item_view); | 35 DCHECK(menu_item_view); |
37 DCHECK(button); | 36 DCHECK(view); |
38 button->set_icon_observer(this); | 37 view->set_icon_observer(this); |
39 } | 38 } |
40 virtual ~IconUpdater() { | 39 virtual ~IconUpdater() { |
41 button_->set_icon_observer(NULL); | 40 view_->set_icon_observer(NULL); |
42 } | 41 } |
43 | 42 |
44 // Overridden from BrowserActionButton::IconObserver: | 43 // Overridden from BrowserActionView::IconObserver: |
45 virtual void OnIconUpdated(const gfx::ImageSkia& icon) OVERRIDE { | 44 virtual void OnIconUpdated(const gfx::ImageSkia& icon) OVERRIDE { |
46 menu_item_view_->SetIcon(icon); | 45 menu_item_view_->SetIcon(icon); |
47 } | 46 } |
48 | 47 |
49 private: | 48 private: |
50 // The menu item view whose icon might be updated. | 49 // The menu item view whose icon might be updated. |
51 views::MenuItemView* menu_item_view_; | 50 views::MenuItemView* menu_item_view_; |
52 | 51 |
53 // The button to be observed. When its icon changes, update the corresponding | 52 // The view to be observed. When its icon changes, update the corresponding |
54 // menu item view's icon. | 53 // menu item view's icon. |
55 BrowserActionButton* button_; | 54 BrowserActionView* view_; |
56 | 55 |
57 DISALLOW_COPY_AND_ASSIGN(IconUpdater); | 56 DISALLOW_COPY_AND_ASSIGN(IconUpdater); |
58 }; | 57 }; |
59 | 58 |
60 BrowserActionOverflowMenuController::BrowserActionOverflowMenuController( | 59 BrowserActionOverflowMenuController::BrowserActionOverflowMenuController( |
61 BrowserActionsContainer* owner, | 60 BrowserActionsContainer* owner, |
62 Browser* browser, | 61 Browser* browser, |
63 views::MenuButton* menu_button, | 62 views::MenuButton* menu_button, |
64 const std::vector<BrowserActionView*>& views, | 63 const std::vector<BrowserActionView*>& views, |
65 int start_index, | 64 int start_index, |
66 bool for_drop) | 65 bool for_drop) |
67 : owner_(owner), | 66 : owner_(owner), |
68 browser_(browser), | 67 browser_(browser), |
69 observer_(NULL), | 68 observer_(NULL), |
70 menu_button_(menu_button), | 69 menu_button_(menu_button), |
71 menu_(NULL), | 70 menu_(NULL), |
72 views_(&views), | 71 views_(&views), |
73 start_index_(start_index), | 72 start_index_(start_index), |
74 for_drop_(for_drop) { | 73 for_drop_(for_drop) { |
75 menu_ = new views::MenuItemView(this); | 74 menu_ = new views::MenuItemView(this); |
76 menu_runner_.reset(new views::MenuRunner( | 75 menu_runner_.reset(new views::MenuRunner( |
77 menu_, for_drop_ ? views::MenuRunner::FOR_DROP : 0)); | 76 menu_, for_drop_ ? views::MenuRunner::FOR_DROP : 0)); |
78 menu_->set_has_icons(true); | 77 menu_->set_has_icons(true); |
79 | 78 |
80 size_t command_id = 1; // Menu id 0 is reserved, start with 1. | 79 size_t command_id = 1; // Menu id 0 is reserved, start with 1. |
81 for (size_t i = start_index; i < views_->size(); ++i) { | 80 for (size_t i = start_index; i < views_->size(); ++i) { |
82 BrowserActionView* view = (*views_)[i]; | 81 BrowserActionView* view = (*views_)[i]; |
83 views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon( | 82 views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon( |
84 command_id, | 83 command_id, |
85 base::UTF8ToUTF16(view->button()->extension()->name()), | 84 base::UTF8ToUTF16(view->extension()->name()), |
86 view->GetIconWithBadge()); | 85 view->GetIconWithBadge()); |
87 | 86 |
88 // Set the tooltip for this item. | 87 // Set the tooltip for this item. |
89 base::string16 tooltip = base::UTF8ToUTF16( | 88 base::string16 tooltip = base::UTF8ToUTF16( |
90 view->button()->extension_action()->GetTitle( | 89 view->extension_action()->GetTitle( |
91 view->button()->view_controller()->GetCurrentTabId())); | 90 view->view_controller()->GetCurrentTabId())); |
92 menu_->SetTooltip(tooltip, command_id); | 91 menu_->SetTooltip(tooltip, command_id); |
93 | 92 |
94 icon_updaters_.push_back(new IconUpdater(menu_item, view->button())); | 93 icon_updaters_.push_back(new IconUpdater(menu_item, view)); |
95 | 94 |
96 ++command_id; | 95 ++command_id; |
97 } | 96 } |
98 } | 97 } |
99 | 98 |
100 BrowserActionOverflowMenuController::~BrowserActionOverflowMenuController() { | 99 BrowserActionOverflowMenuController::~BrowserActionOverflowMenuController() { |
101 if (observer_) | 100 if (observer_) |
102 observer_->NotifyMenuDeleted(this); | 101 observer_->NotifyMenuDeleted(this); |
103 } | 102 } |
104 | 103 |
(...skipping 18 matching lines...) Expand all Loading... |
123 | 122 |
124 void BrowserActionOverflowMenuController::CancelMenu() { | 123 void BrowserActionOverflowMenuController::CancelMenu() { |
125 menu_->Cancel(); | 124 menu_->Cancel(); |
126 } | 125 } |
127 | 126 |
128 void BrowserActionOverflowMenuController::NotifyBrowserActionViewsDeleting() { | 127 void BrowserActionOverflowMenuController::NotifyBrowserActionViewsDeleting() { |
129 icon_updaters_.clear(); | 128 icon_updaters_.clear(); |
130 } | 129 } |
131 | 130 |
132 bool BrowserActionOverflowMenuController::IsCommandEnabled(int id) const { | 131 bool BrowserActionOverflowMenuController::IsCommandEnabled(int id) const { |
133 BrowserActionButton* button = (*views_)[start_index_ + id - 1]->button(); | 132 BrowserActionView* view = (*views_)[start_index_ + id - 1]; |
134 return button->IsEnabled(button->view_controller()->GetCurrentTabId()); | 133 return view->IsEnabled(view->view_controller()->GetCurrentTabId()); |
135 } | 134 } |
136 | 135 |
137 void BrowserActionOverflowMenuController::ExecuteCommand(int id) { | 136 void BrowserActionOverflowMenuController::ExecuteCommand(int id) { |
138 BrowserActionView* view = (*views_)[start_index_ + id - 1]; | 137 (*views_)[start_index_ + id - 1]->view_controller()->ExecuteActionByUser(); |
139 view->button()->view_controller()->ExecuteActionByUser(); | |
140 } | 138 } |
141 | 139 |
142 bool BrowserActionOverflowMenuController::ShowContextMenu( | 140 bool BrowserActionOverflowMenuController::ShowContextMenu( |
143 views::MenuItemView* source, | 141 views::MenuItemView* source, |
144 int id, | 142 int id, |
145 const gfx::Point& p, | 143 const gfx::Point& p, |
146 ui::MenuSourceType source_type) { | 144 ui::MenuSourceType source_type) { |
147 BrowserActionButton* button = (*views_)[start_index_ + id - 1]->button(); | 145 BrowserActionView* view = (*views_)[start_index_ + id - 1]; |
148 if (!button->extension()->ShowConfigureContextMenus()) | 146 if (!view->extension()->ShowConfigureContextMenus()) |
149 return false; | 147 return false; |
150 | 148 |
151 scoped_refptr<ExtensionContextMenuModel> context_menu_contents = | 149 scoped_refptr<ExtensionContextMenuModel> context_menu_contents = |
152 new ExtensionContextMenuModel( | 150 new ExtensionContextMenuModel( |
153 button->extension(), browser_, button->view_controller()); | 151 view->extension(), browser_, view->view_controller()); |
154 views::MenuRunner context_menu_runner(context_menu_contents.get(), | 152 views::MenuRunner context_menu_runner(context_menu_contents.get(), |
155 views::MenuRunner::HAS_MNEMONICS | | 153 views::MenuRunner::HAS_MNEMONICS | |
156 views::MenuRunner::IS_NESTED | | 154 views::MenuRunner::IS_NESTED | |
157 views::MenuRunner::CONTEXT_MENU); | 155 views::MenuRunner::CONTEXT_MENU); |
158 | 156 |
159 // We can ignore the result as we delete ourself. | 157 // We can ignore the result as we delete ourself. |
160 // This blocks until the user choses something or dismisses the menu. | 158 // This blocks until the user choses something or dismisses the menu. |
161 ignore_result(context_menu_runner.RunMenuAt(menu_button_->GetWidget(), | 159 ignore_result(context_menu_runner.RunMenuAt(menu_button_->GetWidget(), |
162 NULL, | 160 NULL, |
163 gfx::Rect(p, gfx::Size()), | 161 gfx::Rect(p, gfx::Size()), |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 } | 236 } |
239 | 237 |
240 bool BrowserActionOverflowMenuController::CanDrag(views::MenuItemView* menu) { | 238 bool BrowserActionOverflowMenuController::CanDrag(views::MenuItemView* menu) { |
241 return true; | 239 return true; |
242 } | 240 } |
243 | 241 |
244 void BrowserActionOverflowMenuController::WriteDragData( | 242 void BrowserActionOverflowMenuController::WriteDragData( |
245 views::MenuItemView* sender, OSExchangeData* data) { | 243 views::MenuItemView* sender, OSExchangeData* data) { |
246 size_t drag_index; | 244 size_t drag_index; |
247 BrowserActionView* view = ViewForId(sender->GetCommand(), &drag_index); | 245 BrowserActionView* view = ViewForId(sender->GetCommand(), &drag_index); |
248 std::string id = view->button()->extension()->id(); | 246 BrowserActionDragData drag_data(view->extension()->id(), drag_index); |
249 | |
250 BrowserActionDragData drag_data(id, drag_index); | |
251 drag_data.Write(owner_->profile(), data); | 247 drag_data.Write(owner_->profile(), data); |
252 } | 248 } |
253 | 249 |
254 int BrowserActionOverflowMenuController::GetDragOperations( | 250 int BrowserActionOverflowMenuController::GetDragOperations( |
255 views::MenuItemView* sender) { | 251 views::MenuItemView* sender) { |
256 return ui::DragDropTypes::DRAG_MOVE; | 252 return ui::DragDropTypes::DRAG_MOVE; |
257 } | 253 } |
258 | 254 |
259 BrowserActionView* BrowserActionOverflowMenuController::ViewForId( | 255 BrowserActionView* BrowserActionOverflowMenuController::ViewForId( |
260 int id, size_t* index) { | 256 int id, size_t* index) { |
261 // The index of the view being dragged (GetCommand gives a 1-based index into | 257 // The index of the view being dragged (GetCommand gives a 1-based index into |
262 // the overflow menu). | 258 // the overflow menu). |
263 size_t view_index = owner_->VisibleBrowserActions() + id - 1; | 259 size_t view_index = owner_->VisibleBrowserActions() + id - 1; |
264 if (index) | 260 if (index) |
265 *index = view_index; | 261 *index = view_index; |
266 return owner_->GetBrowserActionViewAt(view_index); | 262 return owner_->GetBrowserActionViewAt(view_index); |
267 } | 263 } |
OLD | NEW |