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

Side by Side Diff: chrome/browser/ui/views/extensions/browser_action_overflow_menu_controller.cc

Issue 597783002: Make the chevron menu button responsible for legacy overflow menu logic (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Original filenames Created 6 years, 3 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 (c) 2012 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/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/memory/scoped_vector.h"
7 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
8 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_action.h" 10 #include "chrome/browser/extensions/extension_action.h"
10 #include "chrome/browser/extensions/extension_context_menu_model.h" 11 #include "chrome/browser/extensions/extension_context_menu_model.h"
11 #include "chrome/browser/extensions/extension_toolbar_model.h" 12 #include "chrome/browser/extensions/extension_toolbar_model.h"
12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h" 14 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_list.h"
15 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" 15 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
16 #include "chrome/browser/ui/views/toolbar/browser_action_view.h" 16 #include "chrome/browser/ui/views/toolbar/browser_action_view.h"
17 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" 17 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
18 #include "extensions/browser/extension_registry.h" 18 #include "extensions/browser/extension_registry.h"
19 #include "extensions/common/extension.h" 19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_set.h" 20 #include "extensions/common/extension_set.h"
21 #include "ui/views/border.h"
22 #include "ui/views/controls/button/label_button_border.h"
23 #include "ui/views/controls/menu/menu_delegate.h"
21 #include "ui/views/controls/menu/menu_item_view.h" 24 #include "ui/views/controls/menu/menu_item_view.h"
22 #include "ui/views/controls/menu/menu_runner.h" 25 #include "ui/views/controls/menu/menu_runner.h"
26 #include "ui/views/metrics.h"
27
28 namespace {
23 29
24 // 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
25 // comes from BrowserActionView::GetIconWithBadge() when the menu item view is 31 // comes from BrowserActionView::GetIconWithBadge() when the menu item view is
26 // 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
27 // is read from file system in another thread. 33 // is read from file system in another thread.
28 // 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
29 // action's icon has been updated. 35 // action's icon has been updated.
30 class IconUpdater : public BrowserActionView::IconObserver { 36 class IconUpdater : public BrowserActionView::IconObserver {
31 public: 37 public:
32 IconUpdater(views::MenuItemView* menu_item_view, BrowserActionView* view) 38 IconUpdater(views::MenuItemView* menu_item_view, BrowserActionView* view)
33 : menu_item_view_(menu_item_view), 39 : menu_item_view_(menu_item_view),
34 view_(view) { 40 view_(view) {
35 DCHECK(menu_item_view); 41 DCHECK(menu_item_view);
36 DCHECK(view); 42 DCHECK(view);
37 view->set_icon_observer(this); 43 view->set_icon_observer(this);
38 } 44 }
39 virtual ~IconUpdater() { 45 virtual ~IconUpdater() {
40 view_->set_icon_observer(NULL); 46 view_->set_icon_observer(NULL);
41 } 47 }
42 48
43 // Overridden from BrowserActionView::IconObserver: 49 // BrowserActionView::IconObserver:
44 virtual void OnIconUpdated(const gfx::ImageSkia& icon) OVERRIDE { 50 virtual void OnIconUpdated(const gfx::ImageSkia& icon) OVERRIDE {
45 menu_item_view_->SetIcon(icon); 51 menu_item_view_->SetIcon(icon);
46 } 52 }
47 53
48 private: 54 private:
49 // The menu item view whose icon might be updated. 55 // The menu item view whose icon might be updated.
50 views::MenuItemView* menu_item_view_; 56 views::MenuItemView* menu_item_view_;
51 57
52 // The view to be observed. When its icon changes, update the corresponding 58 // The view to be observed. When its icon changes, update the corresponding
53 // menu item view's icon. 59 // menu item view's icon.
54 BrowserActionView* view_; 60 BrowserActionView* view_;
55 61
56 DISALLOW_COPY_AND_ASSIGN(IconUpdater); 62 DISALLOW_COPY_AND_ASSIGN(IconUpdater);
57 }; 63 };
58 64
59 BrowserActionOverflowMenuController::BrowserActionOverflowMenuController( 65 } // namespace
60 BrowserActionsContainer* owner, 66
61 Browser* browser, 67 // This class handles the overflow menu for browser actions (showing the menu,
62 views::MenuButton* menu_button, 68 // drag and drop, etc). This class manages its own lifetime.
63 const std::vector<BrowserActionView*>& views, 69 class ChevronMenuButton::MenuController : public views::MenuDelegate {
64 int start_index, 70 public:
71 MenuController(ChevronMenuButton* owner,
72 BrowserActionsContainer* browser_actions_container,
73 bool for_drop);
74 virtual ~MenuController();
75
76 // Shows the overflow menu.
77 void RunMenu(views::Widget* widget);
78
79 // Closes the overflow menu (and its context menu if open as well).
80 void CloseMenu();
81
82 private:
83 // Overridden from views::MenuDelegate:
Peter Kasting 2014/09/25 01:06:43 Nit: "Overridden from" not necessary
Devlin 2014/09/25 15:56:49 Dang, caught it on line 49 but not here. Removed.
84 virtual bool IsCommandEnabled(int id) const OVERRIDE;
85 virtual void ExecuteCommand(int id) OVERRIDE;
86 virtual bool ShowContextMenu(views::MenuItemView* source,
87 int id,
88 const gfx::Point& p,
89 ui::MenuSourceType source_type) OVERRIDE;
90 virtual void DropMenuClosed(views::MenuItemView* menu) OVERRIDE;
91 // These drag functions offer support for dragging icons into the overflow
92 // menu.
Peter Kasting 2014/09/25 01:06:43 So, MenuButton and MenuDelegate both have these dr
Devlin 2014/09/25 15:56:49 Unfortunately, there really isn't a good way. The
93 virtual bool GetDropFormats(
94 views::MenuItemView* menu,
95 int* formats,
96 std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
97 virtual bool AreDropTypesRequired(views::MenuItemView* menu) OVERRIDE;
98 virtual bool CanDrop(views::MenuItemView* menu,
99 const ui::OSExchangeData& data) OVERRIDE;
100 virtual int GetDropOperation(views::MenuItemView* item,
101 const ui::DropTargetEvent& event,
102 DropPosition* position) OVERRIDE;
103 virtual int OnPerformDrop(views::MenuItemView* menu,
104 DropPosition position,
105 const ui::DropTargetEvent& event) OVERRIDE;
106 // These three drag functions offer support for dragging icons out of the
107 // overflow menu.
108 virtual bool CanDrag(views::MenuItemView* menu) OVERRIDE;
109 virtual void WriteDragData(views::MenuItemView* sender,
110 ui::OSExchangeData* data) OVERRIDE;
111 virtual int GetDragOperations(views::MenuItemView* sender) OVERRIDE;
112
113 // Returns the offset into |views_| for the given |id|.
114 size_t IndexForId(int id) const;
115
116 // The owning ChevronMenuButton.
117 ChevronMenuButton* owner_;
118
119 // A pointer to the browser action container.
120 BrowserActionsContainer* browser_actions_container_;
121
122 // The overflow menu for the menu button. Owned by |menu_runner_|.
123 views::MenuItemView* menu_;
124
125 // Resposible for running the menu.
126 scoped_ptr<views::MenuRunner> menu_runner_;
127
128 // The index into the BrowserActionView vector, indicating where to start
129 // picking browser actions to draw.
130 int start_index_;
131
132 // Whether this controller is being used for drop.
133 bool for_drop_;
134
135 // The vector keeps all icon updaters associated with menu item views in the
136 // controller. The icon updater will update the menu item view's icon when
137 // the browser action view's icon has been updated.
138 ScopedVector<IconUpdater> icon_updaters_;
139
140 DISALLOW_COPY_AND_ASSIGN(MenuController);
141 };
142
143 ChevronMenuButton::MenuController::MenuController(
144 ChevronMenuButton* owner,
145 BrowserActionsContainer* browser_actions_container,
65 bool for_drop) 146 bool for_drop)
66 : owner_(owner), 147 : owner_(owner),
67 browser_(browser), 148 browser_actions_container_(browser_actions_container),
68 observer_(NULL),
69 menu_button_(menu_button),
70 menu_(NULL), 149 menu_(NULL),
71 views_(views), 150 start_index_(
72 start_index_(start_index), 151 browser_actions_container_->VisibleBrowserActionsAfterAnimation()),
73 for_drop_(for_drop) { 152 for_drop_(for_drop) {
74 menu_ = new views::MenuItemView(this); 153 menu_ = new views::MenuItemView(this);
75 menu_runner_.reset(new views::MenuRunner( 154 menu_runner_.reset(new views::MenuRunner(
76 menu_, for_drop_ ? views::MenuRunner::FOR_DROP : 0)); 155 menu_, for_drop_ ? views::MenuRunner::FOR_DROP : 0));
77 menu_->set_has_icons(true); 156 menu_->set_has_icons(true);
78 157
79 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.
80 for (size_t i = start_index; i < views_.size(); ++i) { 159 for (size_t i = start_index_;
81 BrowserActionView* view = views_[i]; 160 i < browser_actions_container_->num_browser_actions(); ++i) {
161 BrowserActionView* view =
162 browser_actions_container_->GetBrowserActionViewAt(i);
82 views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon( 163 views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon(
83 command_id, 164 command_id,
84 base::UTF8ToUTF16(view->extension()->name()), 165 base::UTF8ToUTF16(view->extension()->name()),
85 view->GetIconWithBadge()); 166 view->GetIconWithBadge());
86 167
87 // Set the tooltip for this item. 168 // Set the tooltip for this item.
88 base::string16 tooltip = base::UTF8ToUTF16( 169 base::string16 tooltip = base::UTF8ToUTF16(
89 view->extension_action()->GetTitle( 170 view->extension_action()->GetTitle(
90 view->view_controller()->GetCurrentTabId())); 171 view->view_controller()->GetCurrentTabId()));
91 menu_->SetTooltip(tooltip, command_id); 172 menu_->SetTooltip(tooltip, command_id);
92 173
93 icon_updaters_.push_back(new IconUpdater(menu_item, view)); 174 icon_updaters_.push_back(new IconUpdater(menu_item, view));
94 175
95 ++command_id; 176 ++command_id;
96 } 177 }
97 } 178 }
98 179
99 BrowserActionOverflowMenuController::~BrowserActionOverflowMenuController() { 180 ChevronMenuButton::MenuController::~MenuController() {
100 if (observer_)
101 observer_->NotifyMenuDeleted(this);
102 } 181 }
103 182
104 bool BrowserActionOverflowMenuController::RunMenu(views::Widget* window) { 183 void ChevronMenuButton::MenuController::RunMenu(views::Widget* window) {
105 gfx::Rect bounds = menu_button_->bounds(); 184 gfx::Rect bounds = owner_->bounds();
106 gfx::Point screen_loc; 185 gfx::Point screen_loc;
107 views::View::ConvertPointToScreen(menu_button_, &screen_loc); 186 views::View::ConvertPointToScreen(owner_, &screen_loc);
108 bounds.set_x(screen_loc.x()); 187 bounds.set_x(screen_loc.x());
109 bounds.set_y(screen_loc.y()); 188 bounds.set_y(screen_loc.y());
110 189
111 views::MenuAnchorPosition anchor = views::MENU_ANCHOR_TOPRIGHT; 190 if (menu_runner_->RunMenuAt(window,
112 // As we maintain our own lifetime we can safely ignore the result. 191 owner_,
113 ignore_result(menu_runner_->RunMenuAt( 192 bounds,
114 window, menu_button_, bounds, anchor, ui::MENU_SOURCE_NONE)); 193 views::MENU_ANCHOR_TOPRIGHT,
194 ui::MENU_SOURCE_NONE) ==
195 views::MenuRunner::MENU_DELETED)
196 return;
197
115 if (!for_drop_) { 198 if (!for_drop_) {
116 // Give the context menu (if any) a chance to execute the user-selected 199 // Give the context menu (if any) a chance to execute the user-selected
117 // command. 200 // command.
118 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 201 base::MessageLoop::current()->PostTask(
202 FROM_HERE,
203 base::Bind(&ChevronMenuButton::MenuDone,
204 owner_->weak_factory_.GetWeakPtr()));
119 } 205 }
120 return true;
121 } 206 }
122 207
123 void BrowserActionOverflowMenuController::CancelMenu() { 208 void ChevronMenuButton::MenuController::CloseMenu() {
124 menu_->Cancel(); 209 menu_->Cancel();
125 } 210 }
126 211
127 void BrowserActionOverflowMenuController::NotifyBrowserActionViewsDeleting() { 212 bool ChevronMenuButton::MenuController::IsCommandEnabled(int id) const {
128 icon_updaters_.clear(); 213 BrowserActionView* view =
129 } 214 browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1);
130
131 bool BrowserActionOverflowMenuController::IsCommandEnabled(int id) const {
132 BrowserActionView* view = views_[start_index_ + id - 1];
133 return view->IsEnabled(view->view_controller()->GetCurrentTabId()); 215 return view->IsEnabled(view->view_controller()->GetCurrentTabId());
134 } 216 }
135 217
136 void BrowserActionOverflowMenuController::ExecuteCommand(int id) { 218 void ChevronMenuButton::MenuController::ExecuteCommand(int id) {
137 views_[start_index_ + id - 1]->view_controller()->ExecuteActionByUser(); 219 browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1)->
220 view_controller()->ExecuteActionByUser();
138 } 221 }
139 222
140 bool BrowserActionOverflowMenuController::ShowContextMenu( 223 bool ChevronMenuButton::MenuController::ShowContextMenu(
141 views::MenuItemView* source, 224 views::MenuItemView* source,
142 int id, 225 int id,
143 const gfx::Point& p, 226 const gfx::Point& p,
144 ui::MenuSourceType source_type) { 227 ui::MenuSourceType source_type) {
145 BrowserActionView* view = views_[start_index_ + id - 1]; 228 BrowserActionView* view = browser_actions_container_->GetBrowserActionViewAt(
229 start_index_ + id - 1);
146 if (!view->extension()->ShowConfigureContextMenus()) 230 if (!view->extension()->ShowConfigureContextMenus())
147 return false; 231 return false;
148 232
149 scoped_refptr<ExtensionContextMenuModel> context_menu_contents = 233 scoped_refptr<ExtensionContextMenuModel> context_menu_contents =
150 new ExtensionContextMenuModel( 234 new ExtensionContextMenuModel(view->extension(),
151 view->extension(), browser_, view->view_controller()); 235 view->view_controller()->browser(),
236 view->view_controller());
152 views::MenuRunner context_menu_runner(context_menu_contents.get(), 237 views::MenuRunner context_menu_runner(context_menu_contents.get(),
153 views::MenuRunner::HAS_MNEMONICS | 238 views::MenuRunner::HAS_MNEMONICS |
154 views::MenuRunner::IS_NESTED | 239 views::MenuRunner::IS_NESTED |
155 views::MenuRunner::CONTEXT_MENU); 240 views::MenuRunner::CONTEXT_MENU);
156 241
157 // We can ignore the result as we delete ourself. 242 // We can ignore the result as we delete ourself.
158 // This blocks until the user choses something or dismisses the menu. 243 // This blocks until the user chooses something or dismisses the menu.
159 ignore_result(context_menu_runner.RunMenuAt(menu_button_->GetWidget(), 244 if (context_menu_runner.RunMenuAt(owner_->GetWidget(),
160 NULL, 245 NULL,
161 gfx::Rect(p, gfx::Size()), 246 gfx::Rect(p, gfx::Size()),
162 views::MENU_ANCHOR_TOPLEFT, 247 views::MENU_ANCHOR_TOPLEFT,
163 source_type)); 248 source_type) ==
249 views::MenuRunner::MENU_DELETED)
250 return true;
164 251
165 // The user is done with the context menu, so we can close the underlying 252 // The user is done with the context menu, so we can close the underlying
166 // menu. 253 // menu.
167 menu_->Cancel(); 254 menu_->Cancel();
168 255
169 return true; 256 return true;
170 } 257 }
171 258
172 void BrowserActionOverflowMenuController::DropMenuClosed( 259 void ChevronMenuButton::MenuController::DropMenuClosed(
173 views::MenuItemView* menu) { 260 views::MenuItemView* menu) {
174 delete this; 261 owner_->MenuDone();
175 } 262 }
176 263
177 bool BrowserActionOverflowMenuController::GetDropFormats( 264 bool ChevronMenuButton::MenuController::GetDropFormats(
178 views::MenuItemView* menu, 265 views::MenuItemView* menu,
179 int* formats, 266 int* formats,
180 std::set<OSExchangeData::CustomFormat>* custom_formats) { 267 std::set<OSExchangeData::CustomFormat>* custom_formats) {
181 return BrowserActionDragData::GetDropFormats(custom_formats); 268 return BrowserActionDragData::GetDropFormats(custom_formats);
182 } 269 }
183 270
184 bool BrowserActionOverflowMenuController::AreDropTypesRequired( 271 bool ChevronMenuButton::MenuController::AreDropTypesRequired(
185 views::MenuItemView* menu) { 272 views::MenuItemView* menu) {
186 return BrowserActionDragData::AreDropTypesRequired(); 273 return BrowserActionDragData::AreDropTypesRequired();
187 } 274 }
188 275
189 bool BrowserActionOverflowMenuController::CanDrop( 276 bool ChevronMenuButton::MenuController::CanDrop(
190 views::MenuItemView* menu, const OSExchangeData& data) { 277 views::MenuItemView* menu, const OSExchangeData& data) {
191 return BrowserActionDragData::CanDrop(data, owner_->profile()); 278 return BrowserActionDragData::CanDrop(data,
279 browser_actions_container_->profile());
192 } 280 }
193 281
194 int BrowserActionOverflowMenuController::GetDropOperation( 282 int ChevronMenuButton::MenuController::GetDropOperation(
195 views::MenuItemView* item, 283 views::MenuItemView* item,
196 const ui::DropTargetEvent& event, 284 const ui::DropTargetEvent& event,
197 DropPosition* position) { 285 DropPosition* position) {
198 // Don't allow dropping from the BrowserActionContainer into slot 0 of the 286 // Don't allow dropping from the BrowserActionContainer into slot 0 of the
199 // overflow menu since once the move has taken place the item you are dragging 287 // overflow menu since once the move has taken place the item you are dragging
200 // falls right out of the menu again once the user releases the button 288 // falls right out of the menu again once the user releases the button
201 // (because we don't shrink the BrowserActionContainer when you do this). 289 // (because we don't shrink the BrowserActionContainer when you do this).
202 if ((item->GetCommand() == 0) && (*position == DROP_BEFORE)) { 290 if ((item->GetCommand() == 0) && (*position == DROP_BEFORE)) {
203 BrowserActionDragData drop_data; 291 BrowserActionDragData drop_data;
204 if (!drop_data.Read(event.data())) 292 if (!drop_data.Read(event.data()))
205 return ui::DragDropTypes::DRAG_NONE; 293 return ui::DragDropTypes::DRAG_NONE;
206 294
207 if (drop_data.index() < owner_->VisibleBrowserActions()) 295 if (drop_data.index() < browser_actions_container_->VisibleBrowserActions())
208 return ui::DragDropTypes::DRAG_NONE; 296 return ui::DragDropTypes::DRAG_NONE;
209 } 297 }
210 298
211 return ui::DragDropTypes::DRAG_MOVE; 299 return ui::DragDropTypes::DRAG_MOVE;
212 } 300 }
213 301
214 int BrowserActionOverflowMenuController::OnPerformDrop( 302 int ChevronMenuButton::MenuController::OnPerformDrop(
215 views::MenuItemView* menu, 303 views::MenuItemView* menu,
216 DropPosition position, 304 DropPosition position,
217 const ui::DropTargetEvent& event) { 305 const ui::DropTargetEvent& event) {
218 BrowserActionDragData drop_data; 306 BrowserActionDragData drop_data;
219 if (!drop_data.Read(event.data())) 307 if (!drop_data.Read(event.data()))
220 return ui::DragDropTypes::DRAG_NONE; 308 return ui::DragDropTypes::DRAG_NONE;
221 309
222 size_t drop_index = IndexForId(menu->GetCommand()); 310 size_t drop_index = IndexForId(menu->GetCommand());
223 311
224 // When not dragging within the overflow menu (dragging an icon into the menu) 312 // When not dragging within the overflow menu (dragging an icon into the menu)
225 // subtract one to get the right index. 313 // subtract one to get the right index.
226 if (position == DROP_BEFORE && 314 if (position == DROP_BEFORE &&
227 drop_data.index() < owner_->VisibleBrowserActions()) 315 drop_data.index() < browser_actions_container_->VisibleBrowserActions())
228 --drop_index; 316 --drop_index;
229 317
318 Profile* profile = browser_actions_container_->profile();
230 // Move the extension in the model. 319 // Move the extension in the model.
231 const extensions::Extension* extension = 320 const extensions::Extension* extension =
232 extensions::ExtensionRegistry::Get(browser_->profile())-> 321 extensions::ExtensionRegistry::Get(profile)->
233 enabled_extensions().GetByID(drop_data.id()); 322 enabled_extensions().GetByID(drop_data.id());
234 extensions::ExtensionToolbarModel* toolbar_model = 323 extensions::ExtensionToolbarModel* toolbar_model =
235 extensions::ExtensionToolbarModel::Get(browser_->profile()); 324 extensions::ExtensionToolbarModel::Get(profile);
236 if (browser_->profile()->IsOffTheRecord()) 325 if (profile->IsOffTheRecord())
237 drop_index = toolbar_model->IncognitoIndexToOriginal(drop_index); 326 drop_index = toolbar_model->IncognitoIndexToOriginal(drop_index);
238 toolbar_model->MoveExtensionIcon(extension, drop_index); 327 toolbar_model->MoveExtensionIcon(extension, drop_index);
239 328
240 // If the extension was moved to the overflow menu from the main bar, notify 329 // If the extension was moved to the overflow menu from the main bar, notify
241 // the owner. 330 // the owner.
242 if (drop_data.index() < owner_->VisibleBrowserActions()) 331 if (drop_data.index() < browser_actions_container_->VisibleBrowserActions())
243 owner_->NotifyActionMovedToOverflow(); 332 browser_actions_container_->NotifyActionMovedToOverflow();
244 333
245 if (for_drop_) 334 if (for_drop_)
246 delete this; 335 owner_->MenuDone();
247 return ui::DragDropTypes::DRAG_MOVE; 336 return ui::DragDropTypes::DRAG_MOVE;
248 } 337 }
249 338
250 bool BrowserActionOverflowMenuController::CanDrag(views::MenuItemView* menu) { 339 bool ChevronMenuButton::MenuController::CanDrag(views::MenuItemView* menu) {
251 return true; 340 return true;
252 } 341 }
253 342
254 void BrowserActionOverflowMenuController::WriteDragData( 343 void ChevronMenuButton::MenuController::WriteDragData(
255 views::MenuItemView* sender, OSExchangeData* data) { 344 views::MenuItemView* sender, OSExchangeData* data) {
256 size_t drag_index = IndexForId(sender->GetCommand()); 345 size_t drag_index = IndexForId(sender->GetCommand());
257 const extensions::Extension* extension = views_[drag_index]->extension(); 346 const extensions::Extension* extension =
347 browser_actions_container_->GetBrowserActionViewAt(drag_index)->
348 extension();
258 BrowserActionDragData drag_data(extension->id(), drag_index); 349 BrowserActionDragData drag_data(extension->id(), drag_index);
259 drag_data.Write(owner_->profile(), data); 350 drag_data.Write(browser_actions_container_->profile(), data);
260 } 351 }
261 352
262 int BrowserActionOverflowMenuController::GetDragOperations( 353 int ChevronMenuButton::MenuController::GetDragOperations(
263 views::MenuItemView* sender) { 354 views::MenuItemView* sender) {
264 return ui::DragDropTypes::DRAG_MOVE; 355 return ui::DragDropTypes::DRAG_MOVE;
265 } 356 }
266 357
267 size_t BrowserActionOverflowMenuController::IndexForId(int id) const { 358 size_t ChevronMenuButton::MenuController::IndexForId(int id) const {
268 // The index of the view being dragged (GetCommand gives a 1-based index into 359 // The index of the view being dragged (GetCommand gives a 1-based index into
269 // the overflow menu). 360 // the overflow menu).
270 DCHECK_GT(owner_->VisibleBrowserActions() + id, 0u); 361 DCHECK_GT(browser_actions_container_->VisibleBrowserActions() + id, 0u);
271 return owner_->VisibleBrowserActions() + id - 1; 362 return browser_actions_container_->VisibleBrowserActions() + id - 1;
272 } 363 }
364
365 ChevronMenuButton::ChevronMenuButton(
366 BrowserActionsContainer* browser_actions_container)
367 : views::MenuButton(NULL, base::string16(), this, false),
368 browser_actions_container_(browser_actions_container),
369 weak_factory_(this) {
370 }
371
372 ChevronMenuButton::~ChevronMenuButton() {
373 }
374
375 void ChevronMenuButton::CloseMenu() {
376 if (menu_controller_.get())
377 menu_controller_->CloseMenu();
378 }
379
380 scoped_ptr<views::LabelButtonBorder> ChevronMenuButton::CreateDefaultBorder()
381 const {
382 // The chevron resource was designed to not have any insets.
383 scoped_ptr<views::LabelButtonBorder> border =
384 views::MenuButton::CreateDefaultBorder();
385 border->set_insets(gfx::Insets());
386 return border.Pass();
387 }
388
389 bool ChevronMenuButton::GetDropFormats(
390 int* formats,
391 std::set<OSExchangeData::CustomFormat>* custom_formats) {
392 return BrowserActionDragData::GetDropFormats(custom_formats);
393 }
394
395 bool ChevronMenuButton::AreDropTypesRequired() {
396 return BrowserActionDragData::AreDropTypesRequired();
397 }
398
399 bool ChevronMenuButton::CanDrop(const OSExchangeData& data) {
400 return BrowserActionDragData::CanDrop(
401 data, browser_actions_container_->profile());
402 }
403
404 void ChevronMenuButton::OnDragEntered(const ui::DropTargetEvent& event) {
405 DCHECK(!weak_factory_.HasWeakPtrs());
406 base::MessageLoop::current()->PostDelayedTask(
407 FROM_HERE,
408 base::Bind(&ChevronMenuButton::ShowOverflowMenu,
409 weak_factory_.GetWeakPtr(),
410 true),
411 base::TimeDelta::FromMilliseconds(views::GetMenuShowDelay()));
412 }
413
414 int ChevronMenuButton::OnDragUpdated(const ui::DropTargetEvent& event) {
415 return ui::DragDropTypes::DRAG_MOVE;
416 }
417
418 void ChevronMenuButton::OnDragExited() {
419 weak_factory_.InvalidateWeakPtrs();
420 }
421
422 int ChevronMenuButton::OnPerformDrop(const ui::DropTargetEvent& event) {
423 return ui::DragDropTypes::DRAG_MOVE;
424 }
425
426 void ChevronMenuButton::OnMenuButtonClicked(views::View* source,
427 const gfx::Point& point) {
428 DCHECK_EQ(this, source);
429 ShowOverflowMenu(false);
430 }
431
432 void ChevronMenuButton::ShowOverflowMenu(bool for_drop) {
433 DCHECK(!menu_controller_.get());
434 menu_controller_.reset(new MenuController(
435 this, browser_actions_container_, for_drop));
436 menu_controller_->RunMenu(GetWidget());
437 }
438
439 void ChevronMenuButton::MenuDone() {
440 menu_controller_.reset();
441 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698