| Index: chrome/browser/ui/views/browser_actions_container.cc
|
| diff --git a/chrome/browser/ui/views/browser_actions_container.cc b/chrome/browser/ui/views/browser_actions_container.cc
|
| deleted file mode 100644
|
| index 18b653a8a76328b9d1e677eb0945f102912785c5..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/ui/views/browser_actions_container.cc
|
| +++ /dev/null
|
| @@ -1,876 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/ui/views/browser_actions_container.h"
|
| -
|
| -#include "base/compiler_specific.h"
|
| -#include "base/prefs/pref_service.h"
|
| -#include "base/stl_util.h"
|
| -#include "chrome/browser/extensions/extension_service.h"
|
| -#include "chrome/browser/extensions/extension_system.h"
|
| -#include "chrome/browser/extensions/extension_util.h"
|
| -#include "chrome/browser/extensions/tab_helper.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/sessions/session_tab_helper.h"
|
| -#include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/ui/browser_window.h"
|
| -#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| -#include "chrome/browser/ui/view_ids.h"
|
| -#include "chrome/browser/ui/views/browser_action_view.h"
|
| -#include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
|
| -#include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views.h"
|
| -#include "chrome/browser/ui/views/extensions/extension_popup.h"
|
| -#include "chrome/browser/ui/views/toolbar_view.h"
|
| -#include "chrome/common/pref_names.h"
|
| -#include "grit/generated_resources.h"
|
| -#include "grit/theme_resources.h"
|
| -#include "grit/ui_resources.h"
|
| -#include "ui/base/accessibility/accessible_view_state.h"
|
| -#include "ui/base/dragdrop/drag_utils.h"
|
| -#include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/base/resource/resource_bundle.h"
|
| -#include "ui/base/theme_provider.h"
|
| -#include "ui/gfx/animation/slide_animation.h"
|
| -#include "ui/gfx/canvas.h"
|
| -#include "ui/views/controls/resize_area.h"
|
| -#include "ui/views/metrics.h"
|
| -#include "ui/views/widget/widget.h"
|
| -
|
| -using extensions::Extension;
|
| -
|
| -namespace {
|
| -
|
| -// Horizontal spacing between most items in the container, as well as after the
|
| -// last item or chevron (if visible).
|
| -const int kItemSpacing = ToolbarView::kStandardSpacing;
|
| -
|
| -// Horizontal spacing before the chevron (if visible).
|
| -const int kChevronSpacing = kItemSpacing - 2;
|
| -
|
| -} // namespace
|
| -
|
| -// static
|
| -bool BrowserActionsContainer::disable_animations_during_testing_ = false;
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// BrowserActionsContainer
|
| -
|
| -BrowserActionsContainer::BrowserActionsContainer(Browser* browser,
|
| - View* owner_view)
|
| - : profile_(browser->profile()),
|
| - browser_(browser),
|
| - owner_view_(owner_view),
|
| - popup_(NULL),
|
| - popup_button_(NULL),
|
| - model_(NULL),
|
| - container_width_(0),
|
| - chevron_(NULL),
|
| - overflow_menu_(NULL),
|
| - suppress_chevron_(false),
|
| - resize_amount_(0),
|
| - animation_target_size_(0),
|
| - drop_indicator_position_(-1),
|
| - task_factory_(this),
|
| - show_menu_task_factory_(this) {
|
| - set_id(VIEW_ID_BROWSER_ACTION_TOOLBAR);
|
| -
|
| - model_ = ExtensionToolbarModel::Get(browser->profile());
|
| - if (model_)
|
| - model_->AddObserver(this);
|
| -
|
| - extension_keybinding_registry_.reset(new ExtensionKeybindingRegistryViews(
|
| - browser->profile(),
|
| - owner_view->GetFocusManager(),
|
| - extensions::ExtensionKeybindingRegistry::ALL_EXTENSIONS,
|
| - this));
|
| -
|
| - resize_animation_.reset(new gfx::SlideAnimation(this));
|
| - resize_area_ = new views::ResizeArea(this);
|
| - AddChildView(resize_area_);
|
| -
|
| - chevron_ = new views::MenuButton(NULL, string16(), this, false);
|
| - chevron_->set_border(NULL);
|
| - chevron_->EnableCanvasFlippingForRTLUI(true);
|
| - chevron_->SetAccessibleName(
|
| - l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS_CHEVRON));
|
| - chevron_->SetVisible(false);
|
| - AddChildView(chevron_);
|
| -}
|
| -
|
| -BrowserActionsContainer::~BrowserActionsContainer() {
|
| - if (overflow_menu_)
|
| - overflow_menu_->set_observer(NULL);
|
| - if (model_)
|
| - model_->RemoveObserver(this);
|
| - StopShowFolderDropMenuTimer();
|
| - if (popup_)
|
| - popup_->GetWidget()->RemoveObserver(this);
|
| - HidePopup();
|
| - DeleteBrowserActionViews();
|
| -}
|
| -
|
| -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();
|
| -}
|
| -
|
| -BrowserActionView* BrowserActionsContainer::GetBrowserActionView(
|
| - ExtensionAction* action) {
|
| - for (BrowserActionViews::iterator i(browser_action_views_.begin());
|
| - i != browser_action_views_.end(); ++i) {
|
| - if ((*i)->button()->browser_action() == action)
|
| - return *i;
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -void BrowserActionsContainer::RefreshBrowserActionViews() {
|
| - for (size_t i = 0; i < browser_action_views_.size(); ++i)
|
| - browser_action_views_[i]->button()->UpdateState();
|
| -}
|
| -
|
| -void BrowserActionsContainer::CreateBrowserActionViews() {
|
| - DCHECK(browser_action_views_.empty());
|
| - if (!model_)
|
| - return;
|
| -
|
| - const extensions::ExtensionList& toolbar_items = model_->toolbar_items();
|
| - for (extensions::ExtensionList::const_iterator i(toolbar_items.begin());
|
| - i != toolbar_items.end(); ++i) {
|
| - if (!ShouldDisplayBrowserAction(i->get()))
|
| - continue;
|
| -
|
| - BrowserActionView* view = new BrowserActionView(i->get(), browser_, this);
|
| - browser_action_views_.push_back(view);
|
| - AddChildView(view);
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsContainer::DeleteBrowserActionViews() {
|
| - HidePopup();
|
| - STLDeleteElements(&browser_action_views_);
|
| -}
|
| -
|
| -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]->visible())
|
| - ++visible_actions;
|
| - }
|
| - return visible_actions;
|
| -}
|
| -
|
| -gfx::Size BrowserActionsContainer::GetPreferredSize() {
|
| - if (browser_action_views_.empty())
|
| - 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
|
| - // resizing the view or, if animating the snapping, how far to animate it).
|
| - // 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 clamped_width = std::min(
|
| - std::max(ContainerMinSize(), container_width_ - resize_amount_),
|
| - IconCountToWidth(-1, false));
|
| - return gfx::Size(clamped_width, 0);
|
| -}
|
| -
|
| -void BrowserActionsContainer::Layout() {
|
| - if (browser_action_views_.empty()) {
|
| - SetVisible(false);
|
| - return;
|
| - }
|
| -
|
| - SetVisible(true);
|
| - resize_area_->SetBounds(0, ToolbarView::kVertSpacing, kItemSpacing,
|
| - IconHeight());
|
| -
|
| - // 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 -=
|
| - 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];
|
| - int x = ToolbarView::kStandardSpacing + (i * IconWidth(true));
|
| - if (x + icon_width <= max_x) {
|
| - view->SetBounds(x, 0, icon_width, height());
|
| - view->SetVisible(true);
|
| - } else {
|
| - view->SetVisible(false);
|
| - }
|
| - }
|
| -}
|
| -
|
| -bool BrowserActionsContainer::GetDropFormats(
|
| - int* formats,
|
| - std::set<OSExchangeData::CustomFormat>* custom_formats) {
|
| - custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat());
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool BrowserActionsContainer::AreDropTypesRequired() {
|
| - return true;
|
| -}
|
| -
|
| -bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) {
|
| - BrowserActionDragData drop_data;
|
| - return drop_data.Read(data) ? drop_data.IsFromProfile(profile_) : false;
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnDragEntered(
|
| - const ui::DropTargetEvent& event) {
|
| -}
|
| -
|
| -int BrowserActionsContainer::OnDragUpdated(
|
| - const ui::DropTargetEvent& event) {
|
| - // First check if we are above the chevron (overflow) menu.
|
| - if (GetEventHandlerForPoint(event.location()) == chevron_) {
|
| - if (!show_menu_task_factory_.HasWeakPtrs() && !overflow_menu_)
|
| - StartShowFolderDropMenuTimer();
|
| - return ui::DragDropTypes::DRAG_MOVE;
|
| - }
|
| - StopShowFolderDropMenuTimer();
|
| -
|
| - // Figure out where to display the indicator. This is a complex calculation:
|
| -
|
| - // 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;
|
| -
|
| - // 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);
|
| -
|
| - // 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 ui::DragDropTypes::DRAG_MOVE;
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnDragExited() {
|
| - StopShowFolderDropMenuTimer();
|
| - drop_indicator_position_ = -1;
|
| - SchedulePaint();
|
| -}
|
| -
|
| -int BrowserActionsContainer::OnPerformDrop(
|
| - const ui::DropTargetEvent& event) {
|
| - BrowserActionDragData data;
|
| - if (!data.Read(event.data()))
|
| - return ui::DragDropTypes::DRAG_NONE;
|
| -
|
| - // Make sure we have the same view as we started with.
|
| - DCHECK_EQ(browser_action_views_[data.index()]->button()->extension()->id(),
|
| - data.id());
|
| - DCHECK(model_);
|
| -
|
| - size_t i = 0;
|
| - for (; i < browser_action_views_.size(); ++i) {
|
| - int view_x = browser_action_views_[i]->GetMirroredBounds().x();
|
| - if (!browser_action_views_[i]->visible() ||
|
| - (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;
|
| - }
|
| - }
|
| -
|
| - // |i| now points to the item to the right of the drop indicator*, which is
|
| - // correct when dragging an icon to the left. When dragging to the right,
|
| - // however, we want the icon being dragged to get the index of the item to
|
| - // the left of the drop indicator, so we subtract one.
|
| - // * Well, it can also point to the end, but not when dragging to the left. :)
|
| - if (i > data.index())
|
| - --i;
|
| -
|
| - if (profile_->IsOffTheRecord())
|
| - i = model_->IncognitoIndexToOriginal(i);
|
| -
|
| - model_->MoveBrowserAction(
|
| - browser_action_views_[data.index()]->button()->extension(), i);
|
| -
|
| - OnDragExited(); // Perform clean up after dragging.
|
| - return ui::DragDropTypes::DRAG_MOVE;
|
| -}
|
| -
|
| -void BrowserActionsContainer::GetAccessibleState(
|
| - ui::AccessibleViewState* state) {
|
| - state->role = ui::AccessibilityTypes::ROLE_GROUPING;
|
| - state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS);
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnMenuButtonClicked(views::View* source,
|
| - const gfx::Point& point) {
|
| - if (source == chevron_) {
|
| - overflow_menu_ = new BrowserActionOverflowMenuController(
|
| - this, browser_, chevron_, browser_action_views_,
|
| - VisibleBrowserActions());
|
| - overflow_menu_->set_observer(this);
|
| - overflow_menu_->RunMenu(GetWidget(), false);
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsContainer::WriteDragDataForView(View* sender,
|
| - const gfx::Point& press_pt,
|
| - OSExchangeData* data) {
|
| - DCHECK(data);
|
| -
|
| - for (size_t i = 0; i < browser_action_views_.size(); ++i) {
|
| - BrowserActionButton* button = browser_action_views_[i]->button();
|
| - if (button == sender) {
|
| - // Set the dragging image for the icon.
|
| - gfx::ImageSkia badge(browser_action_views_[i]->GetIconWithBadge());
|
| - drag_utils::SetDragImageOnDataObject(badge, button->size(),
|
| - press_pt.OffsetFromOrigin(),
|
| - data);
|
| -
|
| - // Fill in the remaining info.
|
| - BrowserActionDragData drag_data(
|
| - browser_action_views_[i]->button()->extension()->id(), i);
|
| - drag_data.Write(profile_, data);
|
| - break;
|
| - }
|
| - }
|
| -}
|
| -
|
| -int BrowserActionsContainer::GetDragOperationsForView(View* sender,
|
| - const gfx::Point& p) {
|
| - return ui::DragDropTypes::DRAG_MOVE;
|
| -}
|
| -
|
| -bool BrowserActionsContainer::CanStartDragForView(View* sender,
|
| - const gfx::Point& press_pt,
|
| - const gfx::Point& p) {
|
| - return true;
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) {
|
| - if (!done_resizing) {
|
| - resize_amount_ = resize_amount;
|
| - OnBrowserActionVisibilityChanged();
|
| - return;
|
| - }
|
| -
|
| - // 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, 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);
|
| - SaveDesiredSizeAndAnimate(gfx::Tween::EASE_OUT,
|
| - WidthToIconCount(container_width_));
|
| -}
|
| -
|
| -void BrowserActionsContainer::AnimationProgressed(
|
| - const gfx::Animation* animation) {
|
| - DCHECK_EQ(resize_animation_.get(), animation);
|
| - resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() *
|
| - (container_width_ - animation_target_size_));
|
| - OnBrowserActionVisibilityChanged();
|
| -}
|
| -
|
| -void BrowserActionsContainer::AnimationEnded(const gfx::Animation* animation) {
|
| - container_width_ = animation_target_size_;
|
| - animation_target_size_ = 0;
|
| - resize_amount_ = 0;
|
| - OnBrowserActionVisibilityChanged();
|
| - suppress_chevron_ = false;
|
| -}
|
| -
|
| -void BrowserActionsContainer::NotifyMenuDeleted(
|
| - BrowserActionOverflowMenuController* controller) {
|
| - DCHECK_EQ(overflow_menu_, controller);
|
| - overflow_menu_ = NULL;
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnWidgetDestroying(views::Widget* widget) {
|
| - DCHECK_EQ(popup_->GetWidget(), widget);
|
| - popup_->GetWidget()->RemoveObserver(this);
|
| - popup_ = NULL;
|
| - // |popup_button_| is NULL if the extension has been removed.
|
| - if (popup_button_) {
|
| - popup_button_->SetButtonNotPushed();
|
| - popup_button_ = NULL;
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsContainer::InspectPopup(ExtensionAction* action) {
|
| - BrowserActionView* view = GetBrowserActionView(action);
|
| - ShowPopup(view->button(), ExtensionPopup::SHOW_AND_INSPECT, true);
|
| -}
|
| -
|
| -int BrowserActionsContainer::GetCurrentTabId() const {
|
| - content::WebContents* active_tab =
|
| - browser_->tab_strip_model()->GetActiveWebContents();
|
| - if (!active_tab)
|
| - return -1;
|
| -
|
| - return SessionTabHelper::FromWebContents(active_tab)->session_id().id();
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnBrowserActionExecuted(
|
| - BrowserActionButton* button) {
|
| - ShowPopup(button, ExtensionPopup::SHOW, true);
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnBrowserActionVisibilityChanged() {
|
| - SetVisible(!browser_action_views_.empty());
|
| - owner_view_->Layout();
|
| - owner_view_->SchedulePaint();
|
| -}
|
| -
|
| -gfx::Point BrowserActionsContainer::GetViewContentOffset() const {
|
| - return gfx::Point(0, ToolbarView::kVertSpacing);
|
| -}
|
| -
|
| -extensions::ActiveTabPermissionGranter*
|
| - BrowserActionsContainer::GetActiveTabPermissionGranter() {
|
| - content::WebContents* web_contents =
|
| - browser_->tab_strip_model()->GetActiveWebContents();
|
| - if (!web_contents)
|
| - return NULL;
|
| - return extensions::TabHelper::FromWebContents(web_contents)->
|
| - active_tab_permission_granter();
|
| -}
|
| -
|
| -void BrowserActionsContainer::MoveBrowserAction(const std::string& extension_id,
|
| - size_t new_index) {
|
| - ExtensionService* service =
|
| - extensions::ExtensionSystem::Get(profile_)->extension_service();
|
| - if (service) {
|
| - const Extension* extension = service->GetExtensionById(extension_id, false);
|
| - model_->MoveBrowserAction(extension, new_index);
|
| - SchedulePaint();
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsContainer::HidePopup() {
|
| - // Remove this as an observer and clear |popup_| and |popup_button_| here,
|
| - // since we might change them before OnWidgetDestroying() gets called.
|
| - if (popup_) {
|
| - popup_->GetWidget()->RemoveObserver(this);
|
| - popup_->GetWidget()->Close();
|
| - popup_ = NULL;
|
| - }
|
| - if (popup_button_) {
|
| - popup_button_->SetButtonNotPushed();
|
| - popup_button_ = NULL;
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsContainer::TestExecuteBrowserAction(int index) {
|
| - BrowserActionButton* button = browser_action_views_[index]->button();
|
| - OnBrowserActionExecuted(button);
|
| -}
|
| -
|
| -void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) {
|
| - model_->SetVisibleIconCount(icons);
|
| - chevron_->SetVisible(icons < browser_action_views_.size());
|
| - container_width_ = IconCountToWidth(icons, chevron_->visible());
|
| - Layout();
|
| - SchedulePaint();
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) {
|
| - // 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) {
|
| - // The two-pixel width drop indicator.
|
| - static const int kDropIndicatorWidth = 2;
|
| - gfx::Rect indicator_bounds(
|
| - drop_indicator_position_ - (kDropIndicatorWidth / 2),
|
| - ToolbarView::kVertSpacing, kDropIndicatorWidth, IconHeight());
|
| -
|
| - // Color of the drop indicator.
|
| - static const SkColor kDropIndicatorColor = SK_ColorBLACK;
|
| - canvas->FillRect(indicator_bounds, kDropIndicatorColor);
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsContainer::OnThemeChanged() {
|
| - LoadImages();
|
| -}
|
| -
|
| -void BrowserActionsContainer::ViewHierarchyChanged(
|
| - const ViewHierarchyChangedDetails& details) {
|
| - // No extensions (e.g., incognito).
|
| - if (!model_)
|
| - return;
|
| -
|
| - if (details.is_add && details.child == this) {
|
| - // Initial toolbar button creation and placement in the widget hierarchy.
|
| - // We do this here instead of in the constructor because AddBrowserAction
|
| - // calls Layout on the Toolbar, which needs this object to be constructed
|
| - // before its Layout function is called.
|
| - CreateBrowserActionViews();
|
| - }
|
| -}
|
| -
|
| -// static
|
| -int BrowserActionsContainer::IconWidth(bool include_padding) {
|
| - static bool initialized = false;
|
| - static int icon_width = 0;
|
| - if (!initialized) {
|
| - initialized = true;
|
| - icon_width = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
|
| - 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 = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
|
| - IDR_BROWSER_ACTION)->height();
|
| - }
|
| - return icon_height;
|
| -}
|
| -
|
| -void BrowserActionsContainer::BrowserActionAdded(const Extension* extension,
|
| - int index) {
|
| -#if defined(DEBUG)
|
| - for (size_t i = 0; i < browser_action_views_.size(); ++i) {
|
| - DCHECK(browser_action_views_[i]->button()->extension() != extension) <<
|
| - "Asked to add a browser action view for an extension that already "
|
| - "exists.";
|
| - }
|
| -#endif
|
| - CloseOverflowMenu();
|
| -
|
| - if (!ShouldDisplayBrowserAction(extension))
|
| - return;
|
| -
|
| - 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, browser_, this);
|
| - browser_action_views_.insert(browser_action_views_.begin() + index, view);
|
| - AddChildViewAt(view, index);
|
| -
|
| - // If we are still initializing the container, don't bother animating.
|
| - if (!model_->extensions_initialized())
|
| - return;
|
| -
|
| - // Enlarge the container if it was already at maximum size and we're not in
|
| - // the middle of upgrading.
|
| - if ((model_->GetVisibleIconCount() < 0) &&
|
| - !extensions::ExtensionSystem::Get(profile_)->extension_service()->
|
| - IsBeingUpgraded(extension)) {
|
| - suppress_chevron_ = true;
|
| - SaveDesiredSizeAndAnimate(gfx::Tween::LINEAR, visible_actions + 1);
|
| - } else {
|
| - // Just redraw the (possibly modified) visible icon set.
|
| - OnBrowserActionVisibilityChanged();
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsContainer::BrowserActionRemoved(const Extension* extension) {
|
| - CloseOverflowMenu();
|
| -
|
| - if (popup_ && popup_->host()->extension() == extension)
|
| - HidePopup();
|
| -
|
| - size_t visible_actions = VisibleBrowserActions();
|
| - for (BrowserActionViews::iterator i(browser_action_views_.begin());
|
| - i != browser_action_views_.end(); ++i) {
|
| - if ((*i)->button()->extension() == extension) {
|
| - delete *i;
|
| - browser_action_views_.erase(i);
|
| -
|
| - // If the extension is being upgraded we don't want the bar to shrink
|
| - // because the icon is just going to get re-added to the same location.
|
| - if (extensions::ExtensionSystem::Get(profile_)->extension_service()->
|
| - IsBeingUpgraded(extension))
|
| - return;
|
| -
|
| - 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);
|
| - SaveDesiredSizeAndAnimate(gfx::Tween::EASE_OUT,
|
| - browser_action_views_.size());
|
| - }
|
| - return;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsContainer::BrowserActionMoved(const Extension* extension,
|
| - int index) {
|
| - if (!ShouldDisplayBrowserAction(extension))
|
| - return;
|
| -
|
| - if (profile_->IsOffTheRecord())
|
| - index = model_->OriginalIndexToIncognito(index);
|
| -
|
| - DCHECK(index >= 0 && index < static_cast<int>(browser_action_views_.size()));
|
| -
|
| - DeleteBrowserActionViews();
|
| - CreateBrowserActionViews();
|
| - Layout();
|
| - SchedulePaint();
|
| -}
|
| -
|
| -bool BrowserActionsContainer::BrowserActionShowPopup(
|
| - const extensions::Extension* extension) {
|
| - // Do not override other popups and only show in active window. The window
|
| - // must also have a toolbar, otherwise it should not be showing popups.
|
| - // TODO(justinlin): Remove toolbar check when http://crbug.com/308645 is
|
| - // fixed.
|
| - if (popup_ ||
|
| - !browser_->window()->IsActive() ||
|
| - !browser_->window()->IsToolbarVisible()) {
|
| - return false;
|
| - }
|
| -
|
| - for (BrowserActionViews::iterator it = browser_action_views_.begin();
|
| - it != browser_action_views_.end(); ++it) {
|
| - BrowserActionButton* button = (*it)->button();
|
| - if (button && button->extension() == extension)
|
| - return ShowPopup(button, ExtensionPopup::SHOW, false);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -void BrowserActionsContainer::ModelLoaded() {
|
| - SetContainerWidth();
|
| -}
|
| -
|
| -void BrowserActionsContainer::LoadImages() {
|
| - ui::ThemeProvider* tp = GetThemeProvider();
|
| - chevron_->SetIcon(*tp->GetImageSkiaNamed(IDR_BROWSER_ACTIONS_OVERFLOW));
|
| - chevron_->SetHoverIcon(*tp->GetImageSkiaNamed(
|
| - IDR_BROWSER_ACTIONS_OVERFLOW_H));
|
| - chevron_->SetPushedIcon(*tp->GetImageSkiaNamed(
|
| - 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_->toolbar_items().size();
|
| - chevron_->SetVisible(
|
| - static_cast<size_t>(visible_actions) < model_->toolbar_items().size());
|
| - container_width_ = IconCountToWidth(visible_actions, chevron_->visible());
|
| -}
|
| -
|
| -void BrowserActionsContainer::CloseOverflowMenu() {
|
| - if (overflow_menu_)
|
| - overflow_menu_->CancelMenu();
|
| -}
|
| -
|
| -void BrowserActionsContainer::StopShowFolderDropMenuTimer() {
|
| - show_menu_task_factory_.InvalidateWeakPtrs();
|
| -}
|
| -
|
| -void BrowserActionsContainer::StartShowFolderDropMenuTimer() {
|
| - base::MessageLoop::current()->PostDelayedTask(
|
| - FROM_HERE,
|
| - base::Bind(&BrowserActionsContainer::ShowDropFolder,
|
| - show_menu_task_factory_.GetWeakPtr()),
|
| - base::TimeDelta::FromMilliseconds(views::GetMenuShowDelay()));
|
| -}
|
| -
|
| -void BrowserActionsContainer::ShowDropFolder() {
|
| - DCHECK(!overflow_menu_);
|
| - SetDropIndicator(-1);
|
| - overflow_menu_ = new BrowserActionOverflowMenuController(
|
| - this, browser_, chevron_, browser_action_views_, VisibleBrowserActions());
|
| - overflow_menu_->set_observer(this);
|
| - overflow_menu_->RunMenu(GetWidget(), true);
|
| -}
|
| -
|
| -void BrowserActionsContainer::SetDropIndicator(int x_pos) {
|
| - if (drop_indicator_position_ != x_pos) {
|
| - drop_indicator_position_ = x_pos;
|
| - SchedulePaint();
|
| - }
|
| -}
|
| -
|
| -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;
|
| -}
|
| -
|
| -size_t BrowserActionsContainer::WidthToIconCount(int pixels) const {
|
| - // Check for widths large enough to show the entire icon set.
|
| - 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_->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 static_cast<size_t>(
|
| - std::max(0, available_space + kItemSpacing) / IconWidth(true));
|
| -}
|
| -
|
| -int BrowserActionsContainer::ContainerMinSize() const {
|
| - return ToolbarView::kStandardSpacing + kChevronSpacing +
|
| - chevron_->GetPreferredSize().width() + ToolbarView::kStandardSpacing;
|
| -}
|
| -
|
| -void BrowserActionsContainer::SaveDesiredSizeAndAnimate(
|
| - gfx::Tween::Type tween_type,
|
| - size_t num_visible_icons) {
|
| - // Save off the desired number of visible icons. We do this now instead of at
|
| - // the end of the animation so that even if the browser is shut down while
|
| - // animating, the right value will be restored on next run.
|
| - // NOTE: 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(num_visible_icons);
|
| -
|
| - int target_size = IconCountToWidth(num_visible_icons,
|
| - num_visible_icons < browser_action_views_.size());
|
| - if (!disable_animations_during_testing_) {
|
| - // 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();
|
| - resize_animation_->SetTweenType(tween_type);
|
| - animation_target_size_ = target_size;
|
| - resize_animation_->Show();
|
| - } else {
|
| - animation_target_size_ = target_size;
|
| - AnimationEnded(resize_animation_.get());
|
| - }
|
| -}
|
| -
|
| -bool BrowserActionsContainer::ShouldDisplayBrowserAction(
|
| - const Extension* extension) {
|
| - // Only display incognito-enabled extensions while in incognito mode.
|
| - return
|
| - (!profile_->IsOffTheRecord() ||
|
| - extension_util::IsIncognitoEnabled(
|
| - extension->id(),
|
| - extensions::ExtensionSystem::Get(profile_)->extension_service()));
|
| -}
|
| -
|
| -bool BrowserActionsContainer::ShowPopup(
|
| - BrowserActionButton* button,
|
| - ExtensionPopup::ShowAction show_action,
|
| - bool should_grant) {
|
| - const Extension* extension = button->extension();
|
| - GURL popup_url;
|
| - if (model_->ExecuteBrowserAction(
|
| - extension, browser_, &popup_url, should_grant) !=
|
| - ExtensionToolbarModel::ACTION_SHOW_POPUP) {
|
| - return false;
|
| - }
|
| -
|
| - // If we're showing the same popup, just hide it and return.
|
| - bool same_showing = popup_ && button == popup_button_;
|
| -
|
| - // Always hide the current popup, even if it's not the same.
|
| - // Only one popup should be visible at a time.
|
| - HidePopup();
|
| -
|
| - if (same_showing)
|
| - return false;
|
| -
|
| - // 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->parent()->visible() ? button : chevron_;
|
| - views::BubbleBorder::Arrow arrow = base::i18n::IsRTL() ?
|
| - views::BubbleBorder::TOP_LEFT : views::BubbleBorder::TOP_RIGHT;
|
| - popup_ = ExtensionPopup::ShowPopup(popup_url,
|
| - browser_,
|
| - reference_view,
|
| - arrow,
|
| - show_action);
|
| - popup_->GetWidget()->AddObserver(this);
|
| - popup_button_ = button;
|
| -
|
| - // Only set button as pushed if it was triggered by a user click.
|
| - if (should_grant)
|
| - popup_button_->SetButtonPushed();
|
| - return true;
|
| -}
|
|
|