- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / browser_action_view.h
1 // Copyright (c) 2012 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.
4
5 #ifndef CHROME_BROWSER_UI_VIEWS_BROWSER_ACTION_VIEW_H_
6 #define CHROME_BROWSER_UI_VIEWS_BROWSER_ACTION_VIEW_H_
7
8 #include <string>
9
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"
19
20 class Browser;
21 class BrowserActionButton;
22 class ExtensionAction;
23
24 namespace extensions {
25 class Extension;
26 }
27
28 namespace gfx {
29 class Image;
30 }
31
32 namespace views {
33 class MenuItemView;
34 class MenuRunner;
35 }
36
37 ////////////////////////////////////////////////////////////////////////////////
38 // BrowserActionView
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 {
42  public:
43   // Need DragController here because BrowserActionView could be
44   // dragged/dropped.
45   class Delegate : public views::DragController,
46                    public ExtensionContextMenuModel::PopupDelegate {
47    public:
48     // Returns the current tab's ID, or -1 if there is no current tab.
49     virtual int GetCurrentTabId() const = 0;
50
51     // Called when the user clicks on the browser action icon.
52     virtual void OnBrowserActionExecuted(BrowserActionButton* button) = 0;
53
54     // Called when a browser action becomes visible/hidden.
55     virtual void OnBrowserActionVisibilityChanged() = 0;
56
57     // Returns relative position of a button inside BrowserActionView.
58     virtual gfx::Point GetViewContentOffset() const = 0;
59
60     virtual bool NeedToShowMultipleIconStates() const;
61     virtual bool NeedToShowTooltip() const;
62
63    protected:
64     virtual ~Delegate() {}
65   };
66
67   BrowserActionView(const extensions::Extension* extension,
68                     Browser* browser,
69                     Delegate* delegate);
70   virtual ~BrowserActionView();
71
72   BrowserActionButton* button() { return button_; }
73
74   // Gets browser action button icon with the badge.
75   gfx::ImageSkia GetIconWithBadge();
76
77   // Overridden from views::View:
78   virtual void Layout() OVERRIDE;
79   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
80   virtual gfx::Size GetPreferredSize() OVERRIDE;
81
82  protected:
83   // Overridden from views::View to paint the badge on top of children.
84   virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE;
85
86  private:
87   // The Browser object this view is associated with.
88   Browser* browser_;
89
90   // Usually a container for this view.
91   Delegate* delegate_;
92
93   // The button this view contains.
94   BrowserActionButton* button_;
95
96   // Extension this view associated with.
97   const extensions::Extension* extension_;
98
99   DISALLOW_COPY_AND_ASSIGN(BrowserActionView);
100 };
101
102 ////////////////////////////////////////////////////////////////////////////////
103 // BrowserActionButton
104
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 {
113  public:
114   BrowserActionButton(const extensions::Extension* extension,
115                       Browser* browser_,
116                       BrowserActionView::Delegate* delegate);
117
118   // Call this instead of delete.
119   void Destroy();
120
121   ExtensionAction* browser_action() const { return browser_action_; }
122   const extensions::Extension* extension() { return extension_; }
123
124   // Called to update the display to match the browser action's state.
125   void UpdateState();
126
127   // Does this button's action have a popup?
128   virtual bool IsPopup();
129   virtual GURL GetPopupUrl();
130
131   // Overridden from views::View:
132   virtual bool CanHandleAccelerators() const OVERRIDE;
133   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
134
135   // Overridden from views::ButtonListener:
136   virtual void ButtonPressed(views::Button* sender,
137                              const ui::Event& event) OVERRIDE;
138
139   // Overridden from views::ContextMenuController.
140   virtual void ShowContextMenuForView(View* source,
141                                       const gfx::Point& point,
142                                       ui::MenuSourceType source_type) OVERRIDE;
143
144   // Overridden from content::NotificationObserver:
145   virtual void Observe(int type,
146                        const content::NotificationSource& source,
147                        const content::NotificationDetails& details) OVERRIDE;
148
149   // Overriden from ExtensionActionIconFactory::Observer.
150   virtual void OnIconUpdated() OVERRIDE;
151
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;
163
164   // Overridden from ui::AcceleratorTarget.
165   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
166
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();
171
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;
176
177   // Returns icon factory for the button.
178   ExtensionActionIconFactory& icon_factory() { return icon_factory_; }
179
180   // Returns button icon so it can be accessed during tests.
181   gfx::ImageSkia GetIconForTest();
182
183  protected:
184   // Overridden from views::View:
185   virtual void ViewHierarchyChanged(
186       const ViewHierarchyChangedDetails& details) OVERRIDE;
187
188  private:
189   virtual ~BrowserActionButton();
190
191   // Register an extension command if the extension has an active one.
192   void MaybeRegisterExtensionCommand();
193
194   // Unregisters an extension command, if the extension has registered one and
195   // it is active.
196   void MaybeUnregisterExtensionCommand(bool only_if_active);
197
198   // The Browser object this button is associated with.
199   Browser* browser_;
200
201   // The browser action this view represents. The ExtensionAction is not owned
202   // by this class.
203   ExtensionAction* browser_action_;
204
205   // The extension associated with the browser action we're displaying.
206   const extensions::Extension* extension_;
207
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_;
213
214   // Delegate that usually represents a container for BrowserActionView.
215   BrowserActionView::Delegate* delegate_;
216
217   // The context menu.  This member is non-NULL only when the menu is shown.
218   views::MenuItemView* context_menu_;
219
220   // Used to make sure MaybeRegisterExtensionCommand() is called only once
221   // from ViewHierarchyChanged().
222   bool called_registered_extension_command_;
223
224   content::NotificationRegistrar registrar_;
225
226   // The extension key binding accelerator this browser action is listening for
227   // (to show the popup).
228   scoped_ptr<ui::Accelerator> keybinding_;
229
230   // Responsible for running the menu.
231   scoped_ptr<views::MenuRunner> menu_runner_;
232
233   friend class base::DeleteHelper<BrowserActionButton>;
234
235   DISALLOW_COPY_AND_ASSIGN(BrowserActionButton);
236 };
237
238 #endif  // CHROME_BROWSER_UI_VIEWS_BROWSER_ACTION_VIEW_H_