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