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