1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ACTION_VIEW_H_
6 #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ACTION_VIEW_H_
8 #include "chrome/browser/ui/views/toolbar/toolbar_action_view_delegate_views.h"
9 #include "content/public/browser/notification_observer.h"
10 #include "content/public/browser/notification_registrar.h"
11 #include "ui/views/controls/button/menu_button.h"
12 #include "ui/views/controls/button/menu_button_listener.h"
13 #include "ui/views/drag_controller.h"
14 #include "ui/views/view.h"
16 class ExtensionAction
;
19 namespace extensions
{
27 ////////////////////////////////////////////////////////////////////////////////
29 // A wrapper around a ToolbarActionViewController to display a toolbar action
30 // action in the BrowserActionsContainer.
31 class ToolbarActionView
: public views::MenuButton
,
32 public ToolbarActionViewDelegateViews
,
33 public views::ButtonListener
,
34 public content::NotificationObserver
{
36 // Need DragController here because ToolbarActionView could be
38 class Delegate
: public views::DragController
{
40 // Returns the current web contents.
41 virtual content::WebContents
* GetCurrentWebContents() = 0;
43 // Whether the container for this button is shown inside a menu.
44 virtual bool ShownInsideMenu() const = 0;
46 // Notifies that a drag completed.
47 virtual void OnToolbarActionViewDragDone() = 0;
49 // Returns the view of the toolbar actions overflow menu to use as a
50 // reference point for a popup when this view isn't visible.
51 virtual views::MenuButton
* GetOverflowReferenceView() = 0;
53 // Sets the delegate's active popup owner to be |popup_owner|.
54 virtual void SetPopupOwner(ToolbarActionView
* popup_owner
) = 0;
56 // Returns the primary ToolbarActionView associated with the given
58 virtual ToolbarActionView
* GetMainViewForAction(
59 ToolbarActionView
* view
) = 0;
62 ~Delegate() override
{}
65 ToolbarActionView(ToolbarActionViewController
* view_controller
,
68 ~ToolbarActionView() override
;
70 // Modifies the given |border| in order to display a "popped out" for when
71 // an action wants to run.
72 static void DecorateWantsToRunBorder(views::LabelButtonBorder
* border
);
75 void GetAccessibleState(ui::AXViewState
* state
) override
;
77 // views::ButtonListener:
78 void ButtonPressed(views::Button
* sender
, const ui::Event
& event
) override
;
80 // content::NotificationObserver:
81 void Observe(int type
,
82 const content::NotificationSource
& source
,
83 const content::NotificationDetails
& details
) override
;
85 // MenuButton behavior overrides. These methods all default to LabelButton
86 // behavior unless this button is a popup. In that case, it uses MenuButton
87 // behavior. MenuButton has the notion of a child popup being shown where the
88 // button will stay in the pushed state until the "menu" (a popup in this
89 // case) is dismissed.
90 // TODO(devlin): This is a good idea, but it has some funny UI side-effects,
91 // like the fact that label buttons enter a pressed state immediately, but
92 // menu buttons only enter a pressed state on release (if they're draggable).
93 // We should probably just pick a behavior, and stick to it.
94 bool Activate() override
;
95 bool OnMousePressed(const ui::MouseEvent
& event
) override
;
96 void OnMouseReleased(const ui::MouseEvent
& event
) override
;
97 void OnMouseExited(const ui::MouseEvent
& event
) override
;
98 bool OnKeyReleased(const ui::KeyEvent
& event
) override
;
99 void OnGestureEvent(ui::GestureEvent
* event
) override
;
100 scoped_ptr
<views::LabelButtonBorder
> CreateDefaultBorder() const override
;
101 bool ShouldEnterPushedState(const ui::Event
& event
) override
;
103 // ToolbarActionViewDelegate: (public because called by others).
104 void UpdateState() override
;
105 content::WebContents
* GetCurrentWebContents() const override
;
107 ToolbarActionViewController
* view_controller() {
108 return view_controller_
;
111 // Returns button icon so it can be accessed during tests.
112 gfx::ImageSkia
GetIconForTest();
114 bool wants_to_run_for_testing() const { return wants_to_run_
; }
117 // views::MenuButton:
118 gfx::Size
GetPreferredSize() const override
;
119 const char* GetClassName() const override
;
120 void OnDragDone() override
;
121 void ViewHierarchyChanged(
122 const ViewHierarchyChangedDetails
& details
) override
;
123 void PaintChildren(const PaintContext
& context
) override
;
124 void OnPaintBorder(gfx::Canvas
* canvas
) override
;
126 // ToolbarActionViewDelegateViews:
127 views::View
* GetAsView() override
;
128 bool IsShownInMenu() override
;
129 views::FocusManager
* GetFocusManagerForAccelerator() override
;
130 views::Widget
* GetParentForContextMenu() override
;
131 ToolbarActionViewController
* GetPreferredPopupViewController() override
;
132 views::View
* GetReferenceViewForPopup() override
;
133 views::MenuButton
* GetContextMenuButton() override
;
134 void OnPopupShown(bool by_user
) override
;
135 void OnPopupClosed() override
;
137 // A lock to keep the MenuButton pressed when a menu or popup is visible.
138 scoped_ptr
<views::MenuButton::PressedLock
> pressed_lock_
;
140 // The controller for this toolbar action view.
141 ToolbarActionViewController
* view_controller_
;
143 // The associated profile.
146 // Delegate that usually represents a container for ToolbarActionView.
149 // Used to make sure we only register the command once.
150 bool called_register_command_
;
152 // The cached value of whether or not the action wants to run on the current
156 // A special border to draw when the action wants to run.
157 scoped_ptr
<views::LabelButtonBorder
> wants_to_run_border_
;
159 content::NotificationRegistrar registrar_
;
161 DISALLOW_COPY_AND_ASSIGN(ToolbarActionView
);
164 #endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ACTION_VIEW_H_