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

Side by Side Diff: chrome/browser/ui/toolbar/toolbar_actions_bar.cc

Issue 1105713002: [Extension Toolbar] Slide out overflowed actions for popups (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Latest master Created 5 years, 7 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/toolbar/toolbar_actions_bar.h" 5 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/profiler/scoped_tracker.h" 8 #include "base/profiler/scoped_tracker.h"
9 #include "chrome/browser/extensions/extension_action_manager.h" 9 #include "chrome/browser/extensions/extension_action_manager.h"
10 #include "chrome/browser/extensions/extension_message_bubble_controller.h" 10 #include "chrome/browser/extensions/extension_message_bubble_controller.h"
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 browser_(browser), 118 browser_(browser),
119 model_(extensions::ExtensionToolbarModel::Get(browser_->profile())), 119 model_(extensions::ExtensionToolbarModel::Get(browser_->profile())),
120 main_bar_(main_bar), 120 main_bar_(main_bar),
121 platform_settings_(main_bar != nullptr), 121 platform_settings_(main_bar != nullptr),
122 popup_owner_(nullptr), 122 popup_owner_(nullptr),
123 model_observer_(this), 123 model_observer_(this),
124 suppress_layout_(false), 124 suppress_layout_(false),
125 suppress_animation_(true), 125 suppress_animation_(true),
126 overflowed_action_wants_to_run_(false), 126 overflowed_action_wants_to_run_(false),
127 checked_extension_bubble_(false), 127 checked_extension_bubble_(false),
128 popped_out_action_(nullptr),
128 weak_ptr_factory_(this) { 129 weak_ptr_factory_(this) {
129 if (model_) // |model_| can be null in unittests. 130 if (model_) // |model_| can be null in unittests.
130 model_observer_.Add(model_); 131 model_observer_.Add(model_);
131 } 132 }
132 133
133 ToolbarActionsBar::~ToolbarActionsBar() { 134 ToolbarActionsBar::~ToolbarActionsBar() {
134 // We don't just call DeleteActions() here because it makes assumptions about 135 // We don't just call DeleteActions() here because it makes assumptions about
135 // the order of deletion between the views and the ToolbarActionsBar. 136 // the order of deletion between the views and the ToolbarActionsBar.
136 DCHECK(toolbar_actions_.empty()) << 137 DCHECK(toolbar_actions_.empty()) <<
137 "Must call DeleteActions() before destruction."; 138 "Must call DeleteActions() before destruction.";
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 // Now we add an extra between-item padding value so the space can be divided 222 // Now we add an extra between-item padding value so the space can be divided
222 // evenly by (size of icon with padding). 223 // evenly by (size of icon with padding).
223 return static_cast<size_t>(std::max( 224 return static_cast<size_t>(std::max(
224 0, available_space + platform_settings_.item_spacing) / IconWidth(true)); 225 0, available_space + platform_settings_.item_spacing) / IconWidth(true));
225 } 226 }
226 227
227 size_t ToolbarActionsBar::GetIconCount() const { 228 size_t ToolbarActionsBar::GetIconCount() const {
228 if (!model_) 229 if (!model_)
229 return 0u; 230 return 0u;
230 231
232 // We purposefully do not account for any "popped out" actions in overflow
233 // mode. This is because the popup cannot be showing while the overflow menu
234 // is open, so there's no concern there. Also, if the user has a popped out
235 // action, and immediately opens the overflow menu, we *want* the action there
236 // (since it will close the popup, but do so asynchronously, and we don't
237 // want to "slide" the action back in.
231 size_t visible_icons = in_overflow_mode() ? 238 size_t visible_icons = in_overflow_mode() ?
232 toolbar_actions_.size() - main_bar_->GetIconCount() : 239 toolbar_actions_.size() - model_->visible_icon_count() :
233 model_->visible_icon_count(); 240 model_->visible_icon_count() + (popped_out_action_ ? 1 : 0);
234 241
235 #if DCHECK_IS_ON() 242 #if DCHECK_IS_ON()
236 // Good time for some sanity checks: We should never try to display more 243 // Good time for some sanity checks: We should never try to display more
237 // icons than we have, and we should always have a view per item in the model. 244 // icons than we have, and we should always have a view per item in the model.
238 // (The only exception is if this is in initialization.) 245 // (The only exception is if this is in initialization.)
239 if (!toolbar_actions_.empty() && !suppress_layout_ && 246 if (!toolbar_actions_.empty() && !suppress_layout_ &&
240 model_->extensions_initialized()) { 247 model_->extensions_initialized()) {
241 size_t num_extension_actions = 0u; 248 size_t num_extension_actions = 0u;
242 for (ToolbarActionViewController* action : toolbar_actions_) { 249 for (ToolbarActionViewController* action : toolbar_actions_) {
243 // No component action should ever have a valid extension id, so we can 250 // No component action should ever have a valid extension id, so we can
244 // use this to check the extension amount. 251 // use this to check the extension amount.
245 if (crx_file::id_util::IdIsValid(action->GetId())) 252 if (crx_file::id_util::IdIsValid(action->GetId()))
246 ++num_extension_actions; 253 ++num_extension_actions;
247 } 254 }
248 255
249 int num_component_actions = 256 int num_component_actions =
250 ComponentToolbarActionsFactory::GetInstance()-> 257 ComponentToolbarActionsFactory::GetInstance()->
251 GetNumComponentActions(); 258 GetNumComponentActions();
252 size_t num_total_actions = num_extension_actions + num_component_actions; 259 size_t num_total_actions = num_extension_actions + num_component_actions;
253 260
254 DCHECK_LE(visible_icons, num_total_actions); 261 DCHECK_LE(visible_icons, num_total_actions);
255 DCHECK_EQ(model_->toolbar_items().size(), num_extension_actions); 262 DCHECK_EQ(model_->toolbar_items().size(), num_extension_actions);
256 } 263 }
257 #endif 264 #endif
258 265
259 return visible_icons; 266 return visible_icons;
260 } 267 }
261 268
269 std::vector<ToolbarActionViewController*>
270 ToolbarActionsBar::GetActions() const {
271 std::vector<ToolbarActionViewController*> actions = toolbar_actions_.get();
272
273 // If there is an action that should be popped out, and it's not visible by
274 // default, make it the final action in the list.
275 if (popped_out_action_) {
276 size_t index =
277 std::find(actions.begin(), actions.end(), popped_out_action_) -
278 actions.begin();
279 DCHECK_NE(actions.size(), index);
280 size_t visible = GetIconCount();
281 if (index >= visible) {
282 size_t rindex = actions.size() - index - 1;
283 std::rotate(actions.rbegin() + rindex,
284 actions.rbegin() + rindex + 1,
285 actions.rend() - visible + 1);
286 }
287 }
288
289 return actions;
290 }
291
262 void ToolbarActionsBar::CreateActions() { 292 void ToolbarActionsBar::CreateActions() {
263 DCHECK(toolbar_actions_.empty()); 293 DCHECK(toolbar_actions_.empty());
264 // We wait for the extension system to be initialized before we add any 294 // We wait for the extension system to be initialized before we add any
265 // actions, as they rely on the extension system to function. 295 // actions, as they rely on the extension system to function.
266 if (!model_ || !model_->extensions_initialized()) 296 if (!model_ || !model_->extensions_initialized())
267 return; 297 return;
268 298
269 { 299 {
270 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/463337 300 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/463337
271 // is fixed. 301 // is fixed.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 if (drag_type == DRAG_TO_OVERFLOW) 417 if (drag_type == DRAG_TO_OVERFLOW)
388 delta = -1; 418 delta = -1;
389 else if (drag_type == DRAG_TO_MAIN) 419 else if (drag_type == DRAG_TO_MAIN)
390 delta = 1; 420 delta = 1;
391 model_->MoveExtensionIcon(toolbar_actions_[dragged_index]->GetId(), 421 model_->MoveExtensionIcon(toolbar_actions_[dragged_index]->GetId(),
392 dropped_index); 422 dropped_index);
393 if (delta) 423 if (delta)
394 model_->SetVisibleIconCount(model_->visible_icon_count() + delta); 424 model_->SetVisibleIconCount(model_->visible_icon_count() + delta);
395 } 425 }
396 426
427 void ToolbarActionsBar::OnAnimationEnded() {
428 // Check if we were waiting for animation to finish to run a popup.
429 if (!popped_out_closure_.is_null()) {
430 popped_out_closure_.Run();
431 popped_out_closure_.Reset();
432 }
433 }
434
435 bool ToolbarActionsBar::IsActionVisible(
436 const ToolbarActionViewController* action) const {
437 size_t index = std::find(toolbar_actions_.begin(),
438 toolbar_actions_.end(),
439 action) - toolbar_actions_.begin();
440 return index < GetIconCount() || action == popped_out_action_;
441 }
442
443 void ToolbarActionsBar::PopOutAction(ToolbarActionViewController* controller,
444 const base::Closure& closure) {
445 DCHECK(!popped_out_action_) << "Only one action can be popped out at a time!";
446 bool needs_redraw = !IsActionVisible(controller);
447 popped_out_action_ = controller;
448 if (needs_redraw) {
449 // We suppress animation for this draw, because we need the action to get
450 // into position immediately, since it's about to show its popup.
451 base::AutoReset<bool> layout_resetter(&suppress_animation_, false);
452 delegate_->Redraw(true);
453 }
454
455 ResizeDelegate(gfx::Tween::LINEAR, false);
456 if (!delegate_->IsAnimating()) {
457 // Don't call the closure re-entrantly.
458 base::MessageLoop::current()->PostTask(FROM_HERE, closure);
459 } else {
460 popped_out_closure_ = closure;
461 }
462 }
463
464 void ToolbarActionsBar::UndoPopOut() {
465 DCHECK(popped_out_action_);
466 ToolbarActionViewController* controller = popped_out_action_;
467 popped_out_action_ = nullptr;
468 popped_out_closure_.Reset();
469 if (!IsActionVisible(controller))
470 delegate_->Redraw(true);
471 ResizeDelegate(gfx::Tween::LINEAR, false);
472 }
473
397 void ToolbarActionsBar::SetPopupOwner( 474 void ToolbarActionsBar::SetPopupOwner(
398 ToolbarActionViewController* popup_owner) { 475 ToolbarActionViewController* popup_owner) {
399 // We should never be setting a popup owner when one already exists, and 476 // We should never be setting a popup owner when one already exists, and
400 // never unsetting one when one wasn't set. 477 // never unsetting one when one wasn't set.
401 DCHECK((!popup_owner_ && popup_owner) || 478 DCHECK((!popup_owner_ && popup_owner) ||
402 (popup_owner_ && !popup_owner)); 479 (popup_owner_ && !popup_owner));
403 popup_owner_ = popup_owner; 480 popup_owner_ = popup_owner;
404 } 481 }
405 482
406 void ToolbarActionsBar::HideActivePopup() { 483 void ToolbarActionsBar::HideActivePopup() {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 for (ToolbarActionViewController* action : toolbar_actions_) { 706 for (ToolbarActionViewController* action : toolbar_actions_) {
630 if (action->GetId() == id) 707 if (action->GetId() == id)
631 return action; 708 return action;
632 } 709 }
633 return nullptr; 710 return nullptr;
634 } 711 }
635 712
636 content::WebContents* ToolbarActionsBar::GetCurrentWebContents() { 713 content::WebContents* ToolbarActionsBar::GetCurrentWebContents() {
637 return browser_->tab_strip_model()->GetActiveWebContents(); 714 return browser_->tab_strip_model()->GetActiveWebContents();
638 } 715 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/toolbar/toolbar_actions_bar.h ('k') | chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698