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 457fbdbbd37285e423c2f8d4da33e0178df0559c..e73049005453d68e54a1ac930d84c252fda4594e 100644 |
--- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
+++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
@@ -126,7 +126,8 @@ BrowserActionsContainer::BrowserActionsContainer( |
Browser* browser, |
View* owner_view, |
BrowserActionsContainer* main_container) |
- : profile_(browser->profile()), |
+ : initialized_(false), |
+ profile_(browser->profile()), |
browser_(browser), |
owner_view_(owner_view), |
main_container_(main_container), |
@@ -197,6 +198,8 @@ void BrowserActionsContainer::Init() { |
container_width_ = GetPreferredWidth(); |
SetChevronVisibility(); |
} |
+ |
+ initialized_ = true; |
} |
BrowserActionView* BrowserActionsContainer::GetViewForExtension( |
@@ -270,14 +273,21 @@ void BrowserActionsContainer::ExecuteExtensionCommand( |
command.accelerator()); |
} |
+void BrowserActionsContainer::NotifyActionMovedToOverflow() { |
+ // When an action is moved to overflow, we shrink the size of the container |
+ // by 1. |
+ if (!profile_->IsOffTheRecord()) |
+ model_->SetVisibleIconCount(model_->GetVisibleIconCount() - 1); |
+ Animate(gfx::Tween::EASE_OUT, |
+ VisibleBrowserActionsAfterAnimation() - 1); |
+} |
+ |
bool BrowserActionsContainer::ShownInsideMenu() const { |
return in_overflow_mode(); |
} |
void BrowserActionsContainer::OnBrowserActionViewDragDone() { |
- // We notify here as well as in OnPerformDrop because the dragged view is |
- // removed in OnPerformDrop, so it will never get its OnDragDone() call. |
- // TODO(devlin): we should see about fixing that. |
+ ToolbarVisibleCountChanged(); |
FOR_EACH_OBSERVER(BrowserActionsContainerObserver, |
observers_, |
OnBrowserActionDragDone()); |
@@ -433,7 +443,7 @@ bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) { |
int BrowserActionsContainer::OnDragUpdated( |
const ui::DropTargetEvent& event) { |
// First check if we are above the chevron (overflow) menu. |
- if (GetEventHandlerForPoint(event.location()) == chevron_) { |
+ if (chevron_ && GetEventHandlerForPoint(event.location()) == chevron_) { |
if (!show_menu_task_factory_.HasWeakPtrs() && !overflow_menu_) |
StartShowFolderDropMenuTimer(); |
return ui::DragDropTypes::DRAG_MOVE; |
@@ -546,13 +556,28 @@ int BrowserActionsContainer::OnPerformDrop( |
if (profile_->IsOffTheRecord()) |
i = model_->IncognitoIndexToOriginal(i); |
+ // If this was a drag between containers, we will have to adjust the number of |
+ // visible icons. |
+ bool drag_between_containers = |
+ !browser_action_views_[data.index()]->visible(); |
model_->MoveExtensionIcon( |
browser_action_views_[data.index()]->extension(), i); |
+ if (drag_between_containers) { |
+ // Add one for the dropped icon. |
+ size_t new_icon_count = VisibleBrowserActionsAfterAnimation() + 1; |
+ |
+ // Let the main container update the model. |
+ if (in_overflow_mode()) |
+ main_container_->NotifyActionMovedToOverflow(); |
+ else if (!profile_->IsOffTheRecord()) // This is the main container. |
+ model_->SetVisibleIconCount(model_->GetVisibleIconCount() + 1); |
+ |
+ // The size changed, so we need to animate. |
+ Animate(gfx::Tween::EASE_OUT, new_icon_count); |
+ } |
+ |
OnDragExited(); // Perform clean up after dragging. |
- FOR_EACH_OBSERVER(BrowserActionsContainerObserver, |
- observers_, |
- OnBrowserActionDragDone()); |
return ui::DragDropTypes::DRAG_MOVE; |
} |
@@ -634,7 +659,6 @@ void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) { |
int visible_icons = WidthToIconCount(container_width_); |
if (!profile_->IsOffTheRecord()) |
model_->SetVisibleIconCount(visible_icons); |
- |
Animate(gfx::Tween::EASE_OUT, visible_icons); |
} |
@@ -680,7 +704,8 @@ extensions::ActiveTabPermissionGranter* |
} |
size_t BrowserActionsContainer::GetFirstVisibleIconIndex() const { |
- return in_overflow_mode() ? model_->GetVisibleIconCount() : 0; |
+ return in_overflow_mode() ? |
+ main_container_->VisibleBrowserActionsAfterAnimation() : 0; |
} |
ExtensionPopup* BrowserActionsContainer::TestGetPopup() { |
@@ -688,11 +713,7 @@ ExtensionPopup* BrowserActionsContainer::TestGetPopup() { |
} |
void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) { |
- model_->SetVisibleIconCount(icons); |
- chevron_->SetVisible(icons < browser_action_views_.size()); |
- container_width_ = IconCountToWidth(icons, chevron_->visible()); |
- Layout(); |
- SchedulePaint(); |
+ model_->SetVisibleIconCountForTest(icons); |
} |
void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) { |
@@ -961,6 +982,11 @@ void BrowserActionsContainer::OnBrowserActionVisibilityChanged() { |
if (owner_view_) { |
owner_view_->Layout(); |
owner_view_->SchedulePaint(); |
+ } else { |
+ // In overflow mode, we don't have an owner view, but we still have to |
+ // update ourselves. |
+ Layout(); |
+ SchedulePaint(); |
} |
} |
@@ -972,8 +998,10 @@ int BrowserActionsContainer::GetPreferredWidth() { |
} |
void BrowserActionsContainer::SetChevronVisibility() { |
- if (chevron_) |
- chevron_->SetVisible(GetIconCount() < browser_action_views_.size()); |
+ if (chevron_) { |
+ chevron_->SetVisible( |
+ VisibleBrowserActionsAfterAnimation() < browser_action_views_.size()); |
+ } |
} |
void BrowserActionsContainer::CloseOverflowMenu() { |
@@ -1026,11 +1054,12 @@ size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { |
if (pixels >= IconCountToWidth(-1, false)) |
return browser_action_views_.size(); |
- // We need to reserve space for the resize area, chevron, and the spacing on |
- // either side of the chevron. |
- int available_space = pixels - ToolbarView::kStandardSpacing - |
- (chevron_ ? chevron_->GetPreferredSize().width() : 0) - |
- kChevronSpacing - ToolbarView::kStandardSpacing; |
+ // We reserve space for the padding on either side of the toolbar... |
+ int available_space = pixels - (ToolbarView::kStandardSpacing * 2); |
+ // ... and, if the chevron is enabled, the chevron. |
+ if (chevron_) |
+ available_space -= (chevron_->GetPreferredSize().width() + kChevronSpacing); |
+ |
// Now we add an extra between-item padding value so the space can be divided |
// evenly by (size of icon with padding). |
return static_cast<size_t>( |
@@ -1071,22 +1100,37 @@ bool BrowserActionsContainer::ShouldDisplayBrowserAction( |
size_t BrowserActionsContainer::GetIconCount() const { |
if (!model_) |
return 0u; |
+ |
+ const extensions::ExtensionList& extensions = model_->toolbar_items(); |
+ |
+ // Find the absolute value for the model's visible count. |
+ int model_visible_size = model_->GetVisibleIconCount(); |
+ size_t absolute_model_visible_size = |
+ model_visible_size == -1 ? extensions.size() : model_visible_size; |
+ |
// Find the number of icons which could be displayed. |
size_t displayable_icon_count = 0u; |
- const extensions::ExtensionList& extensions = model_->toolbar_items(); |
- for (extensions::ExtensionList::const_iterator iter = extensions.begin(); |
- iter != extensions.end(); ++iter) { |
- displayable_icon_count += ShouldDisplayBrowserAction(iter->get()) ? 1u : 0u; |
+ size_t main_displayed = 0u; |
+ for (size_t i = 0; i < extensions.size(); ++i) { |
+ // Should there be an icon for this extension at all? |
+ if (ShouldDisplayBrowserAction(extensions[i].get())) { |
+ ++displayable_icon_count; |
+ // Should we display it on the main bar? If this is an incognito window, |
+ // icons have the same overflow status they do in a regular window. |
+ main_displayed += i < absolute_model_visible_size ? 1u : 0u; |
+ } |
} |
- // Find the absolute value for the model's visible count. |
- int model_size = model_->GetVisibleIconCount(); |
- size_t absolute_model_size = |
- model_size == -1 ? extensions.size() : model_size; |
- |
- // The main container will try to show |model_size| icons, but reduce if there |
- // aren't enough displayable icons to do so. |
- size_t main_displayed = std::min(displayable_icon_count, absolute_model_size); |
- // The overflow will display the extras, if any. |
+ |
+ // If this is an existing (initialized) container from an incognito profile, |
+ // we can't trust the model (because the incognito bars don't adjust model |
+ // settings). Instead, we go off what we currently have displayed. |
+ if (initialized_ && profile_->IsOffTheRecord()) { |
+ main_displayed = in_overflow_mode() ? |
+ main_container_->VisibleBrowserActionsAfterAnimation() : |
+ VisibleBrowserActionsAfterAnimation(); |
+ } |
+ |
+ // The overflow displays any (displayable) icons not shown by the main bar. |
return in_overflow_mode() ? |
displayable_icon_count - main_displayed : main_displayed; |
} |