Commit 4efc003e authored by rdevlin.cronin's avatar rdevlin.cronin Committed by Commit bot

Make the chevron menu button responsible for legacy overflow menu logic

Move the ChevronMenuButton class into its own file, and move the logic to show
the legacy (drop-down) extension action overflow menu from the
BrowserActionsContainer into there.

This is mainly because:
1. We'll eventually be getting rid of this legacy behavior, and this way, the
   removal is all concentrated in one area (ChevronMenuButton).
2. BrowserActionsContainer is already doing a ton (since it has both new
   overflow and normal logic). It doesn't need this, too.

As a bonus, refactored the lifetime of the overflow menu to be more
deterministic, and got rid of the back-and-forth between it and the
BrowserActionsContainer.

And all with a negative line count! Woohoo!

BUG=417085

Review URL: https://codereview.chromium.org/597783002

Cr-Commit-Position: refs/heads/master@{#297240}
parent b83907e0
// 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.
#ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_BROWSER_ACTION_OVERFLOW_MENU_CONTROLLER_H_
#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_BROWSER_ACTION_OVERFLOW_MENU_CONTROLLER_H_
#include <set>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/sequenced_task_runner_helpers.h"
#include "ui/views/controls/menu/menu_delegate.h"
class Browser;
class BrowserActionsContainer;
class BrowserActionView;
class IconUpdater;
namespace views {
class MenuRunner;
class Widget;
}
// This class handles the overflow menu for browser actions (showing the menu,
// drag and drop, etc). This class manages its own lifetime.
class BrowserActionOverflowMenuController : public views::MenuDelegate {
public:
// The observer is notified prior to the menu being deleted.
class Observer {
public:
virtual void NotifyMenuDeleted(
BrowserActionOverflowMenuController* controller) = 0;
};
BrowserActionOverflowMenuController(
BrowserActionsContainer* owner,
Browser* browser,
views::MenuButton* menu_button,
const std::vector<BrowserActionView*>& views,
int start_index,
bool for_drop);
void set_observer(Observer* observer) { observer_ = observer; }
// Shows the overflow menu.
bool RunMenu(views::Widget* widget);
// Closes the overflow menu (and its context menu if open as well).
void CancelMenu();
// Notify the menu that the associated BrowserActionViews have been deleted.
void NotifyBrowserActionViewsDeleting();
// Overridden from views::MenuDelegate:
virtual bool IsCommandEnabled(int id) const OVERRIDE;
virtual void ExecuteCommand(int id) OVERRIDE;
virtual bool ShowContextMenu(views::MenuItemView* source,
int id,
const gfx::Point& p,
ui::MenuSourceType source_type) OVERRIDE;
virtual void DropMenuClosed(views::MenuItemView* menu) OVERRIDE;
// These drag functions offer support for dragging icons into the overflow
// menu.
virtual bool GetDropFormats(
views::MenuItemView* menu,
int* formats,
std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
virtual bool AreDropTypesRequired(views::MenuItemView* menu) OVERRIDE;
virtual bool CanDrop(views::MenuItemView* menu,
const ui::OSExchangeData& data) OVERRIDE;
virtual int GetDropOperation(views::MenuItemView* item,
const ui::DropTargetEvent& event,
DropPosition* position) OVERRIDE;
virtual int OnPerformDrop(views::MenuItemView* menu,
DropPosition position,
const ui::DropTargetEvent& event) OVERRIDE;
// These three drag functions offer support for dragging icons out of the
// overflow menu.
virtual bool CanDrag(views::MenuItemView* menu) OVERRIDE;
virtual void WriteDragData(views::MenuItemView* sender,
ui::OSExchangeData* data) OVERRIDE;
virtual int GetDragOperations(views::MenuItemView* sender) OVERRIDE;
private:
// This class manages its own lifetime.
virtual ~BrowserActionOverflowMenuController();
// Returns the offset into |views_| for the given |id|.
size_t IndexForId(int id) const;
// A pointer to the browser action container that owns the overflow menu.
BrowserActionsContainer* owner_;
Browser* browser_;
// The observer, may be null.
Observer* observer_;
// A pointer to the overflow menu button that we are showing the menu for.
views::MenuButton* menu_button_;
// The overflow menu for the menu button. Owned by |menu_runner_|.
views::MenuItemView* menu_;
// Resposible for running the menu.
scoped_ptr<views::MenuRunner> menu_runner_;
// The views vector of all the browser actions the container knows about. We
// won't show all items, just the one starting at |start_index| and above.
// Owned by |owner_|.
const std::vector<BrowserActionView*>& views_;
// The index into the BrowserActionView vector, indicating where to start
// picking browser actions to draw.
int start_index_;
// Whether this controller is being used for drop.
bool for_drop_;
// The vector keeps all icon updaters associated with menu item views in the
// controller. The icon updater will update the menu item view's icon when
// the browser action view's icon has been updated.
ScopedVector<IconUpdater> icon_updaters_;
friend class base::DeleteHelper<BrowserActionOverflowMenuController>;
DISALLOW_COPY_AND_ASSIGN(BrowserActionOverflowMenuController);
};
#endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_BROWSER_ACTION_OVERFLOW_MENU_CONTROLLER_H_
...@@ -52,35 +52,6 @@ namespace { ...@@ -52,35 +52,6 @@ namespace {
// Horizontal spacing before the chevron (if visible). // Horizontal spacing before the chevron (if visible).
const int kChevronSpacing = ToolbarView::kStandardSpacing - 2; const int kChevronSpacing = ToolbarView::kStandardSpacing - 2;
// A version of MenuButton with almost empty insets to fit properly on the
// toolbar.
class ChevronMenuButton : public views::MenuButton {
public:
ChevronMenuButton(views::ButtonListener* listener,
const base::string16& text,
views::MenuButtonListener* menu_button_listener,
bool show_menu_marker)
: views::MenuButton(listener,
text,
menu_button_listener,
show_menu_marker) {
}
virtual ~ChevronMenuButton() {}
virtual scoped_ptr<views::LabelButtonBorder> CreateDefaultBorder() const
OVERRIDE {
// The chevron resource was designed to not have any insets.
scoped_ptr<views::LabelButtonBorder> border =
views::MenuButton::CreateDefaultBorder();
border->set_insets(gfx::Insets());
return border.Pass();
}
private:
DISALLOW_COPY_AND_ASSIGN(ChevronMenuButton);
};
} // namespace } // namespace
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -127,11 +98,9 @@ BrowserActionsContainer::BrowserActionsContainer( ...@@ -127,11 +98,9 @@ BrowserActionsContainer::BrowserActionsContainer(
container_width_(0), container_width_(0),
resize_area_(NULL), resize_area_(NULL),
chevron_(NULL), chevron_(NULL),
overflow_menu_(NULL),
suppress_chevron_(false), suppress_chevron_(false),
resize_amount_(0), resize_amount_(0),
animation_target_size_(0), animation_target_size_(0) {
show_menu_task_factory_(this) {
set_id(VIEW_ID_BROWSER_ACTION_TOOLBAR); set_id(VIEW_ID_BROWSER_ACTION_TOOLBAR);
model_ = extensions::ExtensionToolbarModel::Get(browser->profile()); model_ = extensions::ExtensionToolbarModel::Get(browser->profile());
...@@ -156,7 +125,10 @@ BrowserActionsContainer::BrowserActionsContainer( ...@@ -156,7 +125,10 @@ BrowserActionsContainer::BrowserActionsContainer(
// 'Main' mode doesn't need a chevron overflow when overflow is shown inside // 'Main' mode doesn't need a chevron overflow when overflow is shown inside
// the Chrome menu. // the Chrome menu.
if (!overflow_experiment) { if (!overflow_experiment) {
chevron_ = new ChevronMenuButton(NULL, base::string16(), this, false); // Since the ChevronMenuButton holds a raw pointer to us, we need to
// ensure it doesn't outlive us. Having it owned by the view hierarchy as
// a child will suffice.
chevron_ = new ChevronMenuButton(this);
chevron_->EnableCanvasFlippingForRTLUI(true); chevron_->EnableCanvasFlippingForRTLUI(true);
chevron_->SetAccessibleName( chevron_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS_CHEVRON)); l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS_CHEVRON));
...@@ -171,11 +143,8 @@ BrowserActionsContainer::~BrowserActionsContainer() { ...@@ -171,11 +143,8 @@ BrowserActionsContainer::~BrowserActionsContainer() {
observers_, observers_,
OnBrowserActionsContainerDestroyed()); OnBrowserActionsContainerDestroyed());
if (overflow_menu_)
overflow_menu_->set_observer(NULL);
if (model_) if (model_)
model_->RemoveObserver(this); model_->RemoveObserver(this);
StopShowFolderDropMenuTimer();
HideActivePopup(); HideActivePopup();
DeleteBrowserActionViews(); DeleteBrowserActionViews();
} }
...@@ -233,8 +202,6 @@ void BrowserActionsContainer::CreateBrowserActionViews() { ...@@ -233,8 +202,6 @@ void BrowserActionsContainer::CreateBrowserActionViews() {
void BrowserActionsContainer::DeleteBrowserActionViews() { void BrowserActionsContainer::DeleteBrowserActionViews() {
HideActivePopup(); HideActivePopup();
if (overflow_menu_)
overflow_menu_->NotifyBrowserActionViewsDeleting();
STLDeleteElements(&browser_action_views_); STLDeleteElements(&browser_action_views_);
} }
...@@ -382,7 +349,7 @@ void BrowserActionsContainer::Layout() { ...@@ -382,7 +349,7 @@ void BrowserActionsContainer::Layout() {
// If the icons don't all fit, show the chevron (unless suppressed). // If the icons don't all fit, show the chevron (unless suppressed).
int max_x = GetPreferredSize().width(); int max_x = GetPreferredSize().width();
if ((IconCountToWidth(-1, false) > max_x) && !suppress_chevron_ && chevron_) { if (IconCountToWidth(-1, false) > max_x && !suppress_chevron_ && chevron_) {
chevron_->SetVisible(true); chevron_->SetVisible(true);
gfx::Size chevron_size(chevron_->GetPreferredSize()); gfx::Size chevron_size(chevron_->GetPreferredSize());
max_x -= max_x -=
...@@ -447,14 +414,6 @@ bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) { ...@@ -447,14 +414,6 @@ bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) {
int BrowserActionsContainer::OnDragUpdated( int BrowserActionsContainer::OnDragUpdated(
const ui::DropTargetEvent& event) { const ui::DropTargetEvent& event) {
// First check if we are above the chevron (overflow) menu.
if (chevron_ && GetEventHandlerForPoint(event.location()) == chevron_) {
if (!show_menu_task_factory_.HasWeakPtrs() && !overflow_menu_)
StartShowFolderDropMenuTimer();
return ui::DragDropTypes::DRAG_MOVE;
}
StopShowFolderDropMenuTimer();
size_t row_index = 0; size_t row_index = 0;
size_t before_icon_in_row = 0; size_t before_icon_in_row = 0;
// If there are no visible browser actions (such as when dragging an icon to // If there are no visible browser actions (such as when dragging an icon to
...@@ -534,7 +493,6 @@ int BrowserActionsContainer::OnDragUpdated( ...@@ -534,7 +493,6 @@ int BrowserActionsContainer::OnDragUpdated(
} }
void BrowserActionsContainer::OnDragExited() { void BrowserActionsContainer::OnDragExited() {
StopShowFolderDropMenuTimer();
drop_position_.reset(); drop_position_.reset();
SchedulePaint(); SchedulePaint();
} }
...@@ -596,21 +554,6 @@ void BrowserActionsContainer::GetAccessibleState( ...@@ -596,21 +554,6 @@ void BrowserActionsContainer::GetAccessibleState(
state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS); 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(),
false);
overflow_menu_->set_observer(this);
overflow_menu_->RunMenu(GetWidget());
}
}
void BrowserActionsContainer::WriteDragDataForView(View* sender, void BrowserActionsContainer::WriteDragDataForView(View* sender,
const gfx::Point& press_pt, const gfx::Point& press_pt,
OSExchangeData* data) { OSExchangeData* data) {
...@@ -692,12 +635,6 @@ void BrowserActionsContainer::AnimationEnded(const gfx::Animation* animation) { ...@@ -692,12 +635,6 @@ void BrowserActionsContainer::AnimationEnded(const gfx::Animation* animation) {
OnBrowserActionsContainerAnimationEnded()); OnBrowserActionsContainerAnimationEnded());
} }
void BrowserActionsContainer::NotifyMenuDeleted(
BrowserActionOverflowMenuController* controller) {
DCHECK_EQ(overflow_menu_, controller);
overflow_menu_ = NULL;
}
content::WebContents* BrowserActionsContainer::GetCurrentWebContents() { content::WebContents* BrowserActionsContainer::GetCurrentWebContents() {
return browser_->tab_strip_model()->GetActiveWebContents(); return browser_->tab_strip_model()->GetActiveWebContents();
} }
...@@ -819,7 +756,8 @@ void BrowserActionsContainer::ToolbarExtensionAdded(const Extension* extension, ...@@ -819,7 +756,8 @@ void BrowserActionsContainer::ToolbarExtensionAdded(const Extension* extension,
"exists."; "exists.";
} }
#endif #endif
CloseOverflowMenu(); if (chevron_)
chevron_->CloseMenu();
if (!ShouldDisplayBrowserAction(extension)) if (!ShouldDisplayBrowserAction(extension))
return; return;
...@@ -866,7 +804,8 @@ void BrowserActionsContainer::ToolbarExtensionAdded(const Extension* extension, ...@@ -866,7 +804,8 @@ void BrowserActionsContainer::ToolbarExtensionAdded(const Extension* extension,
void BrowserActionsContainer::ToolbarExtensionRemoved( void BrowserActionsContainer::ToolbarExtensionRemoved(
const Extension* extension) { const Extension* extension) {
CloseOverflowMenu(); if (chevron_)
chevron_->CloseMenu();
size_t visible_actions = VisibleBrowserActionsAfterAnimation(); size_t visible_actions = VisibleBrowserActionsAfterAnimation();
for (BrowserActionViews::iterator i(browser_action_views_.begin()); for (BrowserActionViews::iterator i(browser_action_views_.begin());
...@@ -1008,36 +947,6 @@ void BrowserActionsContainer::SetChevronVisibility() { ...@@ -1008,36 +947,6 @@ void BrowserActionsContainer::SetChevronVisibility() {
} }
} }
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_);
overflow_menu_ =
new BrowserActionOverflowMenuController(this,
browser_,
chevron_,
browser_action_views_,
VisibleBrowserActions(),
true);
overflow_menu_->set_observer(this);
overflow_menu_->RunMenu(GetWidget());
}
int BrowserActionsContainer::IconCountToWidth(int icons, int BrowserActionsContainer::IconCountToWidth(int icons,
bool display_chevron) const { bool display_chevron) const {
if (icons < 0) if (icons < 0)
......
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
#include "base/observer_list.h" #include "base/observer_list.h"
#include "chrome/browser/extensions/extension_keybinding_registry.h" #include "chrome/browser/extensions/extension_keybinding_registry.h"
#include "chrome/browser/extensions/extension_toolbar_model.h" #include "chrome/browser/extensions/extension_toolbar_model.h"
#include "chrome/browser/ui/views/extensions/browser_action_overflow_menu_controller.h"
#include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views.h" #include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views.h"
#include "chrome/browser/ui/views/toolbar/browser_action_view.h" #include "chrome/browser/ui/views/toolbar/browser_action_view.h"
#include "chrome/browser/ui/views/toolbar/chevron_menu_button.h"
#include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/tween.h" #include "ui/gfx/animation/tween.h"
#include "ui/views/controls/button/menu_button_listener.h" #include "ui/views/controls/button/menu_button_listener.h"
...@@ -123,11 +123,9 @@ class ResizeArea; ...@@ -123,11 +123,9 @@ class ResizeArea;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class BrowserActionsContainer class BrowserActionsContainer
: public views::View, : public views::View,
public views::MenuButtonListener,
public views::ResizeAreaDelegate, public views::ResizeAreaDelegate,
public gfx::AnimationDelegate, public gfx::AnimationDelegate,
public extensions::ExtensionToolbarModel::Observer, public extensions::ExtensionToolbarModel::Observer,
public BrowserActionOverflowMenuController::Observer,
public BrowserActionView::Delegate, public BrowserActionView::Delegate,
public extensions::ExtensionKeybindingRegistry::Delegate { public extensions::ExtensionKeybindingRegistry::Delegate {
public: public:
...@@ -218,10 +216,6 @@ class BrowserActionsContainer ...@@ -218,10 +216,6 @@ class BrowserActionsContainer
virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE; virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE;
virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE; virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
// Overridden from views::MenuButtonListener:
virtual void OnMenuButtonClicked(views::View* source,
const gfx::Point& point) OVERRIDE;
// Overridden from views::DragController: // Overridden from views::DragController:
virtual void WriteDragDataForView(View* sender, virtual void WriteDragDataForView(View* sender,
const gfx::Point& press_pt, const gfx::Point& press_pt,
...@@ -239,10 +233,6 @@ class BrowserActionsContainer ...@@ -239,10 +233,6 @@ class BrowserActionsContainer
virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
// Overridden from BrowserActionOverflowMenuController::Observer:
virtual void NotifyMenuDeleted(
BrowserActionOverflowMenuController* controller) OVERRIDE;
// Overridden from BrowserActionView::Delegate: // Overridden from BrowserActionView::Delegate:
virtual content::WebContents* GetCurrentWebContents() OVERRIDE; virtual content::WebContents* GetCurrentWebContents() OVERRIDE;
virtual bool ShownInsideMenu() const OVERRIDE; virtual bool ShownInsideMenu() const OVERRIDE;
...@@ -317,18 +307,6 @@ class BrowserActionsContainer ...@@ -317,18 +307,6 @@ class BrowserActionsContainer
// are displayed. // are displayed.
void SetChevronVisibility(); void SetChevronVisibility();
// Closes the overflow menu if open.
void CloseOverflowMenu();
// Cancels the timer for showing the drop down menu.
void StopShowFolderDropMenuTimer();
// Show the drop down folder after a slight delay.
void StartShowFolderDropMenuTimer();
// Show the overflow menu.
void ShowDropFolder();
// Given a number of |icons| and whether to |display_chevron|, returns the // Given a number of |icons| and whether to |display_chevron|, returns the
// amount of pixels needed to draw the entire container. For convenience, // amount of pixels needed to draw the entire container. For convenience,
// callers can set |icons| to -1 to mean "all icons". // callers can set |icons| to -1 to mean "all icons".
...@@ -398,15 +376,11 @@ class BrowserActionsContainer ...@@ -398,15 +376,11 @@ class BrowserActionsContainer
// The chevron for accessing the overflow items. Can be NULL when in overflow // The chevron for accessing the overflow items. Can be NULL when in overflow
// mode or if the toolbar is permanently suppressing the chevron menu. // mode or if the toolbar is permanently suppressing the chevron menu.
views::MenuButton* chevron_; ChevronMenuButton* chevron_;
// The painter used when we are highlighting a subset of extensions. // The painter used when we are highlighting a subset of extensions.
scoped_ptr<views::Painter> highlight_painter_; scoped_ptr<views::Painter> highlight_painter_;
// The menu to show for the overflow button (chevron). This class manages its
// own lifetime so that it can stay alive during drag and drop operations.
BrowserActionOverflowMenuController* overflow_menu_;
// The animation that happens when the container snaps to place. // The animation that happens when the container snaps to place.
scoped_ptr<gfx::SlideAnimation> resize_animation_; scoped_ptr<gfx::SlideAnimation> resize_animation_;
...@@ -435,9 +409,6 @@ class BrowserActionsContainer ...@@ -435,9 +409,6 @@ class BrowserActionsContainer
// icons in the application menu). // icons in the application menu).
static int icons_per_overflow_menu_row_; static int icons_per_overflow_menu_row_;
// Handles delayed showing of the overflow menu when hovering.
base::WeakPtrFactory<BrowserActionsContainer> show_menu_task_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainer); DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainer);
}; };
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/views/extensions/browser_action_overflow_menu_controller.h" #include "chrome/browser/ui/views/toolbar/chevron_menu_button.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_action.h" #include "chrome/browser/extensions/extension_action.h"
...@@ -11,15 +12,20 @@ ...@@ -11,15 +12,20 @@
#include "chrome/browser/extensions/extension_toolbar_model.h" #include "chrome/browser/extensions/extension_toolbar_model.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
#include "chrome/browser/ui/views/toolbar/browser_action_view.h" #include "chrome/browser/ui/views/toolbar/browser_action_view.h"
#include "chrome/browser/ui/views/toolbar/browser_actions_container.h" #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "extensions/common/extension_set.h" #include "extensions/common/extension_set.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/label_button_border.h"
#include "ui/views/controls/menu/menu_delegate.h"
#include "ui/views/controls/menu/menu_item_view.h" #include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/metrics.h"
namespace {
// In the browser actions container's chevron menu, a menu item view's icon // In the browser actions container's chevron menu, a menu item view's icon
// comes from BrowserActionView::GetIconWithBadge() when the menu item view is // comes from BrowserActionView::GetIconWithBadge() when the menu item view is
...@@ -40,7 +46,7 @@ class IconUpdater : public BrowserActionView::IconObserver { ...@@ -40,7 +46,7 @@ class IconUpdater : public BrowserActionView::IconObserver {
view_->set_icon_observer(NULL); view_->set_icon_observer(NULL);
} }
// Overridden from BrowserActionView::IconObserver: // BrowserActionView::IconObserver:
virtual void OnIconUpdated(const gfx::ImageSkia& icon) OVERRIDE { virtual void OnIconUpdated(const gfx::ImageSkia& icon) OVERRIDE {
menu_item_view_->SetIcon(icon); menu_item_view_->SetIcon(icon);
} }
...@@ -56,20 +62,92 @@ class IconUpdater : public BrowserActionView::IconObserver { ...@@ -56,20 +62,92 @@ class IconUpdater : public BrowserActionView::IconObserver {
DISALLOW_COPY_AND_ASSIGN(IconUpdater); DISALLOW_COPY_AND_ASSIGN(IconUpdater);
}; };
BrowserActionOverflowMenuController::BrowserActionOverflowMenuController( } // namespace
BrowserActionsContainer* owner,
Browser* browser, // This class handles the overflow menu for browser actions.
views::MenuButton* menu_button, class ChevronMenuButton::MenuController : public views::MenuDelegate {
const std::vector<BrowserActionView*>& views, public:
int start_index, MenuController(ChevronMenuButton* owner,
BrowserActionsContainer* browser_actions_container,
bool for_drop);
virtual ~MenuController();
// Shows the overflow menu.
void RunMenu(views::Widget* widget);
// Closes the overflow menu (and its context menu if open as well).
void CloseMenu();
private:
// views::MenuDelegate:
virtual bool IsCommandEnabled(int id) const OVERRIDE;
virtual void ExecuteCommand(int id) OVERRIDE;
virtual bool ShowContextMenu(views::MenuItemView* source,
int id,
const gfx::Point& p,
ui::MenuSourceType source_type) OVERRIDE;
virtual void DropMenuClosed(views::MenuItemView* menu) OVERRIDE;
// These drag functions offer support for dragging icons into the overflow
// menu.
virtual bool GetDropFormats(
views::MenuItemView* menu,
int* formats,
std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
virtual bool AreDropTypesRequired(views::MenuItemView* menu) OVERRIDE;
virtual bool CanDrop(views::MenuItemView* menu,
const ui::OSExchangeData& data) OVERRIDE;
virtual int GetDropOperation(views::MenuItemView* item,
const ui::DropTargetEvent& event,
DropPosition* position) OVERRIDE;
virtual int OnPerformDrop(views::MenuItemView* menu,
DropPosition position,
const ui::DropTargetEvent& event) OVERRIDE;
// These three drag functions offer support for dragging icons out of the
// overflow menu.
virtual bool CanDrag(views::MenuItemView* menu) OVERRIDE;
virtual void WriteDragData(views::MenuItemView* sender,
ui::OSExchangeData* data) OVERRIDE;
virtual int GetDragOperations(views::MenuItemView* sender) OVERRIDE;
// Returns the offset into |views_| for the given |id|.
size_t IndexForId(int id) const;
// The owning ChevronMenuButton.
ChevronMenuButton* owner_;
// A pointer to the browser action container.
BrowserActionsContainer* browser_actions_container_;
// The overflow menu for the menu button. Owned by |menu_runner_|.
views::MenuItemView* menu_;
// Resposible for running the menu.
scoped_ptr<views::MenuRunner> menu_runner_;
// The index into the BrowserActionView vector, indicating where to start
// picking browser actions to draw.
int start_index_;
// Whether this controller is being used for drop.
bool for_drop_;
// The vector keeps all icon updaters associated with menu item views in the
// controller. The icon updater will update the menu item view's icon when
// the browser action view's icon has been updated.
ScopedVector<IconUpdater> icon_updaters_;
DISALLOW_COPY_AND_ASSIGN(MenuController);
};
ChevronMenuButton::MenuController::MenuController(
ChevronMenuButton* owner,
BrowserActionsContainer* browser_actions_container,
bool for_drop) bool for_drop)
: owner_(owner), : owner_(owner),
browser_(browser), browser_actions_container_(browser_actions_container),
observer_(NULL),
menu_button_(menu_button),
menu_(NULL), menu_(NULL),
views_(views), start_index_(
start_index_(start_index), browser_actions_container_->VisibleBrowserActionsAfterAnimation()),
for_drop_(for_drop) { for_drop_(for_drop) {
menu_ = new views::MenuItemView(this); menu_ = new views::MenuItemView(this);
menu_runner_.reset(new views::MenuRunner( menu_runner_.reset(new views::MenuRunner(
...@@ -77,8 +155,10 @@ BrowserActionOverflowMenuController::BrowserActionOverflowMenuController( ...@@ -77,8 +155,10 @@ BrowserActionOverflowMenuController::BrowserActionOverflowMenuController(
menu_->set_has_icons(true); menu_->set_has_icons(true);
size_t command_id = 1; // Menu id 0 is reserved, start with 1. size_t command_id = 1; // Menu id 0 is reserved, start with 1.
for (size_t i = start_index; i < views_.size(); ++i) { for (size_t i = start_index_;
BrowserActionView* view = views_[i]; i < browser_actions_container_->num_browser_actions(); ++i) {
BrowserActionView* view =
browser_actions_container_->GetBrowserActionViewAt(i);
views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon( views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon(
command_id, command_id,
base::UTF8ToUTF16(view->extension()->name()), base::UTF8ToUTF16(view->extension()->name()),
...@@ -96,71 +176,77 @@ BrowserActionOverflowMenuController::BrowserActionOverflowMenuController( ...@@ -96,71 +176,77 @@ BrowserActionOverflowMenuController::BrowserActionOverflowMenuController(
} }
} }
BrowserActionOverflowMenuController::~BrowserActionOverflowMenuController() { ChevronMenuButton::MenuController::~MenuController() {
if (observer_)
observer_->NotifyMenuDeleted(this);
} }
bool BrowserActionOverflowMenuController::RunMenu(views::Widget* window) { void ChevronMenuButton::MenuController::RunMenu(views::Widget* window) {
gfx::Rect bounds = menu_button_->bounds(); gfx::Rect bounds = owner_->bounds();
gfx::Point screen_loc; gfx::Point screen_loc;
views::View::ConvertPointToScreen(menu_button_, &screen_loc); views::View::ConvertPointToScreen(owner_, &screen_loc);
bounds.set_x(screen_loc.x()); bounds.set_x(screen_loc.x());
bounds.set_y(screen_loc.y()); bounds.set_y(screen_loc.y());
views::MenuAnchorPosition anchor = views::MENU_ANCHOR_TOPRIGHT; if (menu_runner_->RunMenuAt(window,
// As we maintain our own lifetime we can safely ignore the result. owner_,
ignore_result(menu_runner_->RunMenuAt( bounds,
window, menu_button_, bounds, anchor, ui::MENU_SOURCE_NONE)); views::MENU_ANCHOR_TOPRIGHT,
ui::MENU_SOURCE_NONE) ==
views::MenuRunner::MENU_DELETED)
return;
if (!for_drop_) { if (!for_drop_) {
// Give the context menu (if any) a chance to execute the user-selected // Give the context menu (if any) a chance to execute the user-selected
// command. // command.
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ChevronMenuButton::MenuDone,
owner_->weak_factory_.GetWeakPtr()));
} }
return true;
} }
void BrowserActionOverflowMenuController::CancelMenu() { void ChevronMenuButton::MenuController::CloseMenu() {
menu_->Cancel(); menu_->Cancel();
} }
void BrowserActionOverflowMenuController::NotifyBrowserActionViewsDeleting() { bool ChevronMenuButton::MenuController::IsCommandEnabled(int id) const {
icon_updaters_.clear(); BrowserActionView* view =
} browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1);
bool BrowserActionOverflowMenuController::IsCommandEnabled(int id) const {
BrowserActionView* view = views_[start_index_ + id - 1];
return view->IsEnabled(view->view_controller()->GetCurrentTabId()); return view->IsEnabled(view->view_controller()->GetCurrentTabId());
} }
void BrowserActionOverflowMenuController::ExecuteCommand(int id) { void ChevronMenuButton::MenuController::ExecuteCommand(int id) {
views_[start_index_ + id - 1]->view_controller()->ExecuteActionByUser(); browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1)->
view_controller()->ExecuteActionByUser();
} }
bool BrowserActionOverflowMenuController::ShowContextMenu( bool ChevronMenuButton::MenuController::ShowContextMenu(
views::MenuItemView* source, views::MenuItemView* source,
int id, int id,
const gfx::Point& p, const gfx::Point& p,
ui::MenuSourceType source_type) { ui::MenuSourceType source_type) {
BrowserActionView* view = views_[start_index_ + id - 1]; BrowserActionView* view = browser_actions_container_->GetBrowserActionViewAt(
start_index_ + id - 1);
if (!view->extension()->ShowConfigureContextMenus()) if (!view->extension()->ShowConfigureContextMenus())
return false; return false;
scoped_refptr<ExtensionContextMenuModel> context_menu_contents = scoped_refptr<ExtensionContextMenuModel> context_menu_contents =
new ExtensionContextMenuModel( new ExtensionContextMenuModel(view->extension(),
view->extension(), browser_, view->view_controller()); view->view_controller()->browser(),
view->view_controller());
views::MenuRunner context_menu_runner(context_menu_contents.get(), views::MenuRunner context_menu_runner(context_menu_contents.get(),
views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::HAS_MNEMONICS |
views::MenuRunner::IS_NESTED | views::MenuRunner::IS_NESTED |
views::MenuRunner::CONTEXT_MENU); views::MenuRunner::CONTEXT_MENU);
// We can ignore the result as we delete ourself. // We can ignore the result as we delete ourself.
// This blocks until the user choses something or dismisses the menu. // This blocks until the user chooses something or dismisses the menu.
ignore_result(context_menu_runner.RunMenuAt(menu_button_->GetWidget(), if (context_menu_runner.RunMenuAt(owner_->GetWidget(),
NULL, NULL,
gfx::Rect(p, gfx::Size()), gfx::Rect(p, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT, views::MENU_ANCHOR_TOPLEFT,
source_type)); source_type) ==
views::MenuRunner::MENU_DELETED)
return true;
// The user is done with the context menu, so we can close the underlying // The user is done with the context menu, so we can close the underlying
// menu. // menu.
...@@ -169,29 +255,30 @@ bool BrowserActionOverflowMenuController::ShowContextMenu( ...@@ -169,29 +255,30 @@ bool BrowserActionOverflowMenuController::ShowContextMenu(
return true; return true;
} }
void BrowserActionOverflowMenuController::DropMenuClosed( void ChevronMenuButton::MenuController::DropMenuClosed(
views::MenuItemView* menu) { views::MenuItemView* menu) {
delete this; owner_->MenuDone();
} }
bool BrowserActionOverflowMenuController::GetDropFormats( bool ChevronMenuButton::MenuController::GetDropFormats(
views::MenuItemView* menu, views::MenuItemView* menu,
int* formats, int* formats,
std::set<OSExchangeData::CustomFormat>* custom_formats) { std::set<OSExchangeData::CustomFormat>* custom_formats) {
return BrowserActionDragData::GetDropFormats(custom_formats); return BrowserActionDragData::GetDropFormats(custom_formats);
} }
bool BrowserActionOverflowMenuController::AreDropTypesRequired( bool ChevronMenuButton::MenuController::AreDropTypesRequired(
views::MenuItemView* menu) { views::MenuItemView* menu) {
return BrowserActionDragData::AreDropTypesRequired(); return BrowserActionDragData::AreDropTypesRequired();
} }
bool BrowserActionOverflowMenuController::CanDrop( bool ChevronMenuButton::MenuController::CanDrop(
views::MenuItemView* menu, const OSExchangeData& data) { views::MenuItemView* menu, const OSExchangeData& data) {
return BrowserActionDragData::CanDrop(data, owner_->profile()); return BrowserActionDragData::CanDrop(data,
browser_actions_container_->profile());
} }
int BrowserActionOverflowMenuController::GetDropOperation( int ChevronMenuButton::MenuController::GetDropOperation(
views::MenuItemView* item, views::MenuItemView* item,
const ui::DropTargetEvent& event, const ui::DropTargetEvent& event,
DropPosition* position) { DropPosition* position) {
...@@ -204,14 +291,14 @@ int BrowserActionOverflowMenuController::GetDropOperation( ...@@ -204,14 +291,14 @@ int BrowserActionOverflowMenuController::GetDropOperation(
if (!drop_data.Read(event.data())) if (!drop_data.Read(event.data()))
return ui::DragDropTypes::DRAG_NONE; return ui::DragDropTypes::DRAG_NONE;
if (drop_data.index() < owner_->VisibleBrowserActions()) if (drop_data.index() < browser_actions_container_->VisibleBrowserActions())
return ui::DragDropTypes::DRAG_NONE; return ui::DragDropTypes::DRAG_NONE;
} }
return ui::DragDropTypes::DRAG_MOVE; return ui::DragDropTypes::DRAG_MOVE;
} }
int BrowserActionOverflowMenuController::OnPerformDrop( int ChevronMenuButton::MenuController::OnPerformDrop(
views::MenuItemView* menu, views::MenuItemView* menu,
DropPosition position, DropPosition position,
const ui::DropTargetEvent& event) { const ui::DropTargetEvent& event) {
...@@ -224,49 +311,132 @@ int BrowserActionOverflowMenuController::OnPerformDrop( ...@@ -224,49 +311,132 @@ int BrowserActionOverflowMenuController::OnPerformDrop(
// When not dragging within the overflow menu (dragging an icon into the menu) // When not dragging within the overflow menu (dragging an icon into the menu)
// subtract one to get the right index. // subtract one to get the right index.
if (position == DROP_BEFORE && if (position == DROP_BEFORE &&
drop_data.index() < owner_->VisibleBrowserActions()) drop_data.index() < browser_actions_container_->VisibleBrowserActions())
--drop_index; --drop_index;
Profile* profile = browser_actions_container_->profile();
// Move the extension in the model. // Move the extension in the model.
const extensions::Extension* extension = const extensions::Extension* extension =
extensions::ExtensionRegistry::Get(browser_->profile())-> extensions::ExtensionRegistry::Get(profile)->
enabled_extensions().GetByID(drop_data.id()); enabled_extensions().GetByID(drop_data.id());
extensions::ExtensionToolbarModel* toolbar_model = extensions::ExtensionToolbarModel* toolbar_model =
extensions::ExtensionToolbarModel::Get(browser_->profile()); extensions::ExtensionToolbarModel::Get(profile);
if (browser_->profile()->IsOffTheRecord()) if (profile->IsOffTheRecord())
drop_index = toolbar_model->IncognitoIndexToOriginal(drop_index); drop_index = toolbar_model->IncognitoIndexToOriginal(drop_index);
toolbar_model->MoveExtensionIcon(extension, drop_index); toolbar_model->MoveExtensionIcon(extension, drop_index);
// If the extension was moved to the overflow menu from the main bar, notify // If the extension was moved to the overflow menu from the main bar, notify
// the owner. // the owner.
if (drop_data.index() < owner_->VisibleBrowserActions()) if (drop_data.index() < browser_actions_container_->VisibleBrowserActions())
owner_->NotifyActionMovedToOverflow(); browser_actions_container_->NotifyActionMovedToOverflow();
if (for_drop_) if (for_drop_)
delete this; owner_->MenuDone();
return ui::DragDropTypes::DRAG_MOVE; return ui::DragDropTypes::DRAG_MOVE;
} }
bool BrowserActionOverflowMenuController::CanDrag(views::MenuItemView* menu) { bool ChevronMenuButton::MenuController::CanDrag(views::MenuItemView* menu) {
return true; return true;
} }
void BrowserActionOverflowMenuController::WriteDragData( void ChevronMenuButton::MenuController::WriteDragData(
views::MenuItemView* sender, OSExchangeData* data) { views::MenuItemView* sender, OSExchangeData* data) {
size_t drag_index = IndexForId(sender->GetCommand()); size_t drag_index = IndexForId(sender->GetCommand());
const extensions::Extension* extension = views_[drag_index]->extension(); const extensions::Extension* extension =
browser_actions_container_->GetBrowserActionViewAt(drag_index)->
extension();
BrowserActionDragData drag_data(extension->id(), drag_index); BrowserActionDragData drag_data(extension->id(), drag_index);
drag_data.Write(owner_->profile(), data); drag_data.Write(browser_actions_container_->profile(), data);
} }
int BrowserActionOverflowMenuController::GetDragOperations( int ChevronMenuButton::MenuController::GetDragOperations(
views::MenuItemView* sender) { views::MenuItemView* sender) {
return ui::DragDropTypes::DRAG_MOVE; return ui::DragDropTypes::DRAG_MOVE;
} }
size_t BrowserActionOverflowMenuController::IndexForId(int id) const { size_t ChevronMenuButton::MenuController::IndexForId(int id) const {
// The index of the view being dragged (GetCommand gives a 1-based index into // The index of the view being dragged (GetCommand gives a 1-based index into
// the overflow menu). // the overflow menu).
DCHECK_GT(owner_->VisibleBrowserActions() + id, 0u); DCHECK_GT(browser_actions_container_->VisibleBrowserActions() + id, 0u);
return owner_->VisibleBrowserActions() + id - 1; return browser_actions_container_->VisibleBrowserActions() + id - 1;
}
ChevronMenuButton::ChevronMenuButton(
BrowserActionsContainer* browser_actions_container)
: views::MenuButton(NULL, base::string16(), this, false),
browser_actions_container_(browser_actions_container),
weak_factory_(this) {
}
ChevronMenuButton::~ChevronMenuButton() {
}
void ChevronMenuButton::CloseMenu() {
if (menu_controller_)
menu_controller_->CloseMenu();
}
scoped_ptr<views::LabelButtonBorder> ChevronMenuButton::CreateDefaultBorder()
const {
// The chevron resource was designed to not have any insets.
scoped_ptr<views::LabelButtonBorder> border =
views::MenuButton::CreateDefaultBorder();
border->set_insets(gfx::Insets());
return border.Pass();
}
bool ChevronMenuButton::GetDropFormats(
int* formats,
std::set<OSExchangeData::CustomFormat>* custom_formats) {
return BrowserActionDragData::GetDropFormats(custom_formats);
}
bool ChevronMenuButton::AreDropTypesRequired() {
return BrowserActionDragData::AreDropTypesRequired();
}
bool ChevronMenuButton::CanDrop(const OSExchangeData& data) {
return BrowserActionDragData::CanDrop(
data, browser_actions_container_->profile());
}
void ChevronMenuButton::OnDragEntered(const ui::DropTargetEvent& event) {
DCHECK(!weak_factory_.HasWeakPtrs());
if (!menu_controller_) {
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&ChevronMenuButton::ShowOverflowMenu,
weak_factory_.GetWeakPtr(),
true),
base::TimeDelta::FromMilliseconds(views::GetMenuShowDelay()));
}
}
int ChevronMenuButton::OnDragUpdated(const ui::DropTargetEvent& event) {
return ui::DragDropTypes::DRAG_MOVE;
}
void ChevronMenuButton::OnDragExited() {
weak_factory_.InvalidateWeakPtrs();
}
int ChevronMenuButton::OnPerformDrop(const ui::DropTargetEvent& event) {
return ui::DragDropTypes::DRAG_MOVE;
}
void ChevronMenuButton::OnMenuButtonClicked(views::View* source,
const gfx::Point& point) {
DCHECK_EQ(this, source);
ShowOverflowMenu(false);
}
void ChevronMenuButton::ShowOverflowMenu(bool for_drop) {
DCHECK(!menu_controller_);
menu_controller_.reset(new MenuController(
this, browser_actions_container_, for_drop));
menu_controller_->RunMenu(GetWidget());
}
void ChevronMenuButton::MenuDone() {
menu_controller_.reset();
} }
// Copyright 2014 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.
#ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_CHEVRON_MENU_BUTTON_H_
#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_CHEVRON_MENU_BUTTON_H_
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/button/menu_button_listener.h"
class BrowserActionsContainer;
// The MenuButton for the chevron in the extension toolbar, which is also
// responsible for showing the legacy (drop-down) overflow menu.
class ChevronMenuButton : public views::MenuButton,
public views::MenuButtonListener {
public:
explicit ChevronMenuButton(
BrowserActionsContainer* browser_actions_container);
virtual ~ChevronMenuButton();
// Closes the overflow menu (and any context menu), if it is open.
void CloseMenu();
private:
class MenuController;
// views::MenuButton:
virtual scoped_ptr<views::LabelButtonBorder> CreateDefaultBorder() const
OVERRIDE;
virtual bool GetDropFormats(int* formats,
std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
virtual bool AreDropTypesRequired() OVERRIDE;
virtual bool CanDrop(const ui::OSExchangeData& data) OVERRIDE;
virtual void OnDragEntered(const ui::DropTargetEvent& event) OVERRIDE;
virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE;
virtual void OnDragExited() OVERRIDE;
virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE;
// views::MenuButtonListener:
virtual void OnMenuButtonClicked(View* source, const gfx::Point& point)
OVERRIDE;
// Shows the overflow menu.
void ShowOverflowMenu(bool for_drop);
// Called by the overflow menu when all the work is done.
void MenuDone();
// The owning BrowserActionsContainer.
BrowserActionsContainer* browser_actions_container_;
// The overflow menu controller.
scoped_ptr<MenuController> menu_controller_;
base::WeakPtrFactory<ChevronMenuButton> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ChevronMenuButton);
};
#endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_CHEVRON_MENU_BUTTON_H_
...@@ -1973,8 +1973,6 @@ ...@@ -1973,8 +1973,6 @@
'browser/ui/views/extensions/bookmark_app_bubble_view.h', 'browser/ui/views/extensions/bookmark_app_bubble_view.h',
'browser/ui/views/extensions/browser_action_drag_data.cc', 'browser/ui/views/extensions/browser_action_drag_data.cc',
'browser/ui/views/extensions/browser_action_drag_data.h', 'browser/ui/views/extensions/browser_action_drag_data.h',
'browser/ui/views/extensions/browser_action_overflow_menu_controller.cc',
'browser/ui/views/extensions/browser_action_overflow_menu_controller.h',
'browser/ui/views/extensions/bundle_installed_bubble.cc', 'browser/ui/views/extensions/bundle_installed_bubble.cc',
'browser/ui/views/extensions/extension_action_view_controller.cc', 'browser/ui/views/extensions/extension_action_view_controller.cc',
'browser/ui/views/extensions/extension_action_view_controller.h', 'browser/ui/views/extensions/extension_action_view_controller.h',
...@@ -2232,6 +2230,8 @@ ...@@ -2232,6 +2230,8 @@
'browser/ui/views/toolbar/browser_action_test_util_views.cc', 'browser/ui/views/toolbar/browser_action_test_util_views.cc',
'browser/ui/views/toolbar/browser_action_view.cc', 'browser/ui/views/toolbar/browser_action_view.cc',
'browser/ui/views/toolbar/browser_action_view.h', 'browser/ui/views/toolbar/browser_action_view.h',
'browser/ui/views/toolbar/chevron_menu_button.cc',
'browser/ui/views/toolbar/chevron_menu_button.h',
'browser/ui/views/toolbar/extension_toolbar_menu_view.cc', 'browser/ui/views/toolbar/extension_toolbar_menu_view.cc',
'browser/ui/views/toolbar/extension_toolbar_menu_view.h', 'browser/ui/views/toolbar/extension_toolbar_menu_view.h',
'browser/ui/views/toolbar/home_button.cc', 'browser/ui/views/toolbar/home_button.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment