| Index: chrome/browser/views/browser_actions_container.cc
|
| ===================================================================
|
| --- chrome/browser/views/browser_actions_container.cc (revision 54017)
|
| +++ chrome/browser/views/browser_actions_container.cc (working copy)
|
| @@ -24,6 +24,7 @@
|
| #include "chrome/browser/views/detachable_toolbar_view.h"
|
| #include "chrome/browser/views/extensions/browser_action_drag_data.h"
|
| #include "chrome/browser/views/extensions/extension_popup.h"
|
| +#include "chrome/browser/views/toolbar_view.h"
|
| #include "chrome/common/extensions/extension_action.h"
|
| #include "chrome/common/extensions/extension_resource.h"
|
| #include "chrome/common/notification_source.h"
|
| @@ -44,47 +45,13 @@
|
|
|
| #include "grit/theme_resources.h"
|
|
|
| -namespace {
|
| +// Horizontal spacing between most items in the container, as well as after the
|
| +// last item or chevron (if visible).
|
| +static const int kItemSpacing = ToolbarView::kStandardSpacing;
|
| +// Horizontal spacing before the chevron (if visible).
|
| +static const int kChevronSpacing = kItemSpacing - 2;
|
|
|
| -// The size (both dimensions) of the buttons for page actions.
|
| -static const int kButtonSize = 29;
|
| -
|
| -// The padding between the browser actions and the OmniBox/page menu.
|
| -static const int kHorizontalPadding = 4;
|
| -static const int kHorizontalPaddingRtl = 8;
|
| -
|
| -// The padding between browser action buttons. Visually, the actual number of
|
| -// empty (non-drawing) pixels is this value + 2 when adjacent browser icons
|
| -// use their maximum allowed size.
|
| -static const int kBrowserActionButtonPadding = 3;
|
| -
|
| -// This is the same value from toolbar.cc. We position the browser actions
|
| -// container flush with the edges of the toolbar as a special case so that we
|
| -// can draw the badge outside the visual bounds of the container.
|
| -static const int kControlVertOffset = 6;
|
| -
|
| -// The margin between the divider and the chrome menu buttons.
|
| -static const int kDividerHorizontalMargin = 2;
|
| -
|
| -// The padding above and below the divider.
|
| -static const int kDividerVerticalPadding = 9;
|
| -
|
| -// The margin above the chevron.
|
| -static const int kChevronTopMargin = 9;
|
| -
|
| -// The margin to the right of the chevron.
|
| -static const int kChevronRightMargin = 4;
|
| -
|
| -// Width for the resize area.
|
| -static const int kResizeAreaWidth = 4;
|
| -
|
| -// The x offset for the drop indicator (how much we shift it by).
|
| -static const int kDropIndicatorOffsetLtr = 3;
|
| -static const int kDropIndicatorOffsetRtl = 9;
|
| -
|
| -} // namespace.
|
| -
|
| -// Static.
|
| +// static
|
| bool BrowserActionsContainer::disable_animations_during_testing_ = false;
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -99,6 +66,7 @@
|
| ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)),
|
| showing_context_menu_(false),
|
| panel_(panel) {
|
| + set_border(NULL);
|
| set_alignment(TextButton::ALIGN_CENTER);
|
|
|
| // No UpdateState() here because View hierarchy not setup yet. Our parent
|
| @@ -154,12 +122,41 @@
|
| if (tab_id < 0)
|
| return;
|
|
|
| - SkBitmap image = browser_action()->GetIcon(tab_id);
|
| - if (!image.isNull())
|
| - SetIcon(image);
|
| - else if (!default_icon_.isNull())
|
| - SetIcon(default_icon_);
|
| + SkBitmap icon(browser_action()->GetIcon(tab_id));
|
| + if (icon.isNull())
|
| + icon = default_icon_;
|
| + if (!icon.isNull()) {
|
| + SkPaint paint;
|
| + paint.setXfermode(SkXfermode::Create(SkXfermode::kSrcOver_Mode));
|
| + ResourceBundle& rb = ResourceBundle::GetSharedInstance();
|
|
|
| + SkBitmap bg;
|
| + rb.GetBitmapNamed(IDR_BROWSER_ACTION)->copyTo(&bg,
|
| + SkBitmap::kARGB_8888_Config);
|
| + SkCanvas bg_canvas(bg);
|
| + bg_canvas.drawBitmap(icon, SkIntToScalar((bg.width() - icon.width()) / 2),
|
| + SkIntToScalar((bg.height() - icon.height()) / 2), &paint);
|
| + SetIcon(bg);
|
| +
|
| + SkBitmap bg_h;
|
| + rb.GetBitmapNamed(IDR_BROWSER_ACTION_H)->copyTo(&bg_h,
|
| + SkBitmap::kARGB_8888_Config);
|
| + SkCanvas bg_h_canvas(bg_h);
|
| + bg_h_canvas.drawBitmap(icon,
|
| + SkIntToScalar((bg_h.width() - icon.width()) / 2),
|
| + SkIntToScalar((bg_h.height() - icon.height()) / 2), &paint);
|
| + SetHoverIcon(bg_h);
|
| +
|
| + SkBitmap bg_p;
|
| + rb.GetBitmapNamed(IDR_BROWSER_ACTION_P)->copyTo(&bg_p,
|
| + SkBitmap::kARGB_8888_Config);
|
| + SkCanvas bg_p_canvas(bg_p);
|
| + bg_p_canvas.drawBitmap(icon,
|
| + SkIntToScalar((bg_p.width() - icon.width()) / 2),
|
| + SkIntToScalar((bg_p.height() - icon.height()) / 2), &paint);
|
| + SetPushedIcon(bg_p);
|
| + }
|
| +
|
| // If the browser action name is empty, show the extension name instead.
|
| std::wstring name = UTF8ToWide(browser_action()->GetTitle(tab_id));
|
| if (name.empty())
|
| @@ -195,7 +192,7 @@
|
| if (!IsPopup())
|
| return true;
|
|
|
| - panel_->OnBrowserActionExecuted(this, false); // |inspect_with_devtools|.
|
| + panel_->OnBrowserActionExecuted(this, false);
|
|
|
| // TODO(erikkay): Run a nested modal loop while the mouse is down to
|
| // enable menu-like drag-select behavior.
|
| @@ -306,7 +303,7 @@
|
| canvas->DrawBitmapInt(icon, 0, 0);
|
|
|
| if (tab_id >= 0) {
|
| - gfx::Rect bounds(icon.width(), icon.height() + kControlVertOffset);
|
| + gfx::Rect bounds(icon.width(), icon.height() + ToolbarView::kVertSpacing);
|
| button_->extension()->browser_action()->PaintBadge(canvas, bounds, tab_id);
|
| }
|
|
|
| @@ -320,7 +317,15 @@
|
| }
|
|
|
| void BrowserActionView::Layout() {
|
| - button_->SetBounds(0, kControlVertOffset, width(), kButtonSize);
|
| + // We can't rely on button_->GetPreferredSize() here because that's not set
|
| + // correctly until the first call to
|
| + // BrowserActionsContainer::RefreshBrowserActionViews(), whereas this can be
|
| + // called before that when the initial bounds are set (and then not after,
|
| + // since the bounds don't change). So instead of setting the height from the
|
| + // button's preferred size, we use IconHeight(), since that's how big the
|
| + // button should be regardless of what it's displaying.
|
| + button_->SetBounds(0, ToolbarView::kVertSpacing, width(),
|
| + BrowserActionsContainer::IconHeight());
|
| }
|
|
|
| void BrowserActionView::PaintChildren(gfx::Canvas* canvas) {
|
| @@ -342,6 +347,7 @@
|
| popup_(NULL),
|
| popup_button_(NULL),
|
| model_(NULL),
|
| + container_width_(0),
|
| chevron_(NULL),
|
| overflow_menu_(NULL),
|
| suppress_chevron_(false),
|
| @@ -362,32 +368,14 @@
|
| resize_area_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SEPARATOR));
|
| AddChildView(resize_area_);
|
|
|
| - // TODO(glen): Come up with a new bitmap for the chevron.
|
| - ResourceBundle& rb = ResourceBundle::GetSharedInstance();
|
| - SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS);
|
| chevron_ = new views::MenuButton(NULL, std::wstring(), this, false);
|
| - chevron_->SetVisible(false);
|
| - chevron_->SetIcon(*chevron_image);
|
| + chevron_->set_border(NULL);
|
| + chevron_->EnableCanvasFlippingForRTLUI(true);
|
| chevron_->SetAccessibleName(
|
| l10n_util::GetString(IDS_ACCNAME_EXTENSIONS_CHEVRON));
|
| - // Chevron contains >> that should point left in LTR locales.
|
| - chevron_->EnableCanvasFlippingForRTLUI(true);
|
| + chevron_->SetVisible(false);
|
| AddChildView(chevron_);
|
|
|
| - 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) {
|
| - model_->SetVisibleIconCount((predefined_width - WidthOfNonIconArea()) /
|
| - (kButtonSize + kBrowserActionButtonPadding));
|
| - }
|
| - }
|
| - if (model_ && model_->extensions_initialized())
|
| - SetContainerWidth();
|
| -
|
| SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_EXTENSIONS));
|
| }
|
|
|
| @@ -404,6 +392,24 @@
|
| prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0);
|
| }
|
|
|
| +void BrowserActionsContainer::Init() {
|
| + LoadImages();
|
| +
|
| + // We wait to set the container width until now so that the chevron images
|
| + // will be loaded. The width calculation needs to know the chevron size.
|
| + 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)
|
| + model_->SetVisibleIconCount(WidthToIconCount(predefined_width));
|
| + }
|
| + if (model_ && model_->extensions_initialized())
|
| + SetContainerWidth();
|
| +}
|
| +
|
| int BrowserActionsContainer::GetCurrentTabId() const {
|
| TabContents* tab_contents = browser_->GetSelectedTabContents();
|
| return tab_contents ? tab_contents->controller().session_id().id() : -1;
|
| @@ -510,7 +516,7 @@
|
|
|
| gfx::Size BrowserActionsContainer::GetPreferredSize() {
|
| if (browser_action_views_.empty())
|
| - return gfx::Size(0, 0);
|
| + return gfx::Size(ToolbarView::kStandardSpacing, 0);
|
|
|
| // We calculate the size of the view by taking the current width and
|
| // subtracting resize_amount_ (the latter represents how far the user is
|
| @@ -520,58 +526,42 @@
|
| // other words: ContainerMinSize() < width() - resize < ClampTo(MAX).
|
| int clamped_width = std::min(
|
| std::max(ContainerMinSize(), container_width_ - resize_amount_),
|
| - ClampToNearestIconCount(-1, false));
|
| - return gfx::Size(clamped_width, kButtonSize);
|
| + IconCountToWidth(-1, false));
|
| + return gfx::Size(clamped_width, 0);
|
| }
|
|
|
| void BrowserActionsContainer::Layout() {
|
| if (browser_action_views_.empty()) {
|
| SetVisible(false);
|
| - chevron_->SetVisible(false);
|
| return;
|
| }
|
|
|
| SetVisible(true);
|
| + resize_area_->SetBounds(0, ToolbarView::kVertSpacing, kItemSpacing,
|
| + IconHeight());
|
|
|
| - resize_area_->SetBounds(0, 0, kResizeAreaWidth, height());
|
| - int x = kResizeAreaWidth;
|
| -
|
| - x += base::i18n::IsRTL() ? kHorizontalPaddingRtl : kHorizontalPadding;
|
| -
|
| - // Calculate if all icons fit without showing the chevron. We need to know
|
| - // this beforehand, because showing the chevron will decrease the space that
|
| - // we have to draw the visible ones (ie. if one icon is visible and another
|
| - // doesn't have enough room).
|
| - int last_x_of_icons = x +
|
| - (browser_action_views_.size() * kButtonSize) +
|
| - ((browser_action_views_.size() - 1) *
|
| - kBrowserActionButtonPadding);
|
| -
|
| - gfx::Size sz = GetPreferredSize();
|
| - int max_x = sz.width() - kDividerHorizontalMargin - kChevronRightMargin;
|
| -
|
| - // If they don't all fit, show the chevron (unless suppressed).
|
| - if (last_x_of_icons >= max_x && !suppress_chevron_) {
|
| + // If the icons don't all fit, show the chevron (unless suppressed).
|
| + int max_x = GetPreferredSize().width();
|
| + if ((IconCountToWidth(-1, false) > max_x) && !suppress_chevron_) {
|
| chevron_->SetVisible(true);
|
| gfx::Size chevron_size(chevron_->GetPreferredSize());
|
| - max_x -= chevron_size.width();
|
| - chevron_->SetBounds(width() - chevron_size.width() - kChevronRightMargin,
|
| - kChevronTopMargin,
|
| - chevron_size.width(), chevron_size.height());
|
| + max_x -=
|
| + ToolbarView::kStandardSpacing + chevron_size.width() + kChevronSpacing;
|
| + chevron_->SetBounds(
|
| + width() - ToolbarView::kStandardSpacing - chevron_size.width(),
|
| + ToolbarView::kVertSpacing, chevron_size.width(), chevron_size.height());
|
| } else {
|
| chevron_->SetVisible(false);
|
| }
|
|
|
| // Now draw the icons for the browser actions in the available space.
|
| + int icon_width = IconWidth(false);
|
| for (size_t i = 0; i < browser_action_views_.size(); ++i) {
|
| BrowserActionView* view = browser_action_views_[i];
|
| - // Add padding between buttons if multiple buttons.
|
| - int padding = (i > 0) ? kBrowserActionButtonPadding : 0;
|
| - if (x + kButtonSize + padding < max_x) {
|
| - x += padding;
|
| - view->SetBounds(x, 0, kButtonSize, height());
|
| + int x = ToolbarView::kStandardSpacing + (i * IconWidth(true));
|
| + if (x + icon_width <= max_x) {
|
| + view->SetBounds(x, 0, icon_width, height());
|
| view->SetVisible(true);
|
| - x += kButtonSize;
|
| } else {
|
| view->SetVisible(false);
|
| }
|
| @@ -579,15 +569,6 @@
|
| }
|
|
|
| void BrowserActionsContainer::Paint(gfx::Canvas* canvas) {
|
| - // The one-pixel themed vertical divider to the right of the browser actions.
|
| - int x = base::i18n::IsRTL() ?
|
| - kDividerHorizontalMargin : (width() - kDividerHorizontalMargin);
|
| - DetachableToolbarView::PaintVerticalDivider(
|
| - canvas, x, height(), kDividerVerticalPadding,
|
| - DetachableToolbarView::kEdgeDividerColor,
|
| - DetachableToolbarView::kMiddleDividerColor,
|
| - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR));
|
| -
|
| // 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) {
|
| @@ -595,8 +576,7 @@
|
| static const int kDropIndicatorWidth = 2;
|
| gfx::Rect indicator_bounds(
|
| drop_indicator_position_ - (kDropIndicatorWidth / 2),
|
| - kDividerVerticalPadding, kDropIndicatorWidth,
|
| - height() - (2 * kDividerVerticalPadding));
|
| + ToolbarView::kVertSpacing, kDropIndicatorWidth, IconHeight());
|
|
|
| // Color of the drop indicator.
|
| static const SkColor kDropIndicatorColor = SK_ColorBLACK;
|
| @@ -653,30 +633,52 @@
|
| }
|
| 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
|
| - // clamping affects where the drop indicator is drawn.
|
| + // Figure out where to display the indicator. This is a complex calculation:
|
|
|
| - // We add half a button size so that when you drag a button to the right and
|
| - // you are half-way dragging across a button the drop indicator moves from the
|
| - // left of that button to the right of that button.
|
| - int x = event.x() + (kButtonSize / 2) + (2 * kBrowserActionButtonPadding);
|
| - if (chevron_->IsVisible())
|
| - x += chevron_->bounds().width();
|
| - x = ClampToNearestIconCount(x, false);
|
| + // First, we figure out how much space is to the left of the icon area, so we
|
| + // can calculate the true offset into the icon area.
|
| + int width_before_icons = ToolbarView::kStandardSpacing +
|
| + (base::i18n::IsRTL() ?
|
| + (chevron_->GetPreferredSize().width() + kChevronSpacing) : 0);
|
| + int offset_into_icon_area = event.x() - width_before_icons;
|
|
|
| - if (!base::i18n::IsRTL() && chevron_->IsVisible()) {
|
| - // The clamping function includes the chevron width. In LTR locales, the
|
| - // chevron is on the right and we never want to account for its width. In
|
| - // RTL it is on the left and we always want to count the width.
|
| - x -= chevron_->width();
|
| - }
|
| + // Next, we determine which icon to place the indicator in front of. We want
|
| + // to place the indicator in front of icon n when the cursor is between the
|
| + // midpoints of icons (n - 1) and n. To do this we take the offset into the
|
| + // icon area and transform it as follows:
|
| + //
|
| + // Real icon area:
|
| + // 0 a * b c
|
| + // | | | |
|
| + // |[IC|ON] [IC|ON] [IC|ON]
|
| + // We want to be before icon 0 for 0 < x <= a, icon 1 for a < x <= b, etc.
|
| + // Here the "*" represents the offset into the icon area, and since it's
|
| + // between a and b, we want to return "1".
|
| + //
|
| + // Transformed "icon area":
|
| + // 0 a * b c
|
| + // | | | |
|
| + // |[ICON] |[ICON] |[ICON] |
|
| + // If we shift both our offset and our divider points later by half an icon
|
| + // plus one spacing unit, then it becomes very easy to calculate how many
|
| + // divider points we've passed, because they're the multiples of "one icon
|
| + // plus padding".
|
| + int before_icon_unclamped = (offset_into_icon_area + (IconWidth(false) / 2) +
|
| + kItemSpacing) / IconWidth(true);
|
|
|
| - // Clamping gives us a value where the next button will be drawn, but we want
|
| - // to subtract the padding (and then some) to make it appear in-between the
|
| - // buttons.
|
| - SetDropIndicator(x - kBrowserActionButtonPadding - (base::i18n::IsRTL() ?
|
| - kDropIndicatorOffsetRtl : kDropIndicatorOffsetLtr));
|
| + // Because the user can drag outside the container bounds, we need to clamp to
|
| + // the valid range. Note that the maximum allowable value is (num icons), not
|
| + // (num icons - 1), because we represent the indicator being past the last
|
| + // icon as being "before the (last + 1) icon".
|
| + int before_icon = std::min(std::max(before_icon_unclamped, 0),
|
| + static_cast<int>(VisibleBrowserActions()));
|
| +
|
| + // Now we convert back to a pixel offset into the container. We want to place
|
| + // the center of the drop indicator at the midpoint of the space before our
|
| + // chosen icon.
|
| + SetDropIndicator(width_before_icons + (before_icon * IconWidth(true)) -
|
| + (kItemSpacing / 2));
|
| +
|
| return DragDropTypes::DRAG_MOVE;
|
| }
|
|
|
| @@ -728,6 +730,10 @@
|
| return DragDropTypes::DRAG_MOVE;
|
| }
|
|
|
| +void BrowserActionsContainer::OnThemeChanged() {
|
| + LoadImages();
|
| +}
|
| +
|
| bool BrowserActionsContainer::GetAccessibleRole(
|
| AccessibilityTypes::Role* role) {
|
| DCHECK(role);
|
| @@ -779,28 +785,25 @@
|
| }
|
|
|
| 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_width_ - resize_amount);
|
| - int max_width = ClampToNearestIconCount(-1, false);
|
| - new_width = std::min(new_width, max_width);
|
| -
|
| + if (done_resizing) {
|
| // 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();
|
| + // time to set the container size to the size we have resized to, and then
|
| + // animate to the nearest icon count size if necessary (which may be 0).
|
| + int max_width = IconCountToWidth(-1, false);
|
| + container_width_ =
|
| + std::min(std::max(0, container_width_ - resize_amount), max_width);
|
| + if (container_width_ < max_width) {
|
| + animation_target_size_ =
|
| + IconCountToWidth(WidthToIconCount(container_width_), true);
|
| + resize_animation_->Reset();
|
| + resize_animation_->SetTweenType(Tween::EASE_OUT);
|
| + resize_animation_->Show();
|
| + return;
|
| + }
|
| + } else {
|
| + resize_amount_ = resize_amount;
|
| }
|
| + OnBrowserActionVisibilityChanged();
|
| }
|
|
|
| void BrowserActionsContainer::AnimationProgressed(const Animation* animation) {
|
| @@ -859,16 +862,41 @@
|
|
|
| void BrowserActionsContainer::TestExecuteBrowserAction(int index) {
|
| BrowserActionButton* button = browser_action_views_[index]->button();
|
| - OnBrowserActionExecuted(button, false); // |inspect_with_devtools|.
|
| + OnBrowserActionExecuted(button, false);
|
| }
|
|
|
| void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) {
|
| + model_->SetVisibleIconCount(icons);
|
| chevron_->SetVisible(icons < browser_action_views_.size());
|
| - container_width_ = IconCountToWidth(icons);
|
| + container_width_ = IconCountToWidth(icons, chevron_->IsVisible());
|
| Layout();
|
| SchedulePaint();
|
| }
|
|
|
| +// static
|
| +int BrowserActionsContainer::IconWidth(bool include_padding) {
|
| + static bool initialized = false;
|
| + static int icon_width = 0;
|
| + if (!initialized) {
|
| + initialized = true;
|
| + icon_width = ResourceBundle::GetSharedInstance().GetBitmapNamed(
|
| + IDR_BROWSER_ACTION)->width();
|
| + }
|
| + return icon_width + (include_padding ? kItemSpacing : 0);
|
| +}
|
| +
|
| +// static
|
| +int BrowserActionsContainer::IconHeight() {
|
| + static bool initialized = false;
|
| + static int icon_height = 0;
|
| + if (!initialized) {
|
| + initialized = true;
|
| + icon_height = ResourceBundle::GetSharedInstance().GetBitmapNamed(
|
| + IDR_BROWSER_ACTION)->height();
|
| + }
|
| + return icon_height;
|
| +}
|
| +
|
| void BrowserActionsContainer::BrowserActionAdded(Extension* extension,
|
| int index) {
|
| #if defined(DEBUG)
|
| @@ -888,7 +916,6 @@
|
| // 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);
|
| @@ -897,23 +924,15 @@
|
| if (!model_->extensions_initialized())
|
| return;
|
|
|
| - // For details on why we do the following see the class comments in the
|
| - // header.
|
| -
|
| - // Determine if we need to increase (we only do that if the container was
|
| - // showing all icons before the addition of this icon).
|
| - if (model_->GetVisibleIconCount() >= 0 || extension->being_upgraded()) {
|
| - // Some icons were hidden, don't increase the size of the container.
|
| - OnBrowserActionVisibilityChanged();
|
| - } else {
|
| - // Container was at max, increase the size of it by one icon.
|
| - int target_size = IconCountToWidth(visible_actions + 1);
|
| -
|
| - // We don't want the chevron to appear while we animate. See documentation
|
| - // in the header for why we do this.
|
| - suppress_chevron_ = !chevron_->IsVisible();
|
| -
|
| + // Enlarge the container if it was already at maximum size and we're not in
|
| + // the middle of upgrading.
|
| + if ((model_->GetVisibleIconCount() < 0) && !extension->being_upgraded()) {
|
| + int target_size = IconCountToWidth(visible_actions + 1, false);
|
| + suppress_chevron_ = true;
|
| Animate(Tween::LINEAR, target_size);
|
| + } else {
|
| + // Just redraw the (possibly modified) visible icon set.
|
| + OnBrowserActionVisibilityChanged();
|
| }
|
| }
|
|
|
| @@ -936,18 +955,18 @@
|
| if (extension->being_upgraded())
|
| return;
|
|
|
| - // For details on why we do the following see the class comments in the
|
| - // header.
|
| -
|
| - // Calculate the target size we'll animate to (end state). This might be
|
| - // the same size (if the icon we are removing is in the overflow bucket
|
| - // and there are other icons there). We don't decrement visible_actions
|
| - // because we want the container to stay the same size (clamping will take
|
| - // care of shrinking the container if there aren't enough icons to show).
|
| - int target_size =
|
| - ClampToNearestIconCount(IconCountToWidth(visible_actions), true);
|
| -
|
| - Animate(Tween::EASE_OUT, target_size);
|
| + if (browser_action_views_.size() > visible_actions) {
|
| + // If we have more icons than we can show, then we must not be changing
|
| + // the container size (since we either removed an icon from the main
|
| + // area and one from the overflow list will have shifted in, or we
|
| + // removed an entry directly from the overflow list).
|
| + OnBrowserActionVisibilityChanged();
|
| + } else {
|
| + // Either we went from overflow to no-overflow, or we shrunk the no-
|
| + // overflow container by 1. Either way the size changed, so animate.
|
| + chevron_->SetVisible(false);
|
| + Animate(Tween::EASE_OUT, IconCountToWidth(-1, false));
|
| + }
|
| return;
|
| }
|
| }
|
| @@ -973,12 +992,19 @@
|
| SetContainerWidth();
|
| }
|
|
|
| +void BrowserActionsContainer::LoadImages() {
|
| + ThemeProvider* tp = GetThemeProvider();
|
| + chevron_->SetIcon(*tp->GetBitmapNamed(IDR_BROWSER_ACTIONS_OVERFLOW));
|
| + chevron_->SetHoverIcon(*tp->GetBitmapNamed(IDR_BROWSER_ACTIONS_OVERFLOW_H));
|
| + chevron_->SetPushedIcon(*tp->GetBitmapNamed(IDR_BROWSER_ACTIONS_OVERFLOW_P));
|
| +}
|
| +
|
| void BrowserActionsContainer::SetContainerWidth() {
|
| int visible_actions = model_->GetVisibleIconCount();
|
| if (visible_actions < 0) // All icons should be visible.
|
| visible_actions = model_->size();
|
| chevron_->SetVisible(static_cast<size_t>(visible_actions) < model_->size());
|
| - container_width_ = IconCountToWidth(visible_actions);
|
| + container_width_ = IconCountToWidth(visible_actions, chevron_->IsVisible());
|
| }
|
|
|
| void BrowserActionsContainer::CloseOverflowMenu() {
|
| @@ -1014,65 +1040,34 @@
|
| }
|
| }
|
|
|
| -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::IconCountToWidth(int icons,
|
| + bool display_chevron) const {
|
| + if (icons < 0)
|
| + icons = browser_action_views_.size();
|
| + if ((icons == 0) && !display_chevron)
|
| + return ToolbarView::kStandardSpacing;
|
| + int icons_size =
|
| + (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing);
|
| + int chevron_size = display_chevron ?
|
| + (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0;
|
| + return ToolbarView::kStandardSpacing + icons_size + chevron_size +
|
| + ToolbarView::kStandardSpacing;
|
| }
|
|
|
| -int BrowserActionsContainer::WidthOfNonIconArea() const {
|
| - int chevron_size = (chevron_->IsVisible()) ?
|
| - chevron_->GetPreferredSize().width() : 0;
|
| - int padding = base::i18n::IsRTL() ?
|
| - kHorizontalPaddingRtl : kHorizontalPadding;
|
| - return kResizeAreaWidth + padding + chevron_size + kChevronRightMargin +
|
| - kDividerHorizontalMargin;
|
| +int BrowserActionsContainer::WidthToIconCount(int pixels) const {
|
| + // 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_->GetPreferredSize().width() - kChevronSpacing -
|
| + ToolbarView::kStandardSpacing;
|
| + // Now we add an extra between-item padding value so the space can be divided
|
| + // evenly by (size of icon with padding).
|
| + return std::max(0, available_space + kItemSpacing) / IconWidth(true);
|
| }
|
|
|
| -int BrowserActionsContainer::IconCountToWidth(int icons) const {
|
| - DCHECK_GE(icons, 0);
|
| - if (icons == 0)
|
| - return ContainerMinSize();
|
| -
|
| - int icon_width = kButtonSize + kBrowserActionButtonPadding;
|
| -
|
| - return WidthOfNonIconArea() + (icons * icon_width);
|
| -}
|
| -
|
| int BrowserActionsContainer::ContainerMinSize() const {
|
| - return kResizeAreaWidth + chevron_->width() + kChevronRightMargin;
|
| + return ToolbarView::kStandardSpacing + kChevronSpacing +
|
| + chevron_->GetPreferredSize().width() + ToolbarView::kStandardSpacing;
|
| }
|
|
|
| void BrowserActionsContainer::Animate(Tween::Type tween_type, int target_size) {
|
|
|