Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / gtk / browser_actions_toolbar_gtk.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_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_
6 #define CHROME_BROWSER_UI_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_
7
8 #include <map>
9 #include <string>
10
11 #include "base/compiler_specific.h"
12 #include "base/memory/linked_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "chrome/browser/extensions/extension_toolbar_model.h"
15 #include "chrome/browser/ui/gtk/custom_button.h"
16 #include "chrome/browser/ui/gtk/menu_gtk.h"
17 #include "chrome/browser/ui/gtk/overflow_button.h"
18 #include "content/public/browser/notification_observer.h"
19 #include "content/public/browser/notification_registrar.h"
20 #include "ui/base/gtk/gtk_signal.h"
21 #include "ui/base/gtk/gtk_signal_registrar.h"
22 #include "ui/base/gtk/owned_widget_gtk.h"
23 #include "ui/base/models/simple_menu_model.h"
24 #include "ui/gfx/animation/animation_delegate.h"
25 #include "ui/gfx/animation/slide_animation.h"
26
27 class Browser;
28 class BrowserActionButton;
29 class GtkThemeService;
30 class Profile;
31
32 namespace extensions {
33 class Extension;
34 }
35
36 typedef struct _GdkDragContext GdkDragContext;
37 typedef struct _GtkWidget GtkWidget;
38
39 class BrowserActionsToolbarGtk
40     : public extensions::ExtensionToolbarModel::Observer,
41       public gfx::AnimationDelegate,
42       public MenuGtk::Delegate,
43       public ui::SimpleMenuModel::Delegate,
44       public content::NotificationObserver {
45  public:
46   explicit BrowserActionsToolbarGtk(Browser* browser);
47   virtual ~BrowserActionsToolbarGtk();
48
49   GtkWidget* widget() { return hbox_.get(); }
50   GtkWidget* chevron() { return overflow_button_->widget(); }
51
52   // Returns the widget in use by the BrowserActionButton corresponding to
53   // |extension|. Used in positioning the ExtensionInstalledBubble for
54   // BrowserActions.
55   GtkWidget* GetBrowserActionWidget(const extensions::Extension* extension);
56   BrowserActionButton* GetBrowserActionButton(
57       const extensions::Extension* extension);
58
59   int button_count() { return extension_button_map_.size(); }
60
61   Browser* browser() { return browser_; }
62
63   extensions::ExtensionToolbarModel* model() { return model_; }
64
65   // Returns the currently selected tab ID, or -1 if there is none.
66   int GetCurrentTabId() const;
67
68   // Update the display of all buttons.
69   void Update();
70
71   // content::NotificationObserver implementation.
72   virtual void Observe(int type,
73                        const content::NotificationSource& source,
74                        const content::NotificationDetails& details) OVERRIDE;
75
76   bool animating() {
77     return resize_animation_.is_animating();
78   }
79
80  private:
81   friend class BrowserActionButton;
82
83   // Initialize drag and drop.
84   void SetupDrags();
85
86   // Query the extensions service for all extensions with browser actions,
87   // and create the UI for them.
88   void CreateAllButtons();
89
90   // Sets the width of the container and overflow state according to the model.
91   void SetContainerWidth();
92
93   // Create the UI for a single browser action. This will stick the button
94   // at the end of the toolbar.
95   void CreateButtonForExtension(const extensions::Extension* extension,
96                                 int index);
97
98   // Delete resources associated with UI for a browser action.
99   void RemoveButtonForExtension(const extensions::Extension* extension);
100
101   // Change the visibility of widget() based on whether we have any buttons
102   // to show.
103   void UpdateVisibility();
104
105   // Hide the extension popup, if any.
106   void HidePopup();
107
108   // Animate the toolbar to show the given number of icons. This assumes the
109   // visibility of the overflow button will not change.
110   void AnimateToShowNIcons(int count);
111
112   // Returns true if this extension should be shown in this toolbar. This can
113   // return false if we are in an incognito window and the extension is disabled
114   // for incognito.
115   bool ShouldDisplayBrowserAction(const extensions::Extension* extension);
116
117   // extensions::ExtensionToolbarModel::Observer implementation.
118   virtual void BrowserActionAdded(const extensions::Extension* extension,
119                                   int index) OVERRIDE;
120   virtual void BrowserActionRemoved(
121       const extensions::Extension* extension) OVERRIDE;
122   virtual void BrowserActionMoved(const extensions::Extension* extension,
123                                   int index) OVERRIDE;
124   virtual bool BrowserActionShowPopup(
125       const extensions::Extension* extension) OVERRIDE;
126   virtual void VisibleCountChanged() OVERRIDE;
127
128   // gfx::AnimationDelegate implementation.
129   virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
130   virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
131
132   // SimpleMenuModel::Delegate implementation.
133   // In our case, |command_id| is be the index into the model's extension list.
134   virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
135   virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
136   virtual bool GetAcceleratorForCommandId(
137       int command_id,
138       ui::Accelerator* accelerator) OVERRIDE;
139   virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
140
141   // MenuGtk::Delegate implementation.
142   virtual void StoppedShowing() OVERRIDE;
143   virtual bool AlwaysShowIconForCmd(int command_id) const OVERRIDE;
144
145   // Called by the BrowserActionButton in response to drag-begin.
146   void DragStarted(BrowserActionButton* button, GdkDragContext* drag_context);
147
148   // Sets the width of the button area of the toolbar to |new_width|, clamping
149   // it to appropriate values.
150   void SetButtonHBoxWidth(int new_width);
151
152   // Shows or hides the chevron as appropriate.
153   void UpdateChevronVisibility();
154
155   CHROMEGTK_CALLBACK_4(BrowserActionsToolbarGtk, gboolean, OnDragMotion,
156                        GdkDragContext*, gint, gint, guint);
157   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnDragEnd,
158                        GdkDragContext*);
159   CHROMEGTK_CALLBACK_2(BrowserActionsToolbarGtk, gboolean, OnDragFailed,
160                        GdkDragContext*, GtkDragResult);
161   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnHierarchyChanged,
162                        GtkWidget*);
163   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnSetFocus, GtkWidget*);
164   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean,
165                        OnGripperMotionNotify, GdkEventMotion*);
166   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnGripperExpose,
167                        GdkEventExpose*);
168   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean,
169                        OnGripperEnterNotify, GdkEventCrossing*);
170   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean,
171                        OnGripperLeaveNotify, GdkEventCrossing*);
172   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean,
173                        OnGripperButtonRelease, GdkEventButton*);
174   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean,
175                        OnGripperButtonPress, GdkEventButton*);
176   // The overflow button is pressed.
177   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean,
178                        OnOverflowButtonPress, GdkEventButton*);
179   // The user presses a mouse button over the popped up overflow menu.
180   CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean,
181                        OnOverflowMenuButtonPress, GdkEventButton*);
182   CHROMEGTK_CALLBACK_0(BrowserActionsToolbarGtk, void, OnButtonShowOrHide);
183
184   Browser* browser_;
185
186   Profile* profile_;
187   GtkThemeService* theme_service_;
188
189   extensions::ExtensionToolbarModel* model_;
190
191   // Contains the drag gripper, browser action buttons, and overflow chevron.
192   ui::OwnedWidgetGtk hbox_;
193
194   // Contains the browser action buttons.
195   ui::OwnedWidgetGtk button_hbox_;
196
197   // The overflow button for chrome theme mode.
198   scoped_ptr<CustomDrawButton> overflow_button_;
199   // The separator just next to the overflow button. Only shown in GTK+ theme
200   // mode. In Chrome theme mode, the overflow button has a separator built in.
201   ui::OwnedWidgetGtk separator_;
202   scoped_ptr<MenuGtk> overflow_menu_;
203   scoped_ptr<ui::SimpleMenuModel> overflow_menu_model_;
204   ui::OwnedWidgetGtk overflow_area_;
205   // A widget for adding extra padding to the left of the overflow button.
206   ui::OwnedWidgetGtk overflow_alignment_;
207
208   // The button that is currently being dragged, or NULL.
209   BrowserActionButton* drag_button_;
210
211   // The new position of the button in the drag, or -1.
212   int drop_index_;
213
214   // Map from extension ID to BrowserActionButton, which is a wrapper for
215   // a chrome button and related functionality. There should be one entry
216   // for every extension that has a browser action.
217   typedef std::map<std::string, linked_ptr<BrowserActionButton> >
218       ExtensionButtonMap;
219   ExtensionButtonMap extension_button_map_;
220
221   // We use this animation for the smart resizing of the toolbar.
222   gfx::SlideAnimation resize_animation_;
223   // This is the final width we are animating towards.
224   int desired_width_;
225   // This is the width we were at when we started animating.
226   int start_width_;
227
228   ui::GtkSignalRegistrar signals_;
229
230   content::NotificationRegistrar registrar_;
231
232   base::WeakPtrFactory<BrowserActionsToolbarGtk> weak_factory_;
233
234   DISALLOW_COPY_AND_ASSIGN(BrowserActionsToolbarGtk);
235 };
236
237 #endif  // CHROME_BROWSER_UI_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_