| Index: chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
|
| diff --git a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
|
| deleted file mode 100644
|
| index 9091988e16ff5a69e3b05b4b1e7c75973c0d5065..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
|
| +++ /dev/null
|
| @@ -1,1125 +0,0 @@
|
| -// 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.
|
| -
|
| -#include "chrome/browser/ui/gtk/browser_actions_toolbar_gtk.h"
|
| -
|
| -#include <gtk/gtk.h>
|
| -
|
| -#include <algorithm>
|
| -#include <utility>
|
| -#include <vector>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/i18n/rtl.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "chrome/browser/chrome_notification_types.h"
|
| -#include "chrome/browser/extensions/api/commands/command_service.h"
|
| -#include "chrome/browser/extensions/extension_action.h"
|
| -#include "chrome/browser/extensions/extension_action_icon_factory.h"
|
| -#include "chrome/browser/extensions/extension_action_manager.h"
|
| -#include "chrome/browser/extensions/extension_context_menu_model.h"
|
| -#include "chrome/browser/extensions/extension_service.h"
|
| -#include "chrome/browser/extensions/extension_toolbar_model.h"
|
| -#include "chrome/browser/extensions/extension_util.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/sessions/session_tab_helper.h"
|
| -#include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/ui/gtk/browser_window_gtk.h"
|
| -#include "chrome/browser/ui/gtk/custom_button.h"
|
| -#include "chrome/browser/ui/gtk/extensions/extension_popup_gtk.h"
|
| -#include "chrome/browser/ui/gtk/gtk_chrome_button.h"
|
| -#include "chrome/browser/ui/gtk/gtk_chrome_shrinkable_hbox.h"
|
| -#include "chrome/browser/ui/gtk/gtk_theme_service.h"
|
| -#include "chrome/browser/ui/gtk/gtk_util.h"
|
| -#include "chrome/browser/ui/gtk/hover_controller_gtk.h"
|
| -#include "chrome/browser/ui/gtk/menu_gtk.h"
|
| -#include "chrome/browser/ui/gtk/view_id_util.h"
|
| -#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| -#include "content/public/browser/notification_details.h"
|
| -#include "content/public/browser/notification_source.h"
|
| -#include "extensions/browser/extension_system.h"
|
| -#include "extensions/common/extension.h"
|
| -#include "extensions/common/manifest_constants.h"
|
| -#include "grit/theme_resources.h"
|
| -#include "grit/ui_resources.h"
|
| -#include "ui/base/accelerators/platform_accelerator_gtk.h"
|
| -#include "ui/base/resource/resource_bundle.h"
|
| -#include "ui/gfx/canvas_skia_paint.h"
|
| -#include "ui/gfx/gtk_compat.h"
|
| -#include "ui/gfx/gtk_util.h"
|
| -#include "ui/gfx/image/image.h"
|
| -#include "ui/gfx/image/image_skia_operations.h"
|
| -
|
| -using extensions::Extension;
|
| -using extensions::ExtensionActionManager;
|
| -
|
| -namespace {
|
| -
|
| -// The width of the browser action buttons.
|
| -const int kButtonWidth = 27;
|
| -
|
| -// The padding between browser action buttons.
|
| -const int kButtonPadding = 4;
|
| -
|
| -// The padding to the right of the browser action buttons (between the buttons
|
| -// and chevron if they are both showing).
|
| -const int kButtonChevronPadding = 2;
|
| -
|
| -// Width of the invisible gripper for resizing the toolbar.
|
| -const int kResizeGripperWidth = 4;
|
| -
|
| -const char kDragTarget[] = "application/x-chrome-browseraction";
|
| -
|
| -GtkTargetEntry GetDragTargetEntry() {
|
| - GtkTargetEntry drag_target;
|
| - drag_target.target = const_cast<char*>(kDragTarget);
|
| - drag_target.flags = GTK_TARGET_SAME_APP;
|
| - drag_target.info = 0;
|
| - return drag_target;
|
| -}
|
| -
|
| -// The minimum width in pixels of the button hbox if |icon_count| icons are
|
| -// showing.
|
| -gint WidthForIconCount(gint icon_count) {
|
| - return std::max((kButtonWidth + kButtonPadding) * icon_count - kButtonPadding,
|
| - 0);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -using ui::SimpleMenuModel;
|
| -
|
| -class BrowserActionButton : public content::NotificationObserver,
|
| - public ExtensionActionIconFactory::Observer,
|
| - public ExtensionContextMenuModel::PopupDelegate,
|
| - public MenuGtk::Delegate {
|
| - public:
|
| - BrowserActionButton(BrowserActionsToolbarGtk* toolbar,
|
| - const Extension* extension,
|
| - GtkThemeService* theme_provider)
|
| - : toolbar_(toolbar),
|
| - extension_(extension),
|
| - image_(NULL),
|
| - icon_factory_(toolbar->browser()->profile(), extension,
|
| - browser_action(), this),
|
| - accel_group_(NULL) {
|
| - button_.reset(new CustomDrawButton(
|
| - theme_provider,
|
| - IDR_BROWSER_ACTION,
|
| - IDR_BROWSER_ACTION_P,
|
| - IDR_BROWSER_ACTION_H,
|
| - 0,
|
| - NULL));
|
| - gtk_widget_set_size_request(button(), kButtonWidth, kButtonWidth);
|
| - alignment_.Own(gtk_alignment_new(0, 0, 1, 1));
|
| - gtk_container_add(GTK_CONTAINER(alignment_.get()), button());
|
| - gtk_widget_show(button());
|
| -
|
| - DCHECK(browser_action());
|
| -
|
| - UpdateState();
|
| -
|
| - signals_.Connect(button(), "button-press-event",
|
| - G_CALLBACK(OnButtonPress), this);
|
| - signals_.Connect(button(), "clicked",
|
| - G_CALLBACK(OnClicked), this);
|
| - signals_.Connect(button(), "drag-begin",
|
| - G_CALLBACK(OnDragBegin), this);
|
| - signals_.ConnectAfter(widget(), "expose-event",
|
| - G_CALLBACK(OnExposeEvent), this);
|
| - if (toolbar_->browser()->window()) {
|
| - // If the window exists already, then the browser action button has been
|
| - // recreated after the window was created, for example when the extension
|
| - // is reloaded.
|
| - ConnectBrowserActionPopupAccelerator();
|
| - } else {
|
| - // Window doesn't exist yet, wait for it.
|
| - signals_.Connect(toolbar->widget(), "realize",
|
| - G_CALLBACK(OnRealize), this);
|
| - }
|
| -
|
| - registrar_.Add(
|
| - this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
|
| - content::Source<ExtensionAction>(browser_action()));
|
| - registrar_.Add(
|
| - this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
|
| - content::Source<Profile>(
|
| - toolbar->browser()->profile()->GetOriginalProfile()));
|
| - registrar_.Add(
|
| - this, chrome::NOTIFICATION_EXTENSION_COMMAND_ADDED,
|
| - content::Source<Profile>(
|
| - toolbar->browser()->profile()->GetOriginalProfile()));
|
| - registrar_.Add(
|
| - this, chrome::NOTIFICATION_EXTENSION_COMMAND_REMOVED,
|
| - content::Source<Profile>(
|
| - toolbar->browser()->profile()->GetOriginalProfile()));
|
| - }
|
| -
|
| - virtual ~BrowserActionButton() {
|
| - DisconnectBrowserActionPopupAccelerator();
|
| -
|
| - alignment_.Destroy();
|
| - }
|
| -
|
| - GtkWidget* button() { return button_->widget(); }
|
| -
|
| - GtkWidget* widget() { return alignment_.get(); }
|
| -
|
| - const Extension* extension() { return extension_; }
|
| -
|
| - // NotificationObserver implementation.
|
| - virtual void Observe(int type,
|
| - const content::NotificationSource& source,
|
| - const content::NotificationDetails& details) OVERRIDE {
|
| - switch (type) {
|
| - case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED:
|
| - UpdateState();
|
| - break;
|
| - case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED:
|
| - case chrome::NOTIFICATION_WINDOW_CLOSED:
|
| - DisconnectBrowserActionPopupAccelerator();
|
| - break;
|
| - case chrome::NOTIFICATION_EXTENSION_COMMAND_ADDED:
|
| - case chrome::NOTIFICATION_EXTENSION_COMMAND_REMOVED: {
|
| - std::pair<const std::string, const std::string>* payload =
|
| - content::Details<std::pair<const std::string, const std::string> >(
|
| - details).ptr();
|
| - if (extension_->id() == payload->first &&
|
| - payload->second ==
|
| - extensions::manifest_values::kBrowserActionCommandEvent) {
|
| - if (type == chrome::NOTIFICATION_EXTENSION_COMMAND_ADDED)
|
| - ConnectBrowserActionPopupAccelerator();
|
| - else
|
| - DisconnectBrowserActionPopupAccelerator();
|
| - }
|
| - break;
|
| - }
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - }
|
| -
|
| - // ExtensionActionIconFactory::Observer implementation.
|
| - virtual void OnIconUpdated() OVERRIDE {
|
| - UpdateState();
|
| - }
|
| -
|
| - // Updates the button based on the latest state from the associated
|
| - // browser action.
|
| - void UpdateState() {
|
| - int tab_id = toolbar_->GetCurrentTabId();
|
| - if (tab_id < 0)
|
| - return;
|
| -
|
| - std::string tooltip = browser_action()->GetTitle(tab_id);
|
| - if (tooltip.empty())
|
| - gtk_widget_set_has_tooltip(button(), FALSE);
|
| - else
|
| - gtk_widget_set_tooltip_text(button(), tooltip.c_str());
|
| -
|
| - enabled_ = browser_action()->GetIsVisible(tab_id);
|
| - if (!enabled_)
|
| - button_->SetPaintOverride(GTK_STATE_INSENSITIVE);
|
| - else
|
| - button_->UnsetPaintOverride();
|
| -
|
| - gfx::Image image = icon_factory_.GetIcon(tab_id);
|
| - if (!image.IsEmpty()) {
|
| - if (enabled_) {
|
| - SetImage(image);
|
| - } else {
|
| - SetImage(gfx::Image(gfx::ImageSkiaOperations::CreateTransparentImage(
|
| - image.AsImageSkia(), .25)));
|
| - }
|
| - }
|
| -
|
| - gtk_widget_queue_draw(button());
|
| - }
|
| -
|
| - gfx::Image GetIcon() {
|
| - return icon_factory_.GetIcon(toolbar_->GetCurrentTabId());
|
| - }
|
| -
|
| - MenuGtk* GetContextMenu() {
|
| - if (!extension_->ShowConfigureContextMenus())
|
| - return NULL;
|
| -
|
| - context_menu_model_ =
|
| - new ExtensionContextMenuModel(extension_, toolbar_->browser(), this);
|
| - context_menu_.reset(
|
| - new MenuGtk(this, context_menu_model_.get()));
|
| - return context_menu_.get();
|
| - }
|
| -
|
| - private:
|
| - // Activate the browser action. Returns true if a popup was shown. Showing the
|
| - // popup will grant tab permissions if |should_grant| is true. Popup's shown
|
| - // via an API should not grant permissions.
|
| - bool Activate(GtkWidget* widget, bool should_grant) {
|
| - extensions::ExtensionToolbarModel* model = toolbar_->model();
|
| - const Extension* extension = extension_;
|
| - Browser* browser = toolbar_->browser();
|
| - GURL popup_url;
|
| -
|
| - switch (model->ExecuteBrowserAction(
|
| - extension, browser, &popup_url, should_grant)) {
|
| - case extensions::ExtensionToolbarModel::ACTION_NONE:
|
| - break;
|
| - case extensions::ExtensionToolbarModel::ACTION_SHOW_POPUP:
|
| - ExtensionPopupGtk::Show(popup_url, browser, widget,
|
| - ExtensionPopupGtk::SHOW);
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - // MenuGtk::Delegate implementation.
|
| - virtual void StoppedShowing() OVERRIDE {
|
| - if (enabled_)
|
| - button_->UnsetPaintOverride();
|
| - else
|
| - button_->SetPaintOverride(GTK_STATE_INSENSITIVE);
|
| -
|
| - // If the context menu was showing for the overflow menu, re-assert the
|
| - // grab that was shadowed.
|
| - if (toolbar_->overflow_menu_.get())
|
| - gtk_util::GrabAllInput(toolbar_->overflow_menu_->widget());
|
| - }
|
| -
|
| - virtual void CommandWillBeExecuted() OVERRIDE {
|
| - // If the context menu was showing for the overflow menu, and a command
|
| - // is executed, then stop showing the overflow menu.
|
| - if (toolbar_->overflow_menu_.get())
|
| - toolbar_->overflow_menu_->Cancel();
|
| - }
|
| -
|
| - // ExtensionContextMenuModel::PopupDelegate implementation.
|
| - virtual void InspectPopup(ExtensionAction* action) OVERRIDE {
|
| - GURL popup_url = action->GetPopupUrl(toolbar_->GetCurrentTabId());
|
| - ExtensionPopupGtk::Show(popup_url, toolbar_->browser(), widget(),
|
| - ExtensionPopupGtk::SHOW_AND_INSPECT);
|
| - }
|
| -
|
| - void SetImage(const gfx::Image& image) {
|
| - if (!image_) {
|
| - image_ = gtk_image_new_from_pixbuf(image.ToGdkPixbuf());
|
| - gtk_button_set_image(GTK_BUTTON(button()), image_);
|
| - } else {
|
| - gtk_image_set_from_pixbuf(GTK_IMAGE(image_), image.ToGdkPixbuf());
|
| - }
|
| - }
|
| -
|
| - static gboolean OnButtonPress(GtkWidget* widget,
|
| - GdkEventButton* event,
|
| - BrowserActionButton* button) {
|
| - if (event->button != 3)
|
| - return FALSE;
|
| -
|
| - MenuGtk* menu = button->GetContextMenu();
|
| - if (!menu)
|
| - return FALSE;
|
| -
|
| - button->button_->SetPaintOverride(GTK_STATE_ACTIVE);
|
| - menu->PopupForWidget(widget, event->button, event->time);
|
| -
|
| - return TRUE;
|
| - }
|
| -
|
| - static void OnClicked(GtkWidget* widget, BrowserActionButton* button) {
|
| - if (button->enabled_)
|
| - button->Activate(widget, true);
|
| - }
|
| -
|
| - static gboolean OnExposeEvent(GtkWidget* widget,
|
| - GdkEventExpose* event,
|
| - BrowserActionButton* button) {
|
| - int tab_id = button->toolbar_->GetCurrentTabId();
|
| - if (tab_id < 0)
|
| - return FALSE;
|
| -
|
| - ExtensionAction* action = button->browser_action();
|
| - if (action->GetBadgeText(tab_id).empty())
|
| - return FALSE;
|
| -
|
| - gfx::CanvasSkiaPaint canvas(event, false);
|
| - GtkAllocation allocation;
|
| - gtk_widget_get_allocation(widget, &allocation);
|
| - action->PaintBadge(&canvas, gfx::Rect(allocation), tab_id);
|
| - return FALSE;
|
| - }
|
| -
|
| - static void OnDragBegin(GtkWidget* widget,
|
| - GdkDragContext* drag_context,
|
| - BrowserActionButton* button) {
|
| - // Simply pass along the notification to the toolbar. The point of this
|
| - // function is to tell the toolbar which BrowserActionButton initiated the
|
| - // drag.
|
| - button->toolbar_->DragStarted(button, drag_context);
|
| - }
|
| -
|
| - // The accelerator handler for when the shortcuts to open the popup is struck.
|
| - static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group,
|
| - GObject* acceleratable,
|
| - guint keyval,
|
| - GdkModifierType modifier,
|
| - BrowserActionButton* button) {
|
| - // Open the popup for this extension.
|
| - GtkWidget* anchor = button->widget();
|
| - // The anchor might be in the overflow menu. Then we point to the chevron.
|
| - if (!gtk_widget_get_visible(anchor))
|
| - anchor = button->toolbar_->chevron();
|
| - button->Activate(anchor, true);
|
| - return TRUE;
|
| - }
|
| -
|
| - // The handler for when the browser action is realized. |user_data| contains a
|
| - // pointer to the BrowserAction shown.
|
| - static void OnRealize(GtkWidget* widget, void* user_data) {
|
| - BrowserActionButton* button = static_cast<BrowserActionButton*>(user_data);
|
| - button->ConnectBrowserActionPopupAccelerator();
|
| - }
|
| -
|
| - // Connect the accelerator for the browser action popup.
|
| - void ConnectBrowserActionPopupAccelerator() {
|
| - extensions::CommandService* command_service =
|
| - extensions::CommandService::Get(toolbar_->browser()->profile());
|
| - extensions::Command command;
|
| - if (command_service->GetBrowserActionCommand(extension_->id(),
|
| - extensions::CommandService::ACTIVE_ONLY,
|
| - &command,
|
| - NULL)) {
|
| - // Found the browser action shortcut command, register it.
|
| - keybinding_ = command.accelerator();
|
| -
|
| - gfx::NativeWindow window =
|
| - toolbar_->browser()->window()->GetNativeWindow();
|
| - accel_group_ = gtk_accel_group_new();
|
| - gtk_window_add_accel_group(window, accel_group_);
|
| -
|
| - gtk_accel_group_connect(
|
| - accel_group_,
|
| - ui::GetGdkKeyCodeForAccelerator(keybinding_),
|
| - ui::GetGdkModifierForAccelerator(keybinding_),
|
| - GtkAccelFlags(0),
|
| - g_cclosure_new(G_CALLBACK(OnGtkAccelerator), this, NULL));
|
| -
|
| - // Since we've added an accelerator, we'll need to unregister it before
|
| - // the window is closed, so we listen for the window being closed.
|
| - registrar_.Add(this,
|
| - chrome::NOTIFICATION_WINDOW_CLOSED,
|
| - content::Source<GtkWindow>(window));
|
| - }
|
| - }
|
| -
|
| - // Disconnect the accelerator for the browser action popup and delete clean up
|
| - // the accelerator group registration.
|
| - void DisconnectBrowserActionPopupAccelerator() {
|
| - if (accel_group_) {
|
| - gfx::NativeWindow window =
|
| - toolbar_->browser()->window()->GetNativeWindow();
|
| - gtk_accel_group_disconnect_key(
|
| - accel_group_,
|
| - ui::GetGdkKeyCodeForAccelerator(keybinding_),
|
| - GetGdkModifierForAccelerator(keybinding_));
|
| - gtk_window_remove_accel_group(window, accel_group_);
|
| - g_object_unref(accel_group_);
|
| - accel_group_ = NULL;
|
| - keybinding_ = ui::Accelerator();
|
| -
|
| - // We've removed the accelerator, so no need to listen to this anymore.
|
| - registrar_.Remove(this,
|
| - chrome::NOTIFICATION_WINDOW_CLOSED,
|
| - content::Source<GtkWindow>(window));
|
| - }
|
| - }
|
| -
|
| - ExtensionAction* browser_action() const {
|
| - return ExtensionActionManager::Get(toolbar_->browser()->profile())->
|
| - GetBrowserAction(*extension_);
|
| - }
|
| -
|
| - // The toolbar containing this button.
|
| - BrowserActionsToolbarGtk* toolbar_;
|
| -
|
| - // The extension that contains this browser action.
|
| - const Extension* extension_;
|
| -
|
| - // The button for this browser action.
|
| - scoped_ptr<CustomDrawButton> button_;
|
| -
|
| - // Whether the browser action is enabled (equivalent to whether a page action
|
| - // is visible).
|
| - bool enabled_;
|
| -
|
| - // The top level widget (parent of |button_|).
|
| - ui::OwnedWidgetGtk alignment_;
|
| -
|
| - // The one image subwidget in |button_|. We keep this out so we don't alter
|
| - // the widget hierarchy while changing the button image because changing the
|
| - // GTK widget hierarchy invalidates all tooltips and several popular
|
| - // extensions change browser action icon in a loop.
|
| - GtkWidget* image_;
|
| -
|
| - // The object that will be used to get the browser action icon for us.
|
| - // It may load the icon asynchronously (in which case the initial icon
|
| - // returned by the factory will be transparent), so we have to observe it for
|
| - // updates to the icon.
|
| - ExtensionActionIconFactory icon_factory_;
|
| -
|
| - // Same as |default_icon_|, but stored as SkBitmap.
|
| - SkBitmap default_skbitmap_;
|
| -
|
| - ui::GtkSignalRegistrar signals_;
|
| - content::NotificationRegistrar registrar_;
|
| -
|
| - // The accelerator group used to handle accelerators, owned by this object.
|
| - GtkAccelGroup* accel_group_;
|
| -
|
| - // The keybinding accelerator registered to show the browser action popup.
|
| - ui::Accelerator keybinding_;
|
| -
|
| - // The context menu view and model for this extension action.
|
| - scoped_ptr<MenuGtk> context_menu_;
|
| - scoped_refptr<ExtensionContextMenuModel> context_menu_model_;
|
| -
|
| - friend class BrowserActionsToolbarGtk;
|
| -};
|
| -
|
| -// BrowserActionsToolbarGtk ----------------------------------------------------
|
| -
|
| -BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
|
| - : browser_(browser),
|
| - profile_(browser->profile()),
|
| - theme_service_(GtkThemeService::GetFrom(browser->profile())),
|
| - model_(NULL),
|
| - hbox_(gtk_hbox_new(FALSE, 0)),
|
| - button_hbox_(gtk_chrome_shrinkable_hbox_new(TRUE, FALSE, kButtonPadding)),
|
| - drag_button_(NULL),
|
| - drop_index_(-1),
|
| - resize_animation_(this),
|
| - desired_width_(0),
|
| - start_width_(0),
|
| - weak_factory_(this) {
|
| - model_ = extensions::ExtensionToolbarModel::Get(profile_);
|
| - if (!model_)
|
| - return;
|
| -
|
| - overflow_button_.reset(new CustomDrawButton(
|
| - theme_service_,
|
| - IDR_BROWSER_ACTIONS_OVERFLOW,
|
| - IDR_BROWSER_ACTIONS_OVERFLOW_P,
|
| - IDR_BROWSER_ACTIONS_OVERFLOW_H,
|
| - 0,
|
| - gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE)));
|
| -
|
| - GtkWidget* gripper = gtk_button_new();
|
| - gtk_widget_set_size_request(gripper, kResizeGripperWidth, -1);
|
| - gtk_widget_set_can_focus(gripper, FALSE);
|
| -
|
| - gtk_widget_add_events(gripper, GDK_POINTER_MOTION_MASK);
|
| - signals_.Connect(gripper, "motion-notify-event",
|
| - G_CALLBACK(OnGripperMotionNotifyThunk), this);
|
| - signals_.Connect(gripper, "expose-event",
|
| - G_CALLBACK(OnGripperExposeThunk), this);
|
| - signals_.Connect(gripper, "enter-notify-event",
|
| - G_CALLBACK(OnGripperEnterNotifyThunk), this);
|
| - signals_.Connect(gripper, "leave-notify-event",
|
| - G_CALLBACK(OnGripperLeaveNotifyThunk), this);
|
| - signals_.Connect(gripper, "button-release-event",
|
| - G_CALLBACK(OnGripperButtonReleaseThunk), this);
|
| - signals_.Connect(gripper, "button-press-event",
|
| - G_CALLBACK(OnGripperButtonPressThunk), this);
|
| - signals_.Connect(chevron(), "button-press-event",
|
| - G_CALLBACK(OnOverflowButtonPressThunk), this);
|
| -
|
| - // |overflow_alignment| adds padding to the right of the browser action
|
| - // buttons, but only appears when the overflow menu is showing.
|
| - overflow_alignment_.Own(gtk_alignment_new(0, 0, 1, 1));
|
| - gtk_container_add(GTK_CONTAINER(overflow_alignment_.get()), chevron());
|
| -
|
| - // |overflow_area_| holds the overflow chevron and the separator, which
|
| - // is only shown in GTK+ theme mode.
|
| - overflow_area_.Own(gtk_hbox_new(FALSE, 0));
|
| - gtk_box_pack_start(GTK_BOX(overflow_area_.get()), overflow_alignment_.get(),
|
| - FALSE, FALSE, 0);
|
| -
|
| - separator_.Own(gtk_vseparator_new());
|
| - gtk_box_pack_start(GTK_BOX(overflow_area_.get()), separator_.get(),
|
| - FALSE, FALSE, 0);
|
| - gtk_widget_set_no_show_all(separator_.get(), TRUE);
|
| -
|
| - gtk_widget_show_all(overflow_area_.get());
|
| - gtk_widget_set_no_show_all(overflow_area_.get(), TRUE);
|
| -
|
| - gtk_box_pack_start(GTK_BOX(hbox_.get()), gripper, FALSE, FALSE, 0);
|
| - gtk_box_pack_start(GTK_BOX(hbox_.get()), button_hbox_.get(), TRUE, TRUE, 0);
|
| - gtk_box_pack_start(GTK_BOX(hbox_.get()), overflow_area_.get(), FALSE, FALSE,
|
| - 0);
|
| -
|
| - model_->AddObserver(this);
|
| - SetupDrags();
|
| -
|
| - if (model_->extensions_initialized()) {
|
| - CreateAllButtons();
|
| - SetContainerWidth();
|
| - }
|
| -
|
| - // We want to connect to "set-focus" on the toplevel window; we have to wait
|
| - // until we are added to a toplevel window to do so.
|
| - signals_.Connect(widget(), "hierarchy-changed",
|
| - G_CALLBACK(OnHierarchyChangedThunk), this);
|
| -
|
| - ViewIDUtil::SetID(button_hbox_.get(), VIEW_ID_BROWSER_ACTION_TOOLBAR);
|
| -
|
| - registrar_.Add(this,
|
| - chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
|
| - content::Source<ThemeService>(theme_service_));
|
| - theme_service_->InitThemesFor(this);
|
| -}
|
| -
|
| -BrowserActionsToolbarGtk::~BrowserActionsToolbarGtk() {
|
| - if (model_)
|
| - model_->RemoveObserver(this);
|
| - button_hbox_.Destroy();
|
| - hbox_.Destroy();
|
| -}
|
| -
|
| -int BrowserActionsToolbarGtk::GetCurrentTabId() const {
|
| - content::WebContents* active_tab =
|
| - browser_->tab_strip_model()->GetActiveWebContents();
|
| - if (!active_tab)
|
| - return -1;
|
| -
|
| - return SessionTabHelper::FromWebContents(active_tab)->session_id().id();
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::Update() {
|
| - for (ExtensionButtonMap::iterator iter = extension_button_map_.begin();
|
| - iter != extension_button_map_.end(); ++iter) {
|
| - iter->second->UpdateState();
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::Observe(
|
| - int type,
|
| - const content::NotificationSource& source,
|
| - const content::NotificationDetails& details) {
|
| - DCHECK(chrome::NOTIFICATION_BROWSER_THEME_CHANGED == type);
|
| - gtk_widget_set_visible(separator_.get(), theme_service_->UsingNativeTheme());
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::SetupDrags() {
|
| - GtkTargetEntry drag_target = GetDragTargetEntry();
|
| - gtk_drag_dest_set(button_hbox_.get(), GTK_DEST_DEFAULT_DROP, &drag_target, 1,
|
| - GDK_ACTION_MOVE);
|
| -
|
| - signals_.Connect(button_hbox_.get(), "drag-motion",
|
| - G_CALLBACK(OnDragMotionThunk), this);
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::CreateAllButtons() {
|
| - extension_button_map_.clear();
|
| -
|
| - int i = 0;
|
| - const extensions::ExtensionList& toolbar_items = model_->toolbar_items();
|
| - for (extensions::ExtensionList::const_iterator iter = toolbar_items.begin();
|
| - iter != toolbar_items.end(); ++iter) {
|
| - CreateButtonForExtension(iter->get(), i++);
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::SetContainerWidth() {
|
| - int showing_actions = model_->GetVisibleIconCount();
|
| - if (showing_actions >= 0)
|
| - SetButtonHBoxWidth(WidthForIconCount(showing_actions));
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::CreateButtonForExtension(
|
| - const Extension* extension, int index) {
|
| - if (!ShouldDisplayBrowserAction(extension))
|
| - return;
|
| -
|
| - if (profile_->IsOffTheRecord())
|
| - index = model_->OriginalIndexToIncognito(index);
|
| -
|
| - RemoveButtonForExtension(extension);
|
| - linked_ptr<BrowserActionButton> button(
|
| - new BrowserActionButton(this, extension, theme_service_));
|
| - gtk_chrome_shrinkable_hbox_pack_start(
|
| - GTK_CHROME_SHRINKABLE_HBOX(button_hbox_.get()), button->widget(), 0);
|
| - gtk_box_reorder_child(GTK_BOX(button_hbox_.get()), button->widget(), index);
|
| - extension_button_map_[extension->id()] = button;
|
| -
|
| - GtkTargetEntry drag_target = GetDragTargetEntry();
|
| - gtk_drag_source_set(button->button(), GDK_BUTTON1_MASK, &drag_target, 1,
|
| - GDK_ACTION_MOVE);
|
| - // We ignore whether the drag was a "success" or "failure" in Gtk's opinion.
|
| - signals_.Connect(button->button(), "drag-end",
|
| - G_CALLBACK(&OnDragEndThunk), this);
|
| - signals_.Connect(button->button(), "drag-failed",
|
| - G_CALLBACK(&OnDragFailedThunk), this);
|
| -
|
| - // Any time a browser action button is shown or hidden we have to update
|
| - // the chevron state.
|
| - signals_.Connect(button->widget(), "show",
|
| - G_CALLBACK(&OnButtonShowOrHideThunk), this);
|
| - signals_.Connect(button->widget(), "hide",
|
| - G_CALLBACK(&OnButtonShowOrHideThunk), this);
|
| -
|
| - gtk_widget_show(button->widget());
|
| -
|
| - UpdateVisibility();
|
| -}
|
| -
|
| -BrowserActionButton* BrowserActionsToolbarGtk::GetBrowserActionButton(
|
| - const Extension* extension) {
|
| - ExtensionButtonMap::iterator it = extension_button_map_.find(
|
| - extension->id());
|
| - return it == extension_button_map_.end() ? NULL : it->second.get();
|
| -}
|
| -
|
| -GtkWidget* BrowserActionsToolbarGtk::GetBrowserActionWidget(
|
| - const Extension* extension) {
|
| - BrowserActionButton* button = GetBrowserActionButton(extension);
|
| - return button == NULL ? NULL : button->widget();
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::RemoveButtonForExtension(
|
| - const Extension* extension) {
|
| - if (extension_button_map_.erase(extension->id()))
|
| - UpdateVisibility();
|
| - UpdateChevronVisibility();
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::UpdateVisibility() {
|
| - gtk_widget_set_visible(widget(), button_count() != 0);
|
| -}
|
| -
|
| -bool BrowserActionsToolbarGtk::ShouldDisplayBrowserAction(
|
| - const Extension* extension) {
|
| - // Only display incognito-enabled extensions while in incognito mode.
|
| - return (!profile_->IsOffTheRecord() ||
|
| - extensions::util::IsIncognitoEnabled(extension->id(), profile_));
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::HidePopup() {
|
| - ExtensionPopupGtk* popup = ExtensionPopupGtk::get_current_extension_popup();
|
| - if (popup)
|
| - popup->DestroyPopup();
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::AnimateToShowNIcons(int count) {
|
| - desired_width_ = WidthForIconCount(count);
|
| -
|
| - GtkAllocation allocation;
|
| - gtk_widget_get_allocation(button_hbox_.get(), &allocation);
|
| - start_width_ = allocation.width;
|
| -
|
| - resize_animation_.Reset();
|
| - resize_animation_.Show();
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::BrowserActionAdded(const Extension* extension,
|
| - int index) {
|
| - overflow_menu_.reset();
|
| -
|
| - CreateButtonForExtension(extension, index);
|
| -
|
| - // If we are still initializing the container, don't bother animating.
|
| - if (!model_->extensions_initialized())
|
| - return;
|
| -
|
| - // Animate the addition if we are showing all browser action buttons.
|
| - if (!gtk_widget_get_visible(overflow_area_.get())) {
|
| - AnimateToShowNIcons(button_count());
|
| - model_->SetVisibleIconCount(button_count());
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::BrowserActionRemoved(
|
| - const Extension* extension) {
|
| - overflow_menu_.reset();
|
| -
|
| - if (drag_button_ != NULL) {
|
| - // Break the current drag.
|
| - gtk_grab_remove(button_hbox_.get());
|
| - }
|
| -
|
| - RemoveButtonForExtension(extension);
|
| -
|
| - if (!gtk_widget_get_visible(overflow_area_.get())) {
|
| - AnimateToShowNIcons(button_count());
|
| - model_->SetVisibleIconCount(button_count());
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::BrowserActionMoved(const Extension* extension,
|
| - int index) {
|
| - // We initiated this move action, and have already moved the button.
|
| - if (drag_button_ != NULL)
|
| - return;
|
| -
|
| - GtkWidget* button_widget = GetBrowserActionWidget(extension);
|
| - if (!button_widget) {
|
| - if (ShouldDisplayBrowserAction(extension))
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - if (profile_->IsOffTheRecord())
|
| - index = model_->OriginalIndexToIncognito(index);
|
| -
|
| - gtk_box_reorder_child(GTK_BOX(button_hbox_.get()), button_widget, index);
|
| -}
|
| -
|
| -bool BrowserActionsToolbarGtk::BrowserActionShowPopup(
|
| - const Extension* extension) {
|
| - // Do not override other popups and only show in active window.
|
| - if (ExtensionPopupGtk::get_current_extension_popup() ||
|
| - !browser_->window()->IsActive()) {
|
| - return false;
|
| - }
|
| -
|
| - BrowserActionButton* button = GetBrowserActionButton(extension);
|
| - if (button == NULL || button->widget() == NULL)
|
| - return false;
|
| -
|
| - GtkWidget* anchor = button->widget();
|
| - if (!gtk_widget_get_visible(anchor))
|
| - anchor = button->toolbar_->chevron();
|
| - return button->Activate(anchor, false);
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::VisibleCountChanged() {
|
| - SetContainerWidth();
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::AnimationProgressed(
|
| - const gfx::Animation* animation) {
|
| - int width = start_width_ + (desired_width_ - start_width_) *
|
| - animation->GetCurrentValue();
|
| - gtk_widget_set_size_request(button_hbox_.get(), width, -1);
|
| -
|
| - if (width == desired_width_)
|
| - resize_animation_.Reset();
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::AnimationEnded(const gfx::Animation* animation) {
|
| - gtk_widget_set_size_request(button_hbox_.get(), desired_width_, -1);
|
| - UpdateChevronVisibility();
|
| -}
|
| -
|
| -bool BrowserActionsToolbarGtk::IsCommandIdChecked(int command_id) const {
|
| - return false;
|
| -}
|
| -
|
| -bool BrowserActionsToolbarGtk::IsCommandIdEnabled(int command_id) const {
|
| - const Extension* extension = model_->toolbar_items()[command_id].get();
|
| - return ExtensionActionManager::Get(profile_)->GetBrowserAction(*extension)
|
| - ->GetIsVisible(GetCurrentTabId());
|
| -}
|
| -
|
| -bool BrowserActionsToolbarGtk::GetAcceleratorForCommandId(
|
| - int command_id,
|
| - ui::Accelerator* accelerator) {
|
| - return false;
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::ExecuteCommand(int command_id, int event_flags) {
|
| - const Extension* extension = model_->toolbar_items()[command_id].get();
|
| - GURL popup_url;
|
| -
|
| - switch (model_->ExecuteBrowserAction(
|
| - extension, browser(), &popup_url, true)) {
|
| - case extensions::ExtensionToolbarModel::ACTION_NONE:
|
| - break;
|
| - case extensions::ExtensionToolbarModel::ACTION_SHOW_POPUP:
|
| - ExtensionPopupGtk::Show(popup_url, browser(), chevron(),
|
| - ExtensionPopupGtk::SHOW);
|
| - break;
|
| - }
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::StoppedShowing() {
|
| - overflow_button_->UnsetPaintOverride();
|
| -}
|
| -
|
| -bool BrowserActionsToolbarGtk::AlwaysShowIconForCmd(int command_id) const {
|
| - return true;
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::DragStarted(BrowserActionButton* button,
|
| - GdkDragContext* drag_context) {
|
| - // No representation of the widget following the cursor.
|
| - GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
|
| - gtk_drag_set_icon_pixbuf(drag_context, pixbuf, 0, 0);
|
| - g_object_unref(pixbuf);
|
| -
|
| - DCHECK(!drag_button_);
|
| - drag_button_ = button;
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::SetButtonHBoxWidth(int new_width) {
|
| - gint max_width = WidthForIconCount(button_count());
|
| - new_width = std::min(max_width, new_width);
|
| - new_width = std::max(new_width, 0);
|
| - gtk_widget_set_size_request(button_hbox_.get(), new_width, -1);
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::UpdateChevronVisibility() {
|
| - int showing_icon_count =
|
| - gtk_chrome_shrinkable_hbox_get_visible_child_count(
|
| - GTK_CHROME_SHRINKABLE_HBOX(button_hbox_.get()));
|
| - if (showing_icon_count == 0) {
|
| - gtk_alignment_set_padding(GTK_ALIGNMENT(overflow_alignment_.get()),
|
| - 0, 0, 0, 0);
|
| - } else {
|
| - gtk_alignment_set_padding(GTK_ALIGNMENT(overflow_alignment_.get()),
|
| - 0, 0, kButtonChevronPadding, 0);
|
| - }
|
| -
|
| - if (button_count() > showing_icon_count) {
|
| - if (!gtk_widget_get_visible(overflow_area_.get())) {
|
| - if (drag_button_) {
|
| - // During drags, when the overflow chevron shows for the first time,
|
| - // take that much space away from |button_hbox_| to make the drag look
|
| - // smoother.
|
| - GtkRequisition req;
|
| - gtk_widget_size_request(chevron(), &req);
|
| - gint overflow_width = req.width;
|
| - gtk_widget_size_request(button_hbox_.get(), &req);
|
| - gint button_hbox_width = req.width;
|
| - button_hbox_width = std::max(button_hbox_width - overflow_width, 0);
|
| - gtk_widget_set_size_request(button_hbox_.get(), button_hbox_width, -1);
|
| - }
|
| -
|
| - gtk_widget_show(overflow_area_.get());
|
| - }
|
| - } else {
|
| - gtk_widget_hide(overflow_area_.get());
|
| - }
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnDragMotion(GtkWidget* widget,
|
| - GdkDragContext* drag_context,
|
| - gint x, gint y, guint time) {
|
| - // Only handle drags we initiated.
|
| - if (!drag_button_)
|
| - return FALSE;
|
| -
|
| - if (base::i18n::IsRTL()) {
|
| - GtkAllocation allocation;
|
| - gtk_widget_get_allocation(widget, &allocation);
|
| - x = allocation.width - x;
|
| - }
|
| -
|
| - drop_index_ = x < kButtonWidth ? 0 : x / (kButtonWidth + kButtonPadding);
|
| -
|
| - // We will go ahead and reorder the child in order to provide visual feedback
|
| - // to the user. We don't inform the model that it has moved until the drag
|
| - // ends.
|
| - gtk_box_reorder_child(GTK_BOX(button_hbox_.get()), drag_button_->widget(),
|
| - drop_index_);
|
| -
|
| - gdk_drag_status(drag_context, GDK_ACTION_MOVE, time);
|
| - return TRUE;
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::OnDragEnd(GtkWidget* button,
|
| - GdkDragContext* drag_context) {
|
| - if (drop_index_ != -1) {
|
| - if (profile_->IsOffTheRecord())
|
| - drop_index_ = model_->IncognitoIndexToOriginal(drop_index_);
|
| -
|
| - model_->MoveBrowserAction(drag_button_->extension(), drop_index_);
|
| - }
|
| -
|
| - drag_button_ = NULL;
|
| - drop_index_ = -1;
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnDragFailed(GtkWidget* widget,
|
| - GdkDragContext* drag_context,
|
| - GtkDragResult result) {
|
| - // We connect to this signal and return TRUE so that the default failure
|
| - // animation (wherein the drag widget floats back to the start of the drag)
|
| - // does not show, and the drag-end signal is emitted immediately instead of
|
| - // several seconds later.
|
| - return TRUE;
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::OnHierarchyChanged(
|
| - GtkWidget* widget, GtkWidget* previous_toplevel) {
|
| - GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
|
| - if (!gtk_widget_is_toplevel(toplevel))
|
| - return;
|
| -
|
| - signals_.Connect(toplevel, "set-focus", G_CALLBACK(OnSetFocusThunk), this);
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::OnSetFocus(GtkWidget* widget,
|
| - GtkWidget* focus_widget) {
|
| - ExtensionPopupGtk* popup = ExtensionPopupGtk::get_current_extension_popup();
|
| - // The focus of the parent window has changed. Close the popup. Delay the hide
|
| - // because it will destroy the RenderViewHost, which may still be on the
|
| - // call stack.
|
| - if (!popup || popup->being_inspected())
|
| - return;
|
| - base::MessageLoop::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&BrowserActionsToolbarGtk::HidePopup,
|
| - weak_factory_.GetWeakPtr()));
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnGripperMotionNotify(
|
| - GtkWidget* widget, GdkEventMotion* event) {
|
| - if (!(event->state & GDK_BUTTON1_MASK))
|
| - return FALSE;
|
| -
|
| - // Calculate how much the user dragged the gripper and subtract that off the
|
| - // button container's width.
|
| - int distance_dragged;
|
| - if (base::i18n::IsRTL()) {
|
| - distance_dragged = -event->x;
|
| - } else {
|
| - GtkAllocation widget_allocation;
|
| - gtk_widget_get_allocation(widget, &widget_allocation);
|
| - distance_dragged = event->x - widget_allocation.width;
|
| - }
|
| -
|
| - GtkAllocation button_hbox_allocation;
|
| - gtk_widget_get_allocation(button_hbox_.get(), &button_hbox_allocation);
|
| - gint new_width = button_hbox_allocation.width - distance_dragged;
|
| - SetButtonHBoxWidth(new_width);
|
| -
|
| - return FALSE;
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnGripperExpose(GtkWidget* gripper,
|
| - GdkEventExpose* expose) {
|
| - return TRUE;
|
| -}
|
| -
|
| -// These three signal handlers (EnterNotify, LeaveNotify, and ButtonRelease)
|
| -// are used to give the gripper the resize cursor. Since it doesn't have its
|
| -// own window, we have to set the cursor whenever the pointer moves into the
|
| -// button or leaves the button, and be sure to leave it on when the user is
|
| -// dragging.
|
| -gboolean BrowserActionsToolbarGtk::OnGripperEnterNotify(
|
| - GtkWidget* gripper, GdkEventCrossing* event) {
|
| - gdk_window_set_cursor(gtk_widget_get_window(gripper),
|
| - gfx::GetCursor(GDK_SB_H_DOUBLE_ARROW));
|
| - return FALSE;
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnGripperLeaveNotify(
|
| - GtkWidget* gripper, GdkEventCrossing* event) {
|
| - if (!(event->state & GDK_BUTTON1_MASK))
|
| - gdk_window_set_cursor(gtk_widget_get_window(gripper), NULL);
|
| - return FALSE;
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnGripperButtonRelease(
|
| - GtkWidget* gripper, GdkEventButton* event) {
|
| - GtkAllocation allocation;
|
| - gtk_widget_get_allocation(gripper, &allocation);
|
| - gfx::Rect gripper_rect(0, 0, allocation.width, allocation.height);
|
| -
|
| - gfx::Point release_point(event->x, event->y);
|
| - if (!gripper_rect.Contains(release_point))
|
| - gdk_window_set_cursor(gtk_widget_get_window(gripper), NULL);
|
| -
|
| - // After the user resizes the toolbar, we want to smartly resize it to be
|
| - // the perfect size to fit the buttons.
|
| - int visible_icon_count =
|
| - gtk_chrome_shrinkable_hbox_get_visible_child_count(
|
| - GTK_CHROME_SHRINKABLE_HBOX(button_hbox_.get()));
|
| - AnimateToShowNIcons(visible_icon_count);
|
| - model_->SetVisibleIconCount(visible_icon_count);
|
| -
|
| - return FALSE;
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnGripperButtonPress(
|
| - GtkWidget* gripper, GdkEventButton* event) {
|
| - resize_animation_.Reset();
|
| -
|
| - return FALSE;
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnOverflowButtonPress(
|
| - GtkWidget* overflow, GdkEventButton* event) {
|
| - overflow_menu_model_.reset(new SimpleMenuModel(this));
|
| -
|
| - int visible_icon_count =
|
| - gtk_chrome_shrinkable_hbox_get_visible_child_count(
|
| - GTK_CHROME_SHRINKABLE_HBOX(button_hbox_.get()));
|
| - for (int i = visible_icon_count; i < button_count(); ++i) {
|
| - int model_index = i;
|
| - if (profile_->IsOffTheRecord())
|
| - model_index = model_->IncognitoIndexToOriginal(i);
|
| -
|
| - const Extension* extension = model_->toolbar_items()[model_index].get();
|
| - BrowserActionButton* button = extension_button_map_[extension->id()].get();
|
| -
|
| - overflow_menu_model_->AddItem(model_index,
|
| - base::UTF8ToUTF16(extension->name()));
|
| - overflow_menu_model_->SetIcon(overflow_menu_model_->GetItemCount() - 1,
|
| - button->GetIcon());
|
| -
|
| - // TODO(estade): set the menu item's tooltip.
|
| - }
|
| -
|
| - overflow_menu_.reset(new MenuGtk(this, overflow_menu_model_.get()));
|
| - signals_.Connect(overflow_menu_->widget(), "button-press-event",
|
| - G_CALLBACK(OnOverflowMenuButtonPressThunk), this);
|
| -
|
| - overflow_button_->SetPaintOverride(GTK_STATE_ACTIVE);
|
| - overflow_menu_->PopupAsFromKeyEvent(chevron());
|
| -
|
| - return FALSE;
|
| -}
|
| -
|
| -gboolean BrowserActionsToolbarGtk::OnOverflowMenuButtonPress(
|
| - GtkWidget* overflow, GdkEventButton* event) {
|
| - if (event->button != 3)
|
| - return FALSE;
|
| -
|
| - GtkWidget* menu_item = GTK_MENU_SHELL(overflow)->active_menu_item;
|
| - if (!menu_item)
|
| - return FALSE;
|
| -
|
| - int item_index = g_list_index(GTK_MENU_SHELL(overflow)->children, menu_item);
|
| - if (item_index == -1) {
|
| - NOTREACHED();
|
| - return FALSE;
|
| - }
|
| -
|
| - item_index += gtk_chrome_shrinkable_hbox_get_visible_child_count(
|
| - GTK_CHROME_SHRINKABLE_HBOX(button_hbox_.get()));
|
| - if (profile_->IsOffTheRecord())
|
| - item_index = model_->IncognitoIndexToOriginal(item_index);
|
| -
|
| - const Extension* extension = model_->toolbar_items()[item_index].get();
|
| - BrowserActionButton* button = GetBrowserActionButton(extension);
|
| - if (button == NULL) {
|
| - NOTREACHED();
|
| - return FALSE;
|
| - }
|
| -
|
| - MenuGtk* menu = button->GetContextMenu();
|
| - if (!menu)
|
| - return FALSE;
|
| -
|
| - menu->PopupAsContext(gfx::Point(event->x_root, event->y_root),
|
| - event->time);
|
| - return TRUE;
|
| -}
|
| -
|
| -void BrowserActionsToolbarGtk::OnButtonShowOrHide(GtkWidget* sender) {
|
| - if (!resize_animation_.is_animating())
|
| - UpdateChevronVisibility();
|
| -}
|
|
|