Home | History | Annotate | Download | only in gtk
      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 
     45   GtkWidget* widget() { return hbox_.get(); }
     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 
     53   int button_count() { return extension_button_map_.size(); }
     54 
     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 
     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