Chromium Code Reviews| Index: chrome/browser/views/browser_actions_container.cc |
| =================================================================== |
| --- chrome/browser/views/browser_actions_container.cc (revision 53742) |
| +++ chrome/browser/views/browser_actions_container.cc (working copy) |
| @@ -78,12 +78,6 @@ |
| // Width for the resize area. |
| static const int kResizeAreaWidth = 4; |
| -// Width of the drop indicator. |
| -static const int kDropIndicatorWidth = 2; |
| - |
| -// Color of the drop indicator. |
| -static const SkColor kDropIndicatorColor = SK_ColorBLACK; |
| - |
| // The x offset for the drop indicator (how much we shift it by). |
| static const int kDropIndicatorOffsetLtr = 3; |
| static const int kDropIndicatorOffsetRtl = 9; |
| @@ -98,7 +92,8 @@ |
| BrowserActionButton::BrowserActionButton(Extension* extension, |
| BrowserActionsContainer* panel) |
| - : ALLOW_THIS_IN_INITIALIZER_LIST(MenuButton(this, L"", NULL, false)), |
| + : ALLOW_THIS_IN_INITIALIZER_LIST( |
| + MenuButton(this, std::wstring(), NULL, false)), |
| browser_action_(extension->browser_action()), |
| extension_(extension), |
| ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)), |
| @@ -138,18 +133,14 @@ |
| } |
| } |
| -gfx::Insets BrowserActionButton::GetInsets() const { |
| - static gfx::Insets zero_inset; |
| - return zero_inset; |
| -} |
| - |
| void BrowserActionButton::ButtonPressed(views::Button* sender, |
| - const views::Event& event) { |
| - panel_->OnBrowserActionExecuted(this, false); // inspect_with_devtools |
| + const views::Event& event) { |
| + panel_->OnBrowserActionExecuted(this, false); |
|
Finnur
2010/07/27 09:02:23
nit: Doesn't the style guide say you should docume
Peter Kasting
2010/07/27 18:24:43
The precise style guide text is:
"When you pass i
Finnur
2010/07/27 20:13:17
OK
|
| } |
| -void BrowserActionButton::OnImageLoaded( |
| - SkBitmap* image, ExtensionResource resource, int index) { |
| +void BrowserActionButton::OnImageLoaded(SkBitmap* image, |
| + ExtensionResource resource, |
| + int index) { |
| if (image) |
| default_icon_ = *image; |
| @@ -181,66 +172,56 @@ |
| void BrowserActionButton::Observe(NotificationType type, |
| const NotificationSource& source, |
| const NotificationDetails& details) { |
| - if (type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED) { |
| - UpdateState(); |
| - // The browser action may have become visible/hidden so we need to make |
| - // sure the state gets updated. |
| - panel_->OnBrowserActionVisibilityChanged(); |
| - } else { |
| - NOTREACHED() << L"Received unexpected notification"; |
| - } |
| + DCHECK(type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED); |
| + UpdateState(); |
| + // The browser action may have become visible/hidden so we need to make |
| + // sure the state gets updated. |
| + panel_->OnBrowserActionVisibilityChanged(); |
| } |
| bool BrowserActionButton::IsPopup() { |
| int tab_id = panel_->GetCurrentTabId(); |
| - if (tab_id < 0) { |
| - NOTREACHED() << "Button is not on a specific tab."; |
| - return false; |
| - } |
| + DCHECK_GE(tab_id, 0); |
| return browser_action_->HasPopup(tab_id); |
| } |
| GURL BrowserActionButton::GetPopupUrl() { |
| int tab_id = panel_->GetCurrentTabId(); |
| - if (tab_id < 0) { |
| - NOTREACHED() << "Button is not on a specific tab."; |
| - GURL empty_url; |
| - return empty_url; |
| - } |
| + DCHECK_GE(tab_id, 0); |
| return browser_action_->GetPopupUrl(tab_id); |
| } |
| bool BrowserActionButton::Activate() { |
| - if (IsPopup()) { |
| - panel_->OnBrowserActionExecuted(this, false); // |inspect_with_devtools|. |
| + if (!IsPopup()) |
| + return true; |
| - // TODO(erikkay): Run a nested modal loop while the mouse is down to |
| - // enable menu-like drag-select behavior. |
| + panel_->OnBrowserActionExecuted(this, false); // |inspect_with_devtools|. |
| - // The return value of this method is returned via OnMousePressed. |
| - // We need to return false here since we're handing off focus to another |
| - // widget/view, and true will grab it right back and try to send events |
| - // to us. |
| - return false; |
| - } |
| - return true; |
| + // TODO(erikkay): Run a nested modal loop while the mouse is down to |
| + // enable menu-like drag-select behavior. |
| + |
| + // The return value of this method is returned via OnMousePressed. |
| + // We need to return false here since we're handing off focus to another |
| + // widget/view, and true will grab it right back and try to send events |
| + // to us. |
| + return false; |
| } |
| bool BrowserActionButton::OnMousePressed(const views::MouseEvent& e) { |
| - if (e.IsRightMouseButton()) { |
| - // Get the top left point of this button in screen coordinates. |
| - gfx::Point point = gfx::Point(0, 0); |
| - ConvertPointToScreen(this, &point); |
| + if (!e.IsRightMouseButton()) { |
| + return IsPopup() ? |
| + MenuButton::OnMousePressed(e) : TextButton::OnMousePressed(e); |
| + } |
| - // Make the menu appear below the button. |
| - point.Offset(0, height()); |
| + // Get the top left point of this button in screen coordinates. |
| + gfx::Point point = gfx::Point(0, 0); |
| + ConvertPointToScreen(this, &point); |
| - ShowContextMenu(point, true); |
| - return false; |
| - } else if (IsPopup()) { |
| - return MenuButton::OnMousePressed(e); |
| - } |
| - return TextButton::OnMousePressed(e); |
| + // Make the menu appear below the button. |
| + point.Offset(0, height()); |
| + |
| + ShowContextMenu(point, true); |
| + return false; |
| } |
| void BrowserActionButton::OnMouseReleased(const views::MouseEvent& e, |
| @@ -255,9 +236,8 @@ |
| } |
| bool BrowserActionButton::OnKeyReleased(const views::KeyEvent& e) { |
| - if (IsPopup()) |
| - return MenuButton::OnKeyReleased(e); |
| - return TextButton::OnKeyReleased(e); |
| + return IsPopup() ? |
| + MenuButton::OnKeyReleased(e) : TextButton::OnKeyReleased(e); |
| } |
| void BrowserActionButton::OnMouseExited(const views::MouseEvent& e) { |
| @@ -273,8 +253,8 @@ |
| SetButtonPushed(); |
| // Reconstructs the menu every time because the menu's contents are dynamic. |
| - context_menu_contents_ = new ExtensionContextMenuModel( |
| - extension(), panel_->browser(), panel_); |
| + context_menu_contents_ = |
| + new ExtensionContextMenuModel(extension(), panel_->browser(), panel_); |
| context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get())); |
| context_menu_menu_->RunContextMenuAt(p); |
| @@ -322,15 +302,12 @@ |
| if (icon.isNull()) |
| icon = button_->default_icon(); |
| - gfx::Canvas* canvas = |
| - new gfx::CanvasSkia(icon.width(), icon.height(), false); |
| + gfx::Canvas* canvas = new gfx::CanvasSkia(icon.width(), icon.height(), false); |
| canvas->DrawBitmapInt(icon, 0, 0); |
| if (tab_id >= 0) { |
| - gfx::Rect bounds = |
| - gfx::Rect(icon.width(), icon.height() + kControlVertOffset); |
| - button_->extension()->browser_action()->PaintBadge(canvas, |
| - bounds, tab_id); |
| + gfx::Rect bounds(icon.width(), icon.height() + kControlVertOffset); |
| + button_->extension()->browser_action()->PaintBadge(canvas, bounds, tab_id); |
| } |
| return canvas; |
| @@ -350,17 +327,15 @@ |
| View::PaintChildren(canvas); |
| ExtensionAction* action = button()->browser_action(); |
| int tab_id = panel_->GetCurrentTabId(); |
| - if (tab_id < 0) |
| - return; |
| - |
| - action->PaintBadge(canvas, gfx::Rect(width(), height()), tab_id); |
| + if (tab_id >= 0) |
| + action->PaintBadge(canvas, gfx::Rect(width(), height()), tab_id); |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserActionsContainer |
| -BrowserActionsContainer::BrowserActionsContainer( |
| - Browser* browser, View* owner_view) |
| +BrowserActionsContainer::BrowserActionsContainer(Browser* browser, |
| + View* owner_view) |
| : profile_(browser->profile()), |
| browser_(browser), |
| owner_view_(owner_view), |
| @@ -381,6 +356,7 @@ |
| model_ = profile_->GetExtensionsService()->toolbar_model(); |
| model_->AddObserver(this); |
| } |
| + |
| resize_animation_.reset(new SlideAnimation(this)); |
| resize_area_ = new views::ResizeArea(this); |
| resize_area_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SEPARATOR)); |
| @@ -398,20 +374,17 @@ |
| chevron_->EnableCanvasFlippingForRTLUI(true); |
| AddChildView(chevron_); |
| - if (!profile_->GetPrefs()->HasPrefPath(prefs::kExtensionToolbarSize)) { |
| + if (model_ && |
| + !profile_->GetPrefs()->HasPrefPath(prefs::kExtensionToolbarSize)) { |
| // Migration code to the new VisibleIconCount pref. |
| // TODO(mpcomplete): remove this after users are upgraded to 5.0. |
| int predefined_width = |
| profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth); |
| if (predefined_width != 0) { |
| - int icon_width = (kButtonSize + kBrowserActionButtonPadding); |
| - if (model_) { |
| - model_->SetVisibleIconCount( |
| - (predefined_width - WidthOfNonIconArea()) / icon_width); |
| - } |
| + model_->SetVisibleIconCount((predefined_width - WidthOfNonIconArea()) / |
| + (kButtonSize + kBrowserActionButtonPadding)); |
| } |
| } |
| - |
| if (model_ && model_->extensions_initialized()) |
| SetContainerWidth(); |
| @@ -433,21 +406,16 @@ |
| int BrowserActionsContainer::GetCurrentTabId() const { |
| TabContents* tab_contents = browser_->GetSelectedTabContents(); |
| - if (!tab_contents) |
| - return -1; |
| - |
| - return tab_contents->controller().session_id().id(); |
| + return tab_contents ? tab_contents->controller().session_id().id() : -1; |
| } |
| BrowserActionView* BrowserActionsContainer::GetBrowserActionView( |
| ExtensionAction* action) { |
| - for (BrowserActionViews::iterator iter = |
| - browser_action_views_.begin(); iter != browser_action_views_.end(); |
| - ++iter) { |
| + for (BrowserActionViews::iterator iter = browser_action_views_.begin(); |
| + iter != browser_action_views_.end(); ++iter) { |
| if ((*iter)->button()->browser_action() == action) |
| return *iter; |
| } |
| - |
| return NULL; |
| } |
| @@ -456,46 +424,13 @@ |
| browser_action_views_[i]->button()->UpdateState(); |
| } |
| -void BrowserActionsContainer::CloseOverflowMenu() { |
| - if (overflow_menu_) |
| - overflow_menu_->CancelMenu(); |
| -} |
| - |
| -void BrowserActionsContainer::StopShowFolderDropMenuTimer() { |
| - show_menu_task_factory_.RevokeAll(); |
| -} |
| - |
| -void BrowserActionsContainer::StartShowFolderDropMenuTimer() { |
| - int delay = View::GetMenuShowDelay(); |
| - MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| - show_menu_task_factory_.NewRunnableMethod( |
| - &BrowserActionsContainer::ShowDropFolder), |
| - delay); |
| -} |
| - |
| -void BrowserActionsContainer::ShowDropFolder() { |
| - DCHECK(!overflow_menu_); |
| - SetDropIndicator(-1); |
| - overflow_menu_ = new BrowserActionOverflowMenuController( |
| - this, chevron_, browser_action_views_, VisibleBrowserActions()); |
| - overflow_menu_->set_observer(this); |
| - overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), true); |
| -} |
| - |
| -void BrowserActionsContainer::SetDropIndicator(int x_pos) { |
| - if (drop_indicator_position_ != x_pos) { |
| - drop_indicator_position_ = x_pos; |
| - SchedulePaint(); |
| - } |
| -} |
| - |
| void BrowserActionsContainer::CreateBrowserActionViews() { |
| DCHECK(browser_action_views_.empty()); |
| if (!model_) |
| return; |
| - for (ExtensionList::iterator iter = model_->begin(); |
| - iter != model_->end(); ++iter) { |
| + for (ExtensionList::iterator iter = model_->begin(); iter != model_->end(); |
| + ++iter) { |
| if (!ShouldDisplayBrowserAction(*iter)) |
| continue; |
| @@ -516,75 +451,61 @@ |
| } |
| void BrowserActionsContainer::OnBrowserActionVisibilityChanged() { |
| - SetVisible(browser_action_views_.size() > 0); |
| + SetVisible(!browser_action_views_.empty()); |
| owner_view_->Layout(); |
| owner_view_->SchedulePaint(); |
| } |
| -void BrowserActionsContainer::HidePopup() { |
| - if (popup_) |
| - popup_->Close(); |
| +size_t BrowserActionsContainer::VisibleBrowserActions() const { |
| + size_t visible_actions = 0; |
| + for (size_t i = 0; i < browser_action_views_.size(); ++i) { |
| + if (browser_action_views_[i]->IsVisible()) |
| + ++visible_actions; |
| + } |
| + return visible_actions; |
| } |
| -void BrowserActionsContainer::TestExecuteBrowserAction(int index) { |
| - BrowserActionButton* button = browser_action_views_[index]->button(); |
| - OnBrowserActionExecuted(button, false); // |inspect_with_devtools|. |
| -} |
| - |
| -void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) { |
| - chevron_->SetVisible(icons < browser_action_views_.size()); |
| - container_size_.set_width(IconCountToWidth(icons)); |
| - Layout(); |
| - SchedulePaint(); |
| -} |
| - |
| void BrowserActionsContainer::OnBrowserActionExecuted( |
| - BrowserActionButton* button, bool inspect_with_devtools) { |
| + BrowserActionButton* button, |
| + bool inspect_with_devtools) { |
| ExtensionAction* browser_action = button->browser_action(); |
| // Popups just display. No notification to the extension. |
| // TODO(erikkay): should there be? |
| - if (button->IsPopup()) { |
| - // If we're showing the same popup, just hide it and return. |
| - bool same_showing = popup_ && button == popup_button_; |
| + if (!button->IsPopup()) { |
| + ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted( |
| + profile_, browser_action->extension_id(), browser_); |
| + return; |
| + } |
| - // Always hide the current popup, even if it's not the same. |
| - // Only one popup should be visible at a time. |
| - HidePopup(); |
| + // If we're showing the same popup, just hide it and return. |
| + bool same_showing = popup_ && button == popup_button_; |
| - if (same_showing) |
| - return; |
| + // Always hide the current popup, even if it's not the same. |
| + // Only one popup should be visible at a time. |
| + HidePopup(); |
| - // We can get the execute event for browser actions that are not visible, |
| - // since buttons can be activated from the overflow menu (chevron). In that |
| - // case we show the popup as originating from the chevron. |
| - View* reference_view = button->GetParent()->IsVisible() ? button : chevron_; |
| - gfx::Point origin; |
| - View::ConvertPointToScreen(reference_view, &origin); |
| - gfx::Rect rect = reference_view->bounds(); |
| - rect.set_x(origin.x()); |
| - rect.set_y(origin.y()); |
| + if (same_showing) |
| + return; |
| - gfx::NativeWindow frame_window = |
| - browser_->window()->GetNativeHandle(); |
| - BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ? |
| - BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT; |
| + // We can get the execute event for browser actions that are not visible, |
| + // since buttons can be activated from the overflow menu (chevron). In that |
| + // case we show the popup as originating from the chevron. |
| + View* reference_view = button->GetParent()->IsVisible() ? button : chevron_; |
| + gfx::Point origin; |
| + View::ConvertPointToScreen(reference_view, &origin); |
| + gfx::Rect rect = reference_view->bounds(); |
| + rect.set_origin(origin); |
| - popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_, |
| - browser_->profile(), frame_window, rect, arrow_location, |
| - true, // Activate the popup window. |
| - inspect_with_devtools, |
| - ExtensionPopup::BUBBLE_CHROME, |
| - this); // ExtensionPopupDelegate |
|
Finnur
2010/07/27 09:02:23
nit: same question here (comment).
|
| - popup_button_ = button; |
| - popup_button_->SetButtonPushed(); |
| + gfx::NativeWindow frame_window = browser_->window()->GetNativeHandle(); |
| + BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ? |
| + BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT; |
| - return; |
| - } |
| - |
| - // Otherwise, we send the action to the extension. |
| - ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted( |
| - profile_, browser_action->extension_id(), browser_); |
| + popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_, |
| + browser_->profile(), frame_window, rect, arrow_location, true, |
| + inspect_with_devtools, ExtensionPopup::BUBBLE_CHROME, this); |
|
Finnur
2010/07/27 09:02:23
nit: same question here (comments deleted).
|
| + popup_button_ = button; |
| + popup_button_->SetButtonPushed(); |
| } |
| gfx::Size BrowserActionsContainer::GetPreferredSize() { |
| @@ -597,23 +518,20 @@ |
| // But we also clamp it to a minimum size and the maximum size, so that the |
| // container can never shrink too far or take up more space than it needs. In |
| // other words: ContainerMinSize() < width() - resize < ClampTo(MAX). |
| - int width = std::max(ContainerMinSize(), |
| - container_size_.width() - resize_amount_); |
| - int max_width = ClampToNearestIconCount(-1, false); // -1 gives max width. |
| - width = std::min(width, max_width); |
| - |
| - return gfx::Size(width, kButtonSize); |
| + return gfx::Size(std::min(std::max(ContainerMinSize(), |
| + container_width_ - resize_amount_), ClampToNearestIconCount(-1, false)), |
| + kButtonSize); |
|
Finnur
2010/07/27 09:02:23
I'm not a huge fan of this consolidation. The way
Peter Kasting
2010/07/27 18:24:43
I partly did this because the final form (after th
Finnur
2010/07/27 20:13:17
I think the last version (clamped_width) is a dece
|
| } |
| void BrowserActionsContainer::Layout() { |
| - if (browser_action_views_.size() == 0) { |
| + if (browser_action_views_.empty()) { |
| SetVisible(false); |
| chevron_->SetVisible(false); |
| return; |
| - } else { |
| - SetVisible(true); |
| } |
| + SetVisible(true); |
| + |
| resize_area_->SetBounds(0, 0, kResizeAreaWidth, height()); |
| int x = kResizeAreaWidth; |
| @@ -632,10 +550,9 @@ |
| int max_x = sz.width() - kDividerHorizontalMargin - kChevronRightMargin; |
| // If they don't all fit, show the chevron (unless suppressed). |
| - gfx::Size chevron_size; |
| if (last_x_of_icons >= max_x && !suppress_chevron_) { |
| chevron_->SetVisible(true); |
| - chevron_size = chevron_->GetPreferredSize(); |
| + gfx::Size chevron_size(chevron_->GetPreferredSize()); |
| max_x -= chevron_size.width(); |
| chevron_->SetBounds(width() - chevron_size.width() - kChevronRightMargin, |
| kChevronTopMargin, |
| @@ -670,16 +587,18 @@ |
| DetachableToolbarView::kMiddleDividerColor, |
| GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); |
| - // The two-pixel width drop indicator. |
| + // TODO(sky/glen): Instead of using a drop indicator, animate the icons while |
| + // dragging (like we do for tab dragging). |
| if (drop_indicator_position_ > -1) { |
| - x = drop_indicator_position_; |
| - int y = kDividerVerticalPadding; |
| - gfx::Rect indicator_bounds(x - kDropIndicatorWidth / 2, |
| - y, |
| - kDropIndicatorWidth, |
| - height() - (2 * kDividerVerticalPadding)); |
| + // The two-pixel width drop indicator. |
| + static const int kDropIndicatorWidth = 2; |
|
Finnur
2010/07/27 09:02:23
Is this here because the other one was moved? Just
Peter Kasting
2010/07/27 18:24:43
Since it's only used here it seemed clearer to jus
|
| + gfx::Rect indicator_bounds( |
| + drop_indicator_position_ - (kDropIndicatorWidth / 2), |
| + kDividerVerticalPadding, kDropIndicatorWidth, |
| + height() - (2 * kDividerVerticalPadding)); |
| - // TODO(sky/glen): make me pretty! |
| + // Color of the drop indicator. |
| + static const SkColor kDropIndicatorColor = SK_ColorBLACK; |
| canvas->FillRectInt(kDropIndicatorColor, indicator_bounds.x(), |
| indicator_bounds.y(), indicator_bounds.width(), |
| indicator_bounds.height()); |
| @@ -703,7 +622,8 @@ |
| } |
| bool BrowserActionsContainer::GetDropFormats( |
| - int* formats, std::set<OSExchangeData::CustomFormat>* custom_formats) { |
| + int* formats, |
| + std::set<OSExchangeData::CustomFormat>* custom_formats) { |
| custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat()); |
| return true; |
| @@ -715,9 +635,7 @@ |
| bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) { |
| BrowserActionDragData drop_data; |
| - if (!drop_data.Read(data)) |
| - return false; |
| - return drop_data.IsFromProfile(profile_); |
| + return drop_data.Read(data) ? drop_data.IsFromProfile(profile_) : false; |
| } |
| void BrowserActionsContainer::OnDragEntered( |
| @@ -731,9 +649,8 @@ |
| if (show_menu_task_factory_.empty() && !overflow_menu_) |
| StartShowFolderDropMenuTimer(); |
| return DragDropTypes::DRAG_MOVE; |
| - } else { |
| - StopShowFolderDropMenuTimer(); |
| } |
| + StopShowFolderDropMenuTimer(); |
| // Modifying the x value before clamping affects how far you have to drag to |
| // get the drop indicator to shift to another position. Modifying after |
| @@ -775,21 +692,17 @@ |
| return DragDropTypes::DRAG_NONE; |
| // Make sure we have the same view as we started with. |
| - DCHECK(browser_action_views_[data.index()]->button()->extension()->id() == |
| - data.id()); |
| + DCHECK_EQ(browser_action_views_[data.index()]->button()->extension()->id(), |
| + data.id()); |
| DCHECK(model_); |
| - Extension* dragging = |
| - browser_action_views_[data.index()]->button()->extension(); |
| - |
| - int target_x = drop_indicator_position_; |
| - |
| size_t i = 0; |
| for (; i < browser_action_views_.size(); ++i) { |
| int view_x = |
| browser_action_views_[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).x(); |
| if (!browser_action_views_[i]->IsVisible() || |
| - (base::i18n::IsRTL() ? view_x < target_x : view_x >= target_x)) { |
| + (base::i18n::IsRTL() ? (view_x < drop_indicator_position_) : |
| + (view_x >= drop_indicator_position_))) { |
| // We have reached the end of the visible icons or found one that has a |
| // higher x position than the drop point. |
| break; |
| @@ -807,7 +720,8 @@ |
| if (profile_->IsOffTheRecord()) |
| i = model_->IncognitoIndexToOriginal(i); |
| - model_->MoveBrowserAction(dragging, i); |
| + model_->MoveBrowserAction( |
| + browser_action_views_[data.index()]->button()->extension(), i); |
| OnDragExited(); // Perform clean up after dragging. |
| return DragDropTypes::DRAG_MOVE; |
| @@ -820,16 +734,6 @@ |
| return true; |
| } |
| -void BrowserActionsContainer::MoveBrowserAction( |
| - const std::string& extension_id, size_t new_index) { |
| - ExtensionsService* service = profile_->GetExtensionsService(); |
| - if (service) { |
| - Extension* extension = service->GetExtensionById(extension_id, false); |
| - model_->MoveBrowserAction(extension, new_index); |
| - SchedulePaint(); |
| - } |
| -} |
| - |
| void BrowserActionsContainer::RunMenu(View* source, const gfx::Point& pt) { |
| if (source == chevron_) { |
| overflow_menu_ = new BrowserActionOverflowMenuController( |
| @@ -873,43 +777,97 @@ |
| return true; |
| } |
| -int BrowserActionsContainer::ClampToNearestIconCount( |
| - int pixelWidth, bool allow_shrink_to_minimum) const { |
| - // Calculate the width of one icon. |
| - int icon_width = (kButtonSize + kBrowserActionButtonPadding); |
| +void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) { |
| + if (!done_resizing) { |
| + resize_amount_ = resize_amount; |
| + OnBrowserActionVisibilityChanged(); |
| + } else { |
| + // For details on why we do the following see the class comments in the |
| + // header. |
| - // Calculate pixel count for the area not used by the icons. |
| - int extras = WidthOfNonIconArea(); |
| + // Clamp lower limit to 0 and upper limit to the amount that allows enough |
| + // room for all icons to show. |
| + int new_width = std::max(0, container_width_ - resize_amount); |
| + int max_width = ClampToNearestIconCount(-1, false); |
| + new_width = std::min(new_width, max_width); |
| - size_t icon_count = 0u; |
| - if (pixelWidth >= 0) { |
| - // Caller wants to know how many icons fit within a given space so we start |
| - // by subtracting the padding, resize area and dividers. |
| - int icon_area = pixelWidth - extras; |
| - icon_area = std::max(0, icon_area); |
| + // Up until now we've only been modifying the resize_amount, but now it is |
| + // time to set the container size to the size we have resized to, but then |
| + // animate to the nearest icon count size (or down to min size if no icon). |
| + container_width_ = new_width; |
| + animation_target_size_ = ClampToNearestIconCount(new_width, true); |
| + resize_animation_->Reset(); |
| + resize_animation_->SetTweenType(Tween::EASE_OUT); |
| + resize_animation_->Show(); |
| + } |
| +} |
| - // Make sure we never throw an icon into the chevron menu just because |
| - // there isn't enough enough space for the invisible padding around buttons. |
| - icon_area += kBrowserActionButtonPadding - 1; |
| +void BrowserActionsContainer::AnimationProgressed(const Animation* animation) { |
| + DCHECK_EQ(resize_animation_.get(), animation); |
| + resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() * |
| + (container_width_ - animation_target_size_)); |
| + OnBrowserActionVisibilityChanged(); |
| +} |
| - // Count the number of icons that fit within that area. |
| - icon_count = icon_area / icon_width; |
| +void BrowserActionsContainer::AnimationEnded(const Animation* animation) { |
| + container_width_ = animation_target_size_; |
| + animation_target_size_ = 0; |
| + resize_amount_ = 0; |
| + OnBrowserActionVisibilityChanged(); |
| + suppress_chevron_ = false; |
| - if (icon_count == 0 && allow_shrink_to_minimum) { |
| - extras = ContainerMinSize(); // Allow very narrow width if no icons. |
| - } else if (icon_count > browser_action_views_.size()) { |
| - // No use allowing more than what we have. |
| - icon_count = browser_action_views_.size(); |
| - } |
| - } else { |
| - // A negative |pixels| count indicates caller wants to know the max width |
| - // that fits all icons; |
| - icon_count = browser_action_views_.size(); |
| + // Don't save the icon count in incognito because there may be fewer icons |
| + // in that mode. The result is that the container in a normal window is always |
| + // at least as wide as in an incognito window. |
| + if (!profile_->IsOffTheRecord()) |
| + model_->SetVisibleIconCount(VisibleBrowserActions()); |
| +} |
| + |
| +void BrowserActionsContainer::NotifyMenuDeleted( |
| + BrowserActionOverflowMenuController* controller) { |
| + DCHECK(controller == overflow_menu_); |
| + overflow_menu_ = NULL; |
| +} |
| + |
| +void BrowserActionsContainer::InspectPopup(ExtensionAction* action) { |
| + OnBrowserActionExecuted(GetBrowserActionView(action)->button(), true); |
| +} |
| + |
| +void BrowserActionsContainer::ExtensionPopupIsClosing(ExtensionPopup* popup) { |
| + // ExtensionPopup is ref-counted, so we don't need to delete it. |
| + DCHECK_EQ(popup_, popup); |
| + popup_ = NULL; |
| + popup_button_->SetButtonNotPushed(); |
| + popup_button_ = NULL; |
| +} |
| + |
| +void BrowserActionsContainer::MoveBrowserAction(const std::string& extension_id, |
| + size_t new_index) { |
| + ExtensionsService* service = profile_->GetExtensionsService(); |
| + if (service) { |
| + Extension* extension = service->GetExtensionById(extension_id, false); |
| + model_->MoveBrowserAction(extension, new_index); |
| + SchedulePaint(); |
| } |
| +} |
| - return extras + (icon_count * icon_width); |
| +void BrowserActionsContainer::HidePopup() { |
| + if (popup_) |
| + popup_->Close(); |
| } |
| +void BrowserActionsContainer::TestExecuteBrowserAction(int index) { |
| + BrowserActionButton* button = browser_action_views_[index]->button(); |
| + OnBrowserActionExecuted(button, false); // |inspect_with_devtools|. |
| +} |
| + |
| +void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) { |
| + chevron_->SetVisible(icons < browser_action_views_.size()); |
| + container_width_ = IconCountToWidth(icons); |
| + Layout(); |
| + SchedulePaint(); |
| +} |
| + |
| void BrowserActionsContainer::BrowserActionAdded(Extension* extension, |
| int index) { |
| #if defined(DEBUG) |
| @@ -924,13 +882,12 @@ |
| if (!ShouldDisplayBrowserAction(extension)) |
| return; |
| - if (profile_->IsOffTheRecord()) |
| - index = model_->OriginalIndexToIncognito(index); |
| - |
| - // Before we change anything, determine the number of visible browser actions. |
| size_t visible_actions = VisibleBrowserActions(); |
| // Add the new browser action to the vector and the view hierarchy. |
| + if (profile_->IsOffTheRecord()) |
| + index = model_->OriginalIndexToIncognito(index); |
| + |
| BrowserActionView* view = new BrowserActionView(extension, this); |
| browser_action_views_.insert(browser_action_views_.begin() + index, view); |
| AddChildView(index, view); |
| @@ -965,13 +922,9 @@ |
| if (popup_ && popup_->host()->extension() == extension) |
| HidePopup(); |
| - // Before we change anything, determine the number of visible browser |
| - // actions. |
| size_t visible_actions = VisibleBrowserActions(); |
| - |
| - for (BrowserActionViews::iterator iter = |
| - browser_action_views_.begin(); iter != browser_action_views_.end(); |
| - ++iter) { |
| + for (BrowserActionViews::iterator iter = browser_action_views_.begin(); |
| + iter != browser_action_views_.end(); ++iter) { |
| if ((*iter)->button()->extension() == extension) { |
| RemoveChildView(*iter); |
| delete *iter; |
| @@ -1023,11 +976,81 @@ |
| int visible_actions = model_->GetVisibleIconCount(); |
| if (visible_actions < 0) // All icons should be visible. |
| visible_actions = model_->size(); |
| - else |
| - chevron_->SetVisible(true); |
| - container_size_ = gfx::Size(IconCountToWidth(visible_actions), kButtonSize); |
| + chevron_->SetVisible(static_cast<size_t>(visible_actions) < model_->size()); |
| + container_width_ = IconCountToWidth(visible_actions); |
| } |
| +void BrowserActionsContainer::CloseOverflowMenu() { |
| + if (overflow_menu_) |
| + overflow_menu_->CancelMenu(); |
| +} |
| + |
| +void BrowserActionsContainer::StopShowFolderDropMenuTimer() { |
| + show_menu_task_factory_.RevokeAll(); |
| +} |
| + |
| +void BrowserActionsContainer::StartShowFolderDropMenuTimer() { |
| + int delay = View::GetMenuShowDelay(); |
| + MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| + show_menu_task_factory_.NewRunnableMethod( |
| + &BrowserActionsContainer::ShowDropFolder), |
| + delay); |
| +} |
| + |
| +void BrowserActionsContainer::ShowDropFolder() { |
| + DCHECK(!overflow_menu_); |
| + SetDropIndicator(-1); |
| + overflow_menu_ = new BrowserActionOverflowMenuController( |
| + this, chevron_, browser_action_views_, VisibleBrowserActions()); |
| + overflow_menu_->set_observer(this); |
| + overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), true); |
| +} |
| + |
| +void BrowserActionsContainer::SetDropIndicator(int x_pos) { |
| + if (drop_indicator_position_ != x_pos) { |
| + drop_indicator_position_ = x_pos; |
| + SchedulePaint(); |
| + } |
| +} |
| + |
| +int BrowserActionsContainer::ClampToNearestIconCount( |
| + int pixelWidth, |
| + bool allow_shrink_to_minimum) const { |
| + // Calculate the width of one icon. |
| + int icon_width = (kButtonSize + kBrowserActionButtonPadding); |
| + |
| + // Calculate pixel count for the area not used by the icons. |
| + int extras = WidthOfNonIconArea(); |
| + |
| + size_t icon_count = 0u; |
| + if (pixelWidth >= 0) { |
| + // Caller wants to know how many icons fit within a given space so we start |
| + // by subtracting the padding, resize area and dividers. |
| + int icon_area = pixelWidth - extras; |
| + icon_area = std::max(0, icon_area); |
| + |
| + // Make sure we never throw an icon into the chevron menu just because |
| + // there isn't enough enough space for the invisible padding around buttons. |
| + icon_area += kBrowserActionButtonPadding - 1; |
| + |
| + // Count the number of icons that fit within that area. |
| + icon_count = icon_area / icon_width; |
| + |
| + if (icon_count == 0 && allow_shrink_to_minimum) { |
| + extras = ContainerMinSize(); // Allow very narrow width if no icons. |
| + } else if (icon_count > browser_action_views_.size()) { |
| + // No use allowing more than what we have. |
| + icon_count = browser_action_views_.size(); |
| + } |
| + } else { |
| + // A negative |pixels| count indicates caller wants to know the max width |
| + // that fits all icons; |
| + icon_count = browser_action_views_.size(); |
| + } |
| + |
| + return extras + (icon_count * icon_width); |
| +} |
| + |
| int BrowserActionsContainer::WidthOfNonIconArea() const { |
| int chevron_size = (chevron_->IsVisible()) ? |
| chevron_->GetPreferredSize().width() : 0; |
| @@ -1065,86 +1088,6 @@ |
| } |
| } |
| -size_t BrowserActionsContainer::VisibleBrowserActions() const { |
| - size_t visible_actions = 0; |
| - for (size_t i = 0; i < browser_action_views_.size(); ++i) { |
| - if (browser_action_views_[i]->IsVisible()) |
| - ++visible_actions; |
| - } |
| - |
| - return visible_actions; |
| -} |
| - |
| -void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) { |
| - if (!done_resizing) { |
| - resize_amount_ = resize_amount; |
| - OnBrowserActionVisibilityChanged(); |
| - } else { |
| - // For details on why we do the following see the class comments in the |
| - // header. |
| - |
| - // Clamp lower limit to 0 and upper limit to the amount that allows enough |
| - // room for all icons to show. |
| - int new_width = std::max(0, container_size_.width() - resize_amount); |
| - int max_width = ClampToNearestIconCount(-1, false); |
| - new_width = std::min(new_width, max_width); |
| - |
| - // Up until now we've only been modifying the resize_amount, but now it is |
| - // time to set the container size to the size we have resized to, but then |
| - // animate to the nearest icon count size (or down to min size if no icon). |
| - container_size_.set_width(new_width); |
| - animation_target_size_ = ClampToNearestIconCount(new_width, true); |
| - resize_animation_->Reset(); |
| - resize_animation_->SetTweenType(Tween::EASE_OUT); |
| - resize_animation_->Show(); |
| - } |
| -} |
| - |
| -void BrowserActionsContainer::AnimationProgressed(const Animation* animation) { |
| - DCHECK(animation == resize_animation_.get()); |
| - |
| - double e = resize_animation_->GetCurrentValue(); |
| - int difference = container_size_.width() - animation_target_size_; |
| - |
| - resize_amount_ = static_cast<int>(e * difference); |
| - |
| - OnBrowserActionVisibilityChanged(); |
| -} |
| - |
| -void BrowserActionsContainer::AnimationEnded(const Animation* animation) { |
| - container_size_.set_width(animation_target_size_); |
| - animation_target_size_ = 0; |
| - resize_amount_ = 0; |
| - OnBrowserActionVisibilityChanged(); |
| - suppress_chevron_ = false; |
| - |
| - // Don't save the icon count in incognito because there may be fewer icons |
| - // in that mode. The result is that the container in a normal window is always |
| - // at least as wide as in an incognito window. |
| - if (!profile_->IsOffTheRecord()) |
| - model_->SetVisibleIconCount(VisibleBrowserActions()); |
| -} |
| - |
| -void BrowserActionsContainer::NotifyMenuDeleted( |
| - BrowserActionOverflowMenuController* controller) { |
| - DCHECK(controller == overflow_menu_); |
| - overflow_menu_ = NULL; |
| -} |
| - |
| -void BrowserActionsContainer::InspectPopup( |
| - ExtensionAction* action) { |
| - OnBrowserActionExecuted(GetBrowserActionView(action)->button(), |
| - true); // |inspect_with_devtools|. |
| -} |
| - |
| -void BrowserActionsContainer::ExtensionPopupIsClosing(ExtensionPopup* popup) { |
| - // ExtensionPopup is ref-counted, so we don't need to delete it. |
| - DCHECK_EQ(popup_, popup); |
| - popup_ = NULL; |
| - popup_button_->SetButtonNotPushed(); |
| - popup_button_ = NULL; |
| -} |
| - |
| bool BrowserActionsContainer::ShouldDisplayBrowserAction(Extension* extension) { |
| // Only display incognito-enabled extensions while in incognito mode. |
| return (!profile_->IsOffTheRecord() || |