// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_UI_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_ #define CHROME_BROWSER_UI_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_ #include #include #include "base/compiler_specific.h" #include "base/memory/linked_ptr.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/extensions/extension_toolbar_model.h" #include "chrome/browser/ui/gtk/custom_button.h" #include "chrome/browser/ui/gtk/menu_gtk.h" #include "chrome/browser/ui/gtk/overflow_button.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "ui/base/gtk/gtk_signal.h" #include "ui/base/gtk/gtk_signal_registrar.h" #include "ui/base/gtk/owned_widget_gtk.h" #include "ui/base/models/simple_menu_model.h" #include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/animation/slide_animation.h" class Browser; class BrowserActionButton; class GtkThemeService; class Profile; namespace extensions { class Extension; } typedef struct _GdkDragContext GdkDragContext; typedef struct _GtkWidget GtkWidget; class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer, public gfx::AnimationDelegate, public MenuGtk::Delegate, public ui::SimpleMenuModel::Delegate, public content::NotificationObserver { public: explicit BrowserActionsToolbarGtk(Browser* browser); virtual ~BrowserActionsToolbarGtk(); GtkWidget* widget() { return hbox_.get(); } GtkWidget* chevron() { return overflow_button_->widget(); } // Returns the widget in use by the BrowserActionButton corresponding to // |extension|. Used in positioning the ExtensionInstalledBubble for // BrowserActions. GtkWidget* GetBrowserActionWidget(const extensions::Extension* extension); BrowserActionButton* GetBrowserActionButton( const extensions::Extension* extension); int button_count() { return extension_button_map_.size(); } Browser* browser() { return browser_; } ExtensionToolbarModel* model() { return model_; } // Returns the currently selected tab ID, or -1 if there is none. int GetCurrentTabId() const; // Update the display of all buttons. void Update(); // content::NotificationObserver implementation. virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; bool animating() { return resize_animation_.is_animating(); } private: friend class BrowserActionButton; // Initialize drag and drop. void SetupDrags(); // Query the extensions service for all extensions with browser actions, // and create the UI for them. void CreateAllButtons(); // Sets the width of the container and overflow state according to the model. void SetContainerWidth(); // Create the UI for a single browser action. This will stick the button // at the end of the toolbar. void CreateButtonForExtension(const extensions::Extension* extension, int index); // Delete resources associated with UI for a browser action. void RemoveButtonForExtension(const extensions::Extension* extension); // Change the visibility of widget() based on whether we have any buttons // to show. void UpdateVisibility(); // Hide the extension popup, if any. void HidePopup(); // Animate the toolbar to show the given number of icons. This assumes the // visibility of the overflow button will not change. void AnimateToShowNIcons(int count); // Returns true if this extension should be shown in this toolbar. This can // return false if we are in an incognito window and the extension is disabled // for incognito. bool ShouldDisplayBrowserAction(const extensions::Extension* extension); // ExtensionToolbarModel::Observer implementation. virtual void BrowserActionAdded(const extensions::Extension* extension, int index) OVERRIDE; virtual void BrowserActionRemoved( const extensions::Extension* extension) OVERRIDE; virtual void BrowserActionMoved(const extensions::Extension* extension, int index) OVERRIDE; virtual bool BrowserActionShowPopup( const extensions::Extension* extension) OVERRIDE; virtual void ModelLoaded() OVERRIDE; // gfx::AnimationDelegate implementation. virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; // SimpleMenuModel::Delegate implementation. // In our case, |command_id| is be the index into the model's extension list. virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; virtual bool GetAcceleratorForCommandId( int command_id, ui::Accelerator* accelerator) OVERRIDE; virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; // MenuGtk::Delegate implementation. virtual void StoppedShowing() OVERRIDE; virtual bool AlwaysShowIconForCmd(int command_id) const OVERRIDE; // Called by the BrowserActionButton in response to drag-begin. void DragStarted(BrowserActionButton* button, GdkDragContext* drag_context); // Sets the width of the button area of the toolbar to |new_width|, clamping // it to appropriate values. void SetButtonHBoxWidth(int new_width); // Shows or hides the chevron as appropriate. void UpdateChevronVisibility(); CHROMEGTK_CALLBACK_4(BrowserActionsToolbarGtk, gboolean, OnDragMotion, GdkDragContext*, gint, gint, guint); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnDragEnd, GdkDragContext*); CHROMEGTK_CALLBACK_2(BrowserActionsToolbarGtk, gboolean, OnDragFailed, GdkDragContext*, GtkDragResult); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnHierarchyChanged, GtkWidget*); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnSetFocus, GtkWidget*); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnGripperMotionNotify, GdkEventMotion*); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnGripperExpose, GdkEventExpose*); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnGripperEnterNotify, GdkEventCrossing*); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnGripperLeaveNotify, GdkEventCrossing*); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnGripperButtonRelease, GdkEventButton*); CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnGripperButtonPress, GdkEventButton*); // The overflow button is pressed. CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnOverflowButtonPress, GdkEventButton*); // The user presses a mouse button over the popped up overflow menu. CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnOverflowMenuButtonPress, GdkEventButton*); CHROMEGTK_CALLBACK_0(BrowserActionsToolbarGtk, void, OnButtonShowOrHide); Browser* browser_; Profile* profile_; GtkThemeService* theme_service_; ExtensionToolbarModel* model_; // Contains the drag gripper, browser action buttons, and overflow chevron. ui::OwnedWidgetGtk hbox_; // Contains the browser action buttons. ui::OwnedWidgetGtk button_hbox_; // The overflow button for chrome theme mode. scoped_ptr overflow_button_; // The separator just next to the overflow button. Only shown in GTK+ theme // mode. In Chrome theme mode, the overflow button has a separator built in. ui::OwnedWidgetGtk separator_; scoped_ptr overflow_menu_; scoped_ptr overflow_menu_model_; ui::OwnedWidgetGtk overflow_area_; // A widget for adding extra padding to the left of the overflow button. ui::OwnedWidgetGtk overflow_alignment_; // The button that is currently being dragged, or NULL. BrowserActionButton* drag_button_; // The new position of the button in the drag, or -1. int drop_index_; // Map from extension ID to BrowserActionButton, which is a wrapper for // a chrome button and related functionality. There should be one entry // for every extension that has a browser action. typedef std::map > ExtensionButtonMap; ExtensionButtonMap extension_button_map_; // We use this animation for the smart resizing of the toolbar. gfx::SlideAnimation resize_animation_; // This is the final width we are animating towards. int desired_width_; // This is the width we were at when we started animating. int start_width_; ui::GtkSignalRegistrar signals_; content::NotificationRegistrar registrar_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(BrowserActionsToolbarGtk); }; #endif // CHROME_BROWSER_UI_GTK_BROWSER_ACTIONS_TOOLBAR_GTK_H_