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.
5 #ifndef CHROME_BROWSER_UI_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_
6 #define CHROME_BROWSER_UI_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_
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"
28 class BrowserActionButton
;
29 class GtkThemeService
;
32 namespace extensions
{
36 typedef struct _GdkDragContext GdkDragContext
;
37 typedef struct _GtkWidget GtkWidget
;
39 class BrowserActionsToolbarGtk
: public ExtensionToolbarModel::Observer
,
40 public gfx::AnimationDelegate
,
41 public MenuGtk::Delegate
,
42 public ui::SimpleMenuModel::Delegate
,
43 public content::NotificationObserver
{
45 explicit BrowserActionsToolbarGtk(Browser
* browser
);
46 virtual ~BrowserActionsToolbarGtk();
48 GtkWidget
* widget() { return hbox_
.get(); }
49 GtkWidget
* chevron() { return overflow_button_
->widget(); }
51 // Returns the widget in use by the BrowserActionButton corresponding to
52 // |extension|. Used in positioning the ExtensionInstalledBubble for
54 GtkWidget
* GetBrowserActionWidget(const extensions::Extension
* extension
);
55 BrowserActionButton
* GetBrowserActionButton(
56 const extensions::Extension
* extension
);
58 int button_count() { return extension_button_map_
.size(); }
60 Browser
* browser() { return browser_
; }
62 ExtensionToolbarModel
* model() { return model_
; }
64 // Returns the currently selected tab ID, or -1 if there is none.
65 int GetCurrentTabId() const;
67 // Update the display of all buttons.
70 // content::NotificationObserver implementation.
71 virtual void Observe(int type
,
72 const content::NotificationSource
& source
,
73 const content::NotificationDetails
& details
) OVERRIDE
;
76 return resize_animation_
.is_animating();
80 friend class BrowserActionButton
;
82 // Initialize drag and drop.
85 // Query the extensions service for all extensions with browser actions,
86 // and create the UI for them.
87 void CreateAllButtons();
89 // Sets the width of the container and overflow state according to the model.
90 void SetContainerWidth();
92 // Create the UI for a single browser action. This will stick the button
93 // at the end of the toolbar.
94 void CreateButtonForExtension(const extensions::Extension
* extension
,
97 // Delete resources associated with UI for a browser action.
98 void RemoveButtonForExtension(const extensions::Extension
* extension
);
100 // Change the visibility of widget() based on whether we have any buttons
102 void UpdateVisibility();
104 // Hide the extension popup, if any.
107 // Animate the toolbar to show the given number of icons. This assumes the
108 // visibility of the overflow button will not change.
109 void AnimateToShowNIcons(int count
);
111 // Returns true if this extension should be shown in this toolbar. This can
112 // return false if we are in an incognito window and the extension is disabled
114 bool ShouldDisplayBrowserAction(const extensions::Extension
* extension
);
116 // ExtensionToolbarModel::Observer implementation.
117 virtual void BrowserActionAdded(const extensions::Extension
* extension
,
119 virtual void BrowserActionRemoved(
120 const extensions::Extension
* extension
) OVERRIDE
;
121 virtual void BrowserActionMoved(const extensions::Extension
* extension
,
123 virtual bool BrowserActionShowPopup(
124 const extensions::Extension
* extension
) OVERRIDE
;
125 virtual void VisibleCountChanged() OVERRIDE
;
127 // gfx::AnimationDelegate implementation.
128 virtual void AnimationProgressed(const gfx::Animation
* animation
) OVERRIDE
;
129 virtual void AnimationEnded(const gfx::Animation
* animation
) OVERRIDE
;
131 // SimpleMenuModel::Delegate implementation.
132 // In our case, |command_id| is be the index into the model's extension list.
133 virtual bool IsCommandIdChecked(int command_id
) const OVERRIDE
;
134 virtual bool IsCommandIdEnabled(int command_id
) const OVERRIDE
;
135 virtual bool GetAcceleratorForCommandId(
137 ui::Accelerator
* accelerator
) OVERRIDE
;
138 virtual void ExecuteCommand(int command_id
, int event_flags
) OVERRIDE
;
140 // MenuGtk::Delegate implementation.
141 virtual void StoppedShowing() OVERRIDE
;
142 virtual bool AlwaysShowIconForCmd(int command_id
) const OVERRIDE
;
144 // Called by the BrowserActionButton in response to drag-begin.
145 void DragStarted(BrowserActionButton
* button
, GdkDragContext
* drag_context
);
147 // Sets the width of the button area of the toolbar to |new_width|, clamping
148 // it to appropriate values.
149 void SetButtonHBoxWidth(int new_width
);
151 // Shows or hides the chevron as appropriate.
152 void UpdateChevronVisibility();
154 CHROMEGTK_CALLBACK_4(BrowserActionsToolbarGtk
, gboolean
, OnDragMotion
,
155 GdkDragContext
*, gint
, gint
, guint
);
156 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, void, OnDragEnd
,
158 CHROMEGTK_CALLBACK_2(BrowserActionsToolbarGtk
, gboolean
, OnDragFailed
,
159 GdkDragContext
*, GtkDragResult
);
160 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, void, OnHierarchyChanged
,
162 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, void, OnSetFocus
, GtkWidget
*);
163 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, gboolean
,
164 OnGripperMotionNotify
, GdkEventMotion
*);
165 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, gboolean
, OnGripperExpose
,
167 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, gboolean
,
168 OnGripperEnterNotify
, GdkEventCrossing
*);
169 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, gboolean
,
170 OnGripperLeaveNotify
, GdkEventCrossing
*);
171 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, gboolean
,
172 OnGripperButtonRelease
, GdkEventButton
*);
173 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, gboolean
,
174 OnGripperButtonPress
, GdkEventButton
*);
175 // The overflow button is pressed.
176 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, gboolean
,
177 OnOverflowButtonPress
, GdkEventButton
*);
178 // The user presses a mouse button over the popped up overflow menu.
179 CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk
, gboolean
,
180 OnOverflowMenuButtonPress
, GdkEventButton
*);
181 CHROMEGTK_CALLBACK_0(BrowserActionsToolbarGtk
, void, OnButtonShowOrHide
);
186 GtkThemeService
* theme_service_
;
188 ExtensionToolbarModel
* model_
;
190 // Contains the drag gripper, browser action buttons, and overflow chevron.
191 ui::OwnedWidgetGtk hbox_
;
193 // Contains the browser action buttons.
194 ui::OwnedWidgetGtk button_hbox_
;
196 // The overflow button for chrome theme mode.
197 scoped_ptr
<CustomDrawButton
> overflow_button_
;
198 // The separator just next to the overflow button. Only shown in GTK+ theme
199 // mode. In Chrome theme mode, the overflow button has a separator built in.
200 ui::OwnedWidgetGtk separator_
;
201 scoped_ptr
<MenuGtk
> overflow_menu_
;
202 scoped_ptr
<ui::SimpleMenuModel
> overflow_menu_model_
;
203 ui::OwnedWidgetGtk overflow_area_
;
204 // A widget for adding extra padding to the left of the overflow button.
205 ui::OwnedWidgetGtk overflow_alignment_
;
207 // The button that is currently being dragged, or NULL.
208 BrowserActionButton
* drag_button_
;
210 // The new position of the button in the drag, or -1.
213 // Map from extension ID to BrowserActionButton, which is a wrapper for
214 // a chrome button and related functionality. There should be one entry
215 // for every extension that has a browser action.
216 typedef std::map
<std::string
, linked_ptr
<BrowserActionButton
> >
218 ExtensionButtonMap extension_button_map_
;
220 // We use this animation for the smart resizing of the toolbar.
221 gfx::SlideAnimation resize_animation_
;
222 // This is the final width we are animating towards.
224 // This is the width we were at when we started animating.
227 ui::GtkSignalRegistrar signals_
;
229 content::NotificationRegistrar registrar_
;
231 base::WeakPtrFactory
<BrowserActionsToolbarGtk
> weak_factory_
;
233 DISALLOW_COPY_AND_ASSIGN(BrowserActionsToolbarGtk
);
236 #endif // CHROME_BROWSER_UI_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_