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_BROWSER_ACTION_VIEW_H_
6 #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_
10 #include "chrome/browser/extensions/extension_action_icon_factory.h"
11 #include "chrome/browser/extensions/extension_context_menu_model.h"
12 #include "content/public/browser/notification_observer.h"
13 #include "content/public/browser/notification_registrar.h"
14 #include "ui/views/context_menu_controller.h"
15 #include "ui/views/controls/button/menu_button.h"
16 #include "ui/views/controls/button/menu_button_listener.h"
17 #include "ui/views/drag_controller.h"
18 #include "ui/views/view.h"
21 class BrowserActionButton
;
22 class ExtensionAction
;
24 namespace extensions
{
37 ////////////////////////////////////////////////////////////////////////////////
39 // A single entry in the browser action container. This contains the actual
40 // BrowserActionButton, as well as the logic to paint the badge.
41 class BrowserActionView
: public views::View
{
43 // Need DragController here because BrowserActionView could be
45 class Delegate
: public views::DragController
,
46 public ExtensionContextMenuModel::PopupDelegate
{
48 // Returns the current tab's ID, or -1 if there is no current tab.
49 virtual int GetCurrentTabId() const = 0;
51 // Called when the user clicks on the browser action icon.
52 virtual void OnBrowserActionExecuted(BrowserActionButton
* button
) = 0;
54 // Called when a browser action becomes visible/hidden.
55 virtual void OnBrowserActionVisibilityChanged() = 0;
57 // Returns relative position of a button inside BrowserActionView.
58 virtual gfx::Point
GetViewContentOffset() const = 0;
60 virtual bool NeedToShowMultipleIconStates() const;
61 virtual bool NeedToShowTooltip() const;
64 virtual ~Delegate() {}
67 BrowserActionView(const extensions::Extension
* extension
,
70 virtual ~BrowserActionView();
72 BrowserActionButton
* button() { return button_
; }
74 // Gets browser action button icon with the badge.
75 gfx::ImageSkia
GetIconWithBadge();
77 // Overridden from views::View:
78 virtual void Layout() OVERRIDE
;
79 virtual void GetAccessibleState(ui::AccessibleViewState
* state
) OVERRIDE
;
80 virtual gfx::Size
GetPreferredSize() OVERRIDE
;
83 // Overridden from views::View to paint the badge on top of children.
84 virtual void PaintChildren(gfx::Canvas
* canvas
) OVERRIDE
;
87 // The Browser object this view is associated with.
90 // Usually a container for this view.
93 // The button this view contains.
94 BrowserActionButton
* button_
;
96 // Extension this view associated with.
97 const extensions::Extension
* extension_
;
99 DISALLOW_COPY_AND_ASSIGN(BrowserActionView
);
102 ////////////////////////////////////////////////////////////////////////////////
103 // BrowserActionButton
105 // The BrowserActionButton is a specialization of the MenuButton class.
106 // It acts on a ExtensionAction, in this case a BrowserAction and handles
107 // loading the image for the button asynchronously on the file thread.
108 class BrowserActionButton
: public views::MenuButton
,
109 public views::ButtonListener
,
110 public views::ContextMenuController
,
111 public content::NotificationObserver
,
112 public ExtensionActionIconFactory::Observer
{
114 BrowserActionButton(const extensions::Extension
* extension
,
116 BrowserActionView::Delegate
* delegate
);
118 // Call this instead of delete.
121 ExtensionAction
* browser_action() const { return browser_action_
; }
122 const extensions::Extension
* extension() { return extension_
; }
124 // Called to update the display to match the browser action's state.
127 // Does this button's action have a popup?
128 virtual bool IsPopup();
129 virtual GURL
GetPopupUrl();
131 // Overridden from views::View:
132 virtual bool CanHandleAccelerators() const OVERRIDE
;
133 virtual void GetAccessibleState(ui::AccessibleViewState
* state
) OVERRIDE
;
135 // Overridden from views::ButtonListener:
136 virtual void ButtonPressed(views::Button
* sender
,
137 const ui::Event
& event
) OVERRIDE
;
139 // Overridden from views::ContextMenuController.
140 virtual void ShowContextMenuForView(View
* source
,
141 const gfx::Point
& point
,
142 ui::MenuSourceType source_type
) OVERRIDE
;
144 // Overridden from content::NotificationObserver:
145 virtual void Observe(int type
,
146 const content::NotificationSource
& source
,
147 const content::NotificationDetails
& details
) OVERRIDE
;
149 // Overriden from ExtensionActionIconFactory::Observer.
150 virtual void OnIconUpdated() OVERRIDE
;
152 // MenuButton behavior overrides. These methods all default to TextButton
153 // behavior unless this button is a popup. In that case, it uses MenuButton
154 // behavior. MenuButton has the notion of a child popup being shown where the
155 // button will stay in the pushed state until the "menu" (a popup in this
156 // case) is dismissed.
157 virtual bool Activate() OVERRIDE
;
158 virtual bool OnMousePressed(const ui::MouseEvent
& event
) OVERRIDE
;
159 virtual void OnMouseReleased(const ui::MouseEvent
& event
) OVERRIDE
;
160 virtual void OnMouseExited(const ui::MouseEvent
& event
) OVERRIDE
;
161 virtual bool OnKeyReleased(const ui::KeyEvent
& event
) OVERRIDE
;
162 virtual void OnGestureEvent(ui::GestureEvent
* event
) OVERRIDE
;
164 // Overridden from ui::AcceleratorTarget.
165 virtual bool AcceleratorPressed(const ui::Accelerator
& accelerator
) OVERRIDE
;
167 // Notifications when to set button state to pushed/not pushed (for when the
168 // popup/context menu is hidden or shown by the container).
169 void SetButtonPushed();
170 void SetButtonNotPushed();
172 // Whether the browser action is enabled on this tab. Note that we cannot use
173 // the built-in views enabled/SetEnabled because disabled views do not
174 // receive drag events.
175 bool IsEnabled(int tab_id
) const;
177 // Returns icon factory for the button.
178 ExtensionActionIconFactory
& icon_factory() { return icon_factory_
; }
180 // Returns button icon so it can be accessed during tests.
181 gfx::ImageSkia
GetIconForTest();
184 // Overridden from views::View:
185 virtual void ViewHierarchyChanged(
186 const ViewHierarchyChangedDetails
& details
) OVERRIDE
;
189 virtual ~BrowserActionButton();
191 // Register an extension command if the extension has an active one.
192 void MaybeRegisterExtensionCommand();
194 // Unregisters an extension command, if the extension has registered one and
196 void MaybeUnregisterExtensionCommand(bool only_if_active
);
198 // The Browser object this button is associated with.
201 // The browser action this view represents. The ExtensionAction is not owned
203 ExtensionAction
* browser_action_
;
205 // The extension associated with the browser action we're displaying.
206 const extensions::Extension
* extension_
;
208 // The object that will be used to get the browser action icon for us.
209 // It may load the icon asynchronously (in which case the initial icon
210 // returned by the factory will be transparent), so we have to observe it for
211 // updates to the icon.
212 ExtensionActionIconFactory icon_factory_
;
214 // Delegate that usually represents a container for BrowserActionView.
215 BrowserActionView::Delegate
* delegate_
;
217 // The context menu. This member is non-NULL only when the menu is shown.
218 views::MenuItemView
* context_menu_
;
220 // Used to make sure MaybeRegisterExtensionCommand() is called only once
221 // from ViewHierarchyChanged().
222 bool called_registered_extension_command_
;
224 content::NotificationRegistrar registrar_
;
226 // The extension key binding accelerator this browser action is listening for
227 // (to show the popup).
228 scoped_ptr
<ui::Accelerator
> keybinding_
;
230 // Responsible for running the menu.
231 scoped_ptr
<views::MenuRunner
> menu_runner_
;
233 friend class base::DeleteHelper
<BrowserActionButton
>;
235 DISALLOW_COPY_AND_ASSIGN(BrowserActionButton
);
238 #endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_