This source file includes following definitions.
- show_menu_task_factory_
- Init
- GetBrowserActionView
- RefreshBrowserActionViews
- CreateBrowserActionViews
- DeleteBrowserActionViews
- VisibleBrowserActions
- ExecuteExtensionCommand
- AddObserver
- RemoveObserver
- GetPreferredSize
- Layout
- GetDropFormats
- AreDropTypesRequired
- CanDrop
- OnDragEntered
- OnDragUpdated
- OnDragExited
- OnPerformDrop
- GetAccessibleState
- OnMenuButtonClicked
- WriteDragDataForView
- GetDragOperationsForView
- CanStartDragForView
- OnResize
- AnimationProgressed
- AnimationEnded
- NotifyMenuDeleted
- OnWidgetDestroying
- InspectPopup
- GetCurrentTabId
- OnBrowserActionExecuted
- OnBrowserActionVisibilityChanged
- GetActiveTabPermissionGranter
- MoveBrowserAction
- ShowPopup
- HidePopup
- TestExecuteBrowserAction
- TestSetIconVisibilityCount
- OnPaint
- OnThemeChanged
- ViewHierarchyChanged
- IconWidth
- IconHeight
- BrowserActionAdded
- BrowserActionRemoved
- BrowserActionMoved
- BrowserActionShowPopup
- VisibleCountChanged
- HighlightModeChanged
- LoadImages
- SetContainerWidth
- CloseOverflowMenu
- StopShowFolderDropMenuTimer
- StartShowFolderDropMenuTimer
- ShowDropFolder
- SetDropIndicator
- IconCountToWidth
- WidthToIconCount
- ContainerMinSize
- SaveDesiredSizeAndAnimate
- ShouldDisplayBrowserAction
- ShowPopup
#include "chrome/browser/ui/views/toolbar/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_util.h"
#include "chrome/browser/extensions/extension_view_host.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/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/browser_action_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/common/extensions/command.h"
#include "chrome/common/pref_names.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/pref_names.h"
#include "extensions/browser/runtime_data.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/ui_resources.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/dragdrop/drag_utils.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/nine_image_painter_factory.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/gfx/geometry/rect.h"
#include "ui/views/controls/resize_area.h"
#include "ui/views/metrics.h"
#include "ui/views/painter.h"
#include "ui/views/widget/widget.h"
using extensions::Extension;
namespace {
const int kItemSpacing = ToolbarView::kStandardSpacing;
const int kChevronSpacing = kItemSpacing - 2;
}
bool BrowserActionsContainer::disable_animations_during_testing_ = false;
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_ = extensions::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, base::string16(), this, false);
chevron_->SetBorder(views::Border::NullBorder());
chevron_->EnableCanvasFlippingForRTLUI(true);
chevron_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS_CHEVRON));
chevron_->SetVisible(false);
AddChildView(chevron_);
}
BrowserActionsContainer::~BrowserActionsContainer() {
FOR_EACH_OBSERVER(BrowserActionsContainerObserver,
observers_,
OnBrowserActionsContainerDestroyed());
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();
if (model_ &&
!profile_->GetPrefs()->HasPrefPath(
extensions::pref_names::kToolbarSize)) {
int predefined_width = profile_->GetPrefs()->GetInteger(
extensions::pref_names::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;
}
void BrowserActionsContainer::ExecuteExtensionCommand(
const extensions::Extension* extension,
const extensions::Command& command) {
DCHECK(!command.global());
extension_keybinding_registry_->ExecuteCommand(extension->id(),
command.accelerator());
}
void BrowserActionsContainer::AddObserver(
BrowserActionsContainerObserver* observer) {
observers_.AddObserver(observer);
}
void BrowserActionsContainer::RemoveObserver(
BrowserActionsContainerObserver* observer) {
observers_.RemoveObserver(observer);
}
gfx::Size BrowserActionsContainer::GetPreferredSize() {
if (browser_action_views_.empty())
return gfx::Size(ToolbarView::kStandardSpacing, 0);
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, 0, kItemSpacing, height());
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(),
0,
chevron_size.width(),
chevron_size.height());
} else {
chevron_->SetVisible(false);
}
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) {
if (GetEventHandlerForPoint(event.location()) == chevron_) {
if (!show_menu_task_factory_.HasWeakPtrs() && !overflow_menu_)
StartShowFolderDropMenuTimer();
return ui::DragDropTypes::DRAG_MOVE;
}
StopShowFolderDropMenuTimer();
int width_before_icons = ToolbarView::kStandardSpacing +
(base::i18n::IsRTL() ?
(chevron_->GetPreferredSize().width() + kChevronSpacing) : 0);
int offset_into_icon_area = event.x() - width_before_icons;
int before_icon_unclamped = (offset_into_icon_area + (IconWidth(false) / 2) +
kItemSpacing) / IconWidth(true);
int before_icon = std::min(std::max(before_icon_unclamped, 0),
static_cast<int>(VisibleBrowserActions()));
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;
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_))) {
break;
}
}
if (i > data.index())
--i;
if (profile_->IsOffTheRecord())
i = model_->IncognitoIndexToOriginal(i);
model_->MoveBrowserAction(
browser_action_views_[data.index()]->button()->extension(), i);
OnDragExited();
return ui::DragDropTypes::DRAG_MOVE;
}
void BrowserActionsContainer::GetAccessibleState(
ui::AXViewState* state) {
state->role = ui::AX_ROLE_GROUP;
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) {
gfx::ImageSkia badge(browser_action_views_[i]->GetIconWithBadge());
drag_utils::SetDragImageOnDataObject(badge, button->size(),
press_pt.OffsetFromOrigin(),
data);
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 !model_->is_highlighting();
}
void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) {
if (!done_resizing) {
resize_amount_ = resize_amount;
OnBrowserActionVisibilityChanged();
return;
}
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;
suppress_chevron_ = false;
OnBrowserActionVisibilityChanged();
FOR_EACH_OBSERVER(BrowserActionsContainerObserver,
observers_,
OnBrowserActionsContainerAnimationEnded());
}
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;
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();
}
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();
}
}
bool BrowserActionsContainer::ShowPopup(const extensions::Extension* extension,
bool should_grant) {
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, should_grant);
}
return false;
}
void BrowserActionsContainer::HidePopup() {
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) {
if (model_->is_highlighting() && !browser_action_views_.empty()) {
views::Painter::PaintPainterAt(
canvas, highlight_painter_.get(), GetLocalBounds());
}
if (drop_indicator_position_ > -1) {
static const int kDropIndicatorWidth = 2;
gfx::Rect indicator_bounds(
drop_indicator_position_ - (kDropIndicatorWidth / 2),
0,
kDropIndicatorWidth,
height());
static const SkColor kDropIndicatorColor = SK_ColorBLACK;
canvas->FillRect(indicator_bounds, kDropIndicatorColor);
}
}
void BrowserActionsContainer::OnThemeChanged() {
LoadImages();
}
void BrowserActionsContainer::ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) {
if (!model_)
return;
if (details.is_add && details.child == this) {
CreateBrowserActionViews();
}
}
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);
}
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();
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 (!model_->extensions_initialized())
return;
if ((model_->GetVisibleIconCount() < 0) &&
!extensions::ExtensionSystem::Get(profile_)->runtime_data()->
IsBeingUpgraded(extension)) {
suppress_chevron_ = true;
SaveDesiredSizeAndAnimate(gfx::Tween::LINEAR, visible_actions + 1);
} else {
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 (extensions::ExtensionSystem::Get(profile_)->runtime_data()->
IsBeingUpgraded(extension))
return;
if (browser_action_views_.size() > visible_actions) {
OnBrowserActionVisibilityChanged();
} else {
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) {
return ShowPopup(extension, false);
}
void BrowserActionsContainer::VisibleCountChanged() {
SetContainerWidth();
}
void BrowserActionsContainer::HighlightModeChanged(bool is_highlighting) {
DeleteBrowserActionViews();
CreateBrowserActionViews();
SaveDesiredSizeAndAnimate(gfx::Tween::LINEAR, browser_action_views_.size());
}
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));
const int kImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT);
highlight_painter_.reset(views::Painter::CreateImageGridPainter(kImages));
}
void BrowserActionsContainer::SetContainerWidth() {
int visible_actions = model_->GetVisibleIconCount();
if (visible_actions < 0)
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 {
if (pixels >= IconCountToWidth(-1, false))
return browser_action_views_.size();
int available_space = pixels - ToolbarView::kStandardSpacing -
chevron_->GetPreferredSize().width() - kChevronSpacing -
ToolbarView::kStandardSpacing;
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) {
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_) {
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) {
return !profile_->IsOffTheRecord() ||
extensions::util::IsIncognitoEnabled(extension->id(), profile_);
}
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) !=
extensions::ExtensionToolbarModel::ACTION_SHOW_POPUP) {
return false;
}
bool same_showing = popup_ && button == popup_button_;
HidePopup();
if (same_showing)
return false;
View* reference_view = button->parent()->visible() ? button : chevron_;
popup_ = ExtensionPopup::ShowPopup(popup_url, browser_, reference_view,
views::BubbleBorder::TOP_RIGHT,
show_action);
popup_->GetWidget()->AddObserver(this);
popup_button_ = button;
if (should_grant)
popup_button_->SetButtonPushed();
return true;
}