Index: chrome/browser/ui/views/toolbar/browser_actions_container.cc |
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.cc b/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
index d00e9d99cf6e81947975d1b60641b6b95c16e945..1d49916a698767550953dbef13c599aaed7d4d82 100644 |
--- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
+++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
@@ -59,7 +59,8 @@ ScopedVector<ToolbarActionViewController> GetToolbarActions( |
// Extension actions come first. |
extensions::ExtensionActionManager* action_manager = |
extensions::ExtensionActionManager::Get(browser->profile()); |
- const extensions::ExtensionList& toolbar_items = model->toolbar_items(); |
+ const extensions::ExtensionList& toolbar_items = model->GetItemOrderForTab( |
+ browser->tab_strip_model()->GetActiveWebContents()); |
for (const scoped_refptr<const Extension>& extension : toolbar_items) { |
actions.push_back(new ExtensionActionViewController( |
extension.get(), |
@@ -124,6 +125,8 @@ BrowserActionsContainer::BrowserActionsContainer( |
resize_area_(NULL), |
chevron_(NULL), |
suppress_chevron_(false), |
+ suppress_animation_(false), |
+ suppress_layout_(false), |
resize_amount_(0), |
animation_target_size_(0) { |
set_id(VIEW_ID_BROWSER_ACTION_TOOLBAR); |
@@ -193,8 +196,23 @@ BrowserActionView* BrowserActionsContainer::GetViewForExtension( |
} |
void BrowserActionsContainer::RefreshBrowserActionViews() { |
+ if (browser_action_views_.empty()) |
+ return; // Nothing to do. |
+ |
+ // When we do a bulk-refresh of views (such as when we switch tabs), we don't |
+ // animate the difference. We only animate when it's a change driven by the |
+ // action. |
+ suppress_animation_ = true; |
+ // Don't layout until the end. |
+ suppress_layout_ = true; |
+ |
for (BrowserActionView* view : browser_action_views_) |
view->UpdateState(); |
+ |
+ suppress_layout_ = false; |
+ ReorderViews(); // Also triggers a layout. |
+ |
+ suppress_animation_ = false; |
} |
void BrowserActionsContainer::CreateBrowserActionViews() { |
@@ -202,6 +220,9 @@ void BrowserActionsContainer::CreateBrowserActionViews() { |
if (!model_) |
return; |
+ // We don't Layout while creating views. Instead, Layout() once at the end. |
+ suppress_layout_ = true; |
+ |
ScopedVector<ToolbarActionViewController> actions = |
GetToolbarActions(model_, browser_); |
for (ToolbarActionViewController* controller : actions) { |
@@ -211,6 +232,11 @@ void BrowserActionsContainer::CreateBrowserActionViews() { |
AddChildView(view); |
} |
actions.weak_clear(); |
+ |
+ suppress_layout_ = false; |
+ |
+ Layout(); |
+ SchedulePaint(); |
} |
void BrowserActionsContainer::DeleteBrowserActionViews() { |
@@ -361,6 +387,9 @@ void BrowserActionsContainer::Layout() { |
return; |
} |
+ if (suppress_layout_) |
+ return; |
+ |
SetVisible(true); |
if (resize_area_) |
resize_area_->SetBounds(0, 0, kItemSpacing, height()); |
@@ -636,7 +665,7 @@ void BrowserActionsContainer::AnimationEnded(const gfx::Animation* animation) { |
OnBrowserActionsContainerAnimationEnded()); |
} |
-content::WebContents* BrowserActionsContainer::GetCurrentWebContents() { |
+content::WebContents* BrowserActionsContainer::GetCurrentWebContents() const { |
return browser_->tab_strip_model()->GetActiveWebContents(); |
} |
@@ -884,8 +913,15 @@ bool BrowserActionsContainer::ShowExtensionActionPopup( |
} |
void BrowserActionsContainer::ToolbarVisibleCountChanged() { |
- if (GetPreferredWidth() != container_width_) |
+ if (GetPreferredWidth() != container_width_) { |
Animate(gfx::Tween::EASE_OUT, GetIconCount()); |
+ } else if (animation_target_size_ != 0) { |
+ // It's possible that we're right where we're supposed to be in terms of |
+ // icon count, but that we're also currently resizing. If this is the case, |
+ // end the current animation with the current width. |
+ animation_target_size_ = container_width_; |
+ resize_animation_->Reset(); |
+ } |
} |
void BrowserActionsContainer::ToolbarHighlightModeChanged( |
@@ -899,6 +935,12 @@ void BrowserActionsContainer::ToolbarHighlightModeChanged( |
Animate(gfx::Tween::LINEAR, GetIconCount()); |
} |
+void BrowserActionsContainer::ToolbarReorderNecessary( |
+ content::WebContents* web_contents) { |
+ if (GetCurrentWebContents() == web_contents) |
+ ReorderViews(); |
+} |
+ |
Browser* BrowserActionsContainer::GetBrowser() { |
return browser_; |
} |
@@ -984,7 +1026,8 @@ int BrowserActionsContainer::MinimumNonemptyWidth() const { |
void BrowserActionsContainer::Animate(gfx::Tween::Type tween_type, |
size_t num_visible_icons) { |
int target_size = IconCountToWidth(num_visible_icons); |
- if (resize_animation_ && !disable_animations_during_testing_) { |
+ if (resize_animation_ && !disable_animations_during_testing_ && |
+ !suppress_animation_) { |
// Animate! We have to set the animation_target_size_ after calling Reset(), |
// because that could end up calling AnimationEnded which clears the value. |
resize_animation_->Reset(); |
@@ -997,12 +1040,40 @@ void BrowserActionsContainer::Animate(gfx::Tween::Type tween_type, |
} |
} |
+void BrowserActionsContainer::ReorderViews() { |
+ extensions::ExtensionList new_order = |
+ model_->GetItemOrderForTab(GetCurrentWebContents()); |
+ if (new_order.empty()) |
+ return; // Nothing to do. |
+ |
+ // Run through the views and compare them to the desired order. If something |
+ // is out of place, find the correct spot for it. |
+ for (size_t i = 0; i < new_order.size() - 1; ++i) { |
+ if (new_order[i]->id() != |
+ browser_action_views_[i]->view_controller()->GetId()) { |
+ // Find where the correct view is (it's guaranteed to be after our current |
+ // index, since everything up to this point is correct). |
+ size_t j = i + 1; |
+ while (new_order[i]->id() != |
+ browser_action_views_[j]->view_controller()->GetId()) |
+ ++j; |
+ std::swap(browser_action_views_[i], browser_action_views_[j]); |
+ } |
+ } |
+ |
+ // Our visible browser actions may have changed - re-Layout() and check the |
+ // size. |
+ ToolbarVisibleCountChanged(); |
+ OnBrowserActionVisibilityChanged(); |
+} |
+ |
size_t BrowserActionsContainer::GetIconCount() const { |
if (!model_) |
return 0u; |
// Find the absolute value for the model's visible count. |
- int model_visible_size = model_->GetVisibleIconCount(); |
+ int model_visible_size = |
+ model_->GetVisibleIconCountForTab(GetCurrentWebContents()); |
size_t absolute_model_visible_size = model_visible_size == -1 ? |
model_->toolbar_items().size() : model_visible_size; |