browser_action_view.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson// Copyright 2013 The Chromium Authors. All rights reserved.
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// Use of this source code is governed by a BSD-style license that can be
3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson// found in the LICENSE file.
4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_
6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_
7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "chrome/browser/ui/views/extensions/extension_action_view_controller.h"
9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "chrome/browser/ui/views/extensions/extension_action_view_delegate.h"
10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "content/public/browser/notification_observer.h"
11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "content/public/browser/notification_registrar.h"
12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "ui/views/controls/button/menu_button.h"
13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "ui/views/controls/button/menu_button_listener.h"
14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "ui/views/drag_controller.h"
15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "ui/views/view.h"
16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass Browser;
18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonclass ExtensionAction;
19090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertnamespace extensions {
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass Extension;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertnamespace gfx {
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass Image;
26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson}
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson////////////////////////////////////////////////////////////////////////////////
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// BrowserActionView
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// A wrapper around an ExtensionActionViewController to display an extension
31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson// action in the BrowserActionsContainer.
32// Despite its name, this class can handle either Browser Actions or Page
33// Actions.
34// TODO(devlin): Rename this and BrowserActionsContainer when more of the
35// toolbar redesign is done.
36class BrowserActionView : public views::MenuButton,
37                          public ExtensionActionViewDelegate,
38                          public views::ButtonListener,
39                          public content::NotificationObserver {
40 public:
41  // Need DragController here because BrowserActionView could be
42  // dragged/dropped.
43  class Delegate : public views::DragController {
44   public:
45    // Returns the current web contents.
46    virtual content::WebContents* GetCurrentWebContents() = 0;
47
48    // Whether the container for this button is shown inside a menu.
49    virtual bool ShownInsideMenu() const = 0;
50
51    // Notifies that a drag completed. Note this will only happen if the view
52    // wasn't removed during the drag-and-drop process (i.e., not when there
53    // was a move in the browser actions, since we re-create the views each
54    // time we re-order the browser actions).
55    virtual void OnBrowserActionViewDragDone() = 0;
56
57    // Returns the view of the browser actions overflow menu to use as a
58    // reference point for a popup when this view isn't visible.
59    virtual views::MenuButton* GetOverflowReferenceView() = 0;
60
61    // Sets the delegate's active popup owner to be |popup_owner|.
62    virtual void SetPopupOwner(BrowserActionView* popup_owner) = 0;
63
64    // Hides the active popup of the delegate, if one exists.
65    virtual void HideActivePopup() = 0;
66
67    // Returns the primary BrowserActionView associated with the given
68    // |extension|.
69    virtual BrowserActionView* GetMainViewForExtension(
70        const extensions::Extension* extension) = 0;
71
72   protected:
73    virtual ~Delegate() {}
74  };
75
76  // The IconObserver will receive a notification when the button's icon has
77  // been updated.
78  class IconObserver {
79   public:
80    virtual void OnIconUpdated(const gfx::ImageSkia& icon) = 0;
81
82   protected:
83    virtual ~IconObserver() {}
84  };
85
86  BrowserActionView(const extensions::Extension* extension,
87                    ExtensionAction* extension_action,
88                    Browser* browser,
89                    BrowserActionView::Delegate* delegate);
90  virtual ~BrowserActionView();
91
92  const extensions::Extension* extension() const {
93    return view_controller_->extension();
94  }
95  ExtensionAction* extension_action() {
96    return view_controller_->extension_action();
97  }
98  ExtensionActionViewController* view_controller() {
99    return view_controller_.get();
100  }
101  void set_icon_observer(IconObserver* icon_observer) {
102    icon_observer_ = icon_observer;
103  }
104
105  // Called to update the display to match the browser action's state.
106  void UpdateState();
107
108  // Does this button's action have a popup?
109  bool IsPopup();
110
111  // Overridden from views::View:
112  virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
113
114  // Overridden from views::ButtonListener:
115  virtual void ButtonPressed(views::Button* sender,
116                             const ui::Event& event) OVERRIDE;
117
118  // Overridden from content::NotificationObserver:
119  virtual void Observe(int type,
120                       const content::NotificationSource& source,
121                       const content::NotificationDetails& details) OVERRIDE;
122
123  // MenuButton behavior overrides.  These methods all default to LabelButton
124  // behavior unless this button is a popup.  In that case, it uses MenuButton
125  // behavior.  MenuButton has the notion of a child popup being shown where the
126  // button will stay in the pushed state until the "menu" (a popup in this
127  // case) is dismissed.
128  virtual bool Activate() OVERRIDE;
129  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
130  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
131  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
132  virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE;
133  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
134  virtual scoped_ptr<views::LabelButtonBorder> CreateDefaultBorder() const
135      OVERRIDE;
136
137  // Whether the browser action is enabled on this tab. Note that we cannot use
138  // the built-in views enabled/SetEnabled because disabled views do not
139  // receive drag events.
140  bool IsEnabled(int tab_id) const;
141
142  // Gets the icon of this button and its badge.
143  gfx::ImageSkia GetIconWithBadge();
144
145  // Returns button icon so it can be accessed during tests.
146  gfx::ImageSkia GetIconForTest();
147
148 private:
149  // Overridden from views::View:
150  virtual void ViewHierarchyChanged(
151      const ViewHierarchyChangedDetails& details) OVERRIDE;
152  virtual void OnDragDone() OVERRIDE;
153  virtual gfx::Size GetPreferredSize() const OVERRIDE;
154  virtual void PaintChildren(gfx::Canvas* canvas,
155                             const views::CullSet& cull_set) OVERRIDE;
156
157  // ExtensionActionViewDelegate:
158  virtual views::View* GetAsView() OVERRIDE;
159  virtual bool IsShownInMenu() OVERRIDE;
160  virtual views::FocusManager* GetFocusManagerForAccelerator() OVERRIDE;
161  virtual views::Widget* GetParentForContextMenu() OVERRIDE;
162  virtual ExtensionActionViewController* GetPreferredPopupViewController()
163      OVERRIDE;
164  virtual views::View* GetReferenceViewForPopup() OVERRIDE;
165  virtual views::MenuButton* GetContextMenuButton() OVERRIDE;
166  virtual content::WebContents* GetCurrentWebContents() OVERRIDE;
167  virtual void HideActivePopup() OVERRIDE;
168  virtual void OnIconUpdated() OVERRIDE;
169  virtual void OnPopupShown(bool grant_tab_permissions) OVERRIDE;
170  virtual void CleanupPopup() OVERRIDE;
171
172  // The controller for this ExtensionAction view.
173  scoped_ptr<ExtensionActionViewController> view_controller_;
174
175  // Delegate that usually represents a container for BrowserActionView.
176  BrowserActionView::Delegate* delegate_;
177
178  // Used to make sure we only register the command once.
179  bool called_registered_extension_command_;
180
181  content::NotificationRegistrar registrar_;
182
183  // The observer that we need to notify when the icon of the button has been
184  // updated.
185  IconObserver* icon_observer_;
186
187  // A lock to keep the MenuButton pressed when a menu or popup is visible.
188  scoped_ptr<views::MenuButton::PressedLock> pressed_lock_;
189
190  DISALLOW_COPY_AND_ASSIGN(BrowserActionView);
191};
192
193#endif  // CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_
194