summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-26 20:18:21 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-26 20:18:21 +0000
commit6463cb2a117dcd866a12becb513cfdba935c16e5 (patch)
tree929c60acd2a4bd78e9b6f4ccbbf0c3bfa4bcf495
parent32d0ef5d82ef2e972635245107825e776072dc82 (diff)
downloadchromium_src-6463cb2a117dcd866a12becb513cfdba935c16e5.zip
chromium_src-6463cb2a117dcd866a12becb513cfdba935c16e5.tar.gz
chromium_src-6463cb2a117dcd866a12becb513cfdba935c16e5.tar.bz2
Refactor back/forward buttons to their own class. Fix them so the menu pops up on drags and the buttons look depressed when the menu is showing.
BUG=12427 TEST=back/forward button behavior should be as on windows (see bug desc. for details). Review URL: http://codereview.chromium.org/113806 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16898 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/back_forward_button_gtk.cc121
-rw-r--r--chrome/browser/gtk/back_forward_button_gtk.h71
-rw-r--r--chrome/browser/gtk/back_forward_menu_model_gtk.cc15
-rw-r--r--chrome/browser/gtk/back_forward_menu_model_gtk.h8
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc154
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h48
-rw-r--r--chrome/browser/gtk/custom_button.cc18
-rw-r--r--chrome/browser/gtk/custom_button.h12
-rw-r--r--chrome/chrome.gyp2
9 files changed, 275 insertions, 174 deletions
diff --git a/chrome/browser/gtk/back_forward_button_gtk.cc b/chrome/browser/gtk/back_forward_button_gtk.cc
new file mode 100644
index 0000000..ae46c4d
--- /dev/null
+++ b/chrome/browser/gtk/back_forward_button_gtk.cc
@@ -0,0 +1,121 @@
+// Copyright (c) 2009 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/gtk/back_forward_button_gtk.h"
+
+#include <gtk/gtk.h>
+
+#include "app/l10n_util.h"
+#include "base/message_loop.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/gtk/back_forward_menu_model_gtk.h"
+#include "chrome/browser/gtk/menu_gtk.h"
+#include "grit/generated_resources.h"
+
+// The time in milliseconds between when the user clicks and the menu appears.
+static const int kMenuTimerDelay = 500;
+
+BackForwardButtonGtk::BackForwardButtonGtk(Browser* browser, bool is_forward)
+ : browser_(browser),
+ is_forward_(is_forward),
+ show_menu_factory_(this) {
+ int normal, active, highlight, depressed, tooltip;
+ if (is_forward) {
+ normal = IDR_FORWARD;
+ active = IDR_FORWARD_P;
+ highlight = IDR_FORWARD_H;
+ depressed = IDR_FORWARD_D;
+ tooltip = IDS_TOOLTIP_FORWARD;
+ } else {
+ normal = IDR_BACK;
+ active = IDR_BACK_P;
+ highlight = IDR_BACK_H;
+ depressed = IDR_BACK_D;
+ tooltip = IDS_TOOLTIP_BACK;
+ }
+ button_.reset(new CustomDrawButton(normal, active, highlight, depressed));
+ gtk_widget_set_tooltip_text(widget(),
+ l10n_util::GetStringUTF8(tooltip).c_str());
+ menu_model_.reset(new BackForwardMenuModelGtk(browser,
+ is_forward ?
+ BackForwardMenuModel::FORWARD_MENU_DELEGATE :
+ BackForwardMenuModel::BACKWARD_MENU_DELEGATE,
+ this));
+
+ g_signal_connect(widget(), "clicked",
+ G_CALLBACK(OnClick), this);
+ g_signal_connect(widget(), "button-press-event",
+ G_CALLBACK(OnButtonPress), this);
+ gtk_widget_add_events(widget(), GDK_POINTER_MOTION_MASK);
+ g_signal_connect(widget(), "motion-notify-event",
+ G_CALLBACK(OnMouseMove), this);
+
+ // Popup the menu as left-aligned relative to this widget rather than the
+ // default of right aligned.
+ g_object_set_data(G_OBJECT(widget()), "left-align-popup",
+ reinterpret_cast<void*>(true));
+}
+
+BackForwardButtonGtk::~BackForwardButtonGtk() {
+}
+
+void BackForwardButtonGtk::StoppedShowingMenu() {
+ button_->UnsetPaintOverride();
+}
+
+void BackForwardButtonGtk::ShowBackForwardMenu() {
+ menu_.reset(new MenuGtk(menu_model_.get(), true));
+ button_->SetPaintOverride(GTK_STATE_ACTIVE);
+
+ // gtk_menu_popup will ignore the first mouse button release if it matches
+ // the button type and is within a short span of the time we pass here.
+ // Since this menu is not popped up by a button press (instead, it is popped
+ // up either on a timer or on a drag) this doesn't apply to us and we can
+ // pass arbitrary values.
+ menu_->Popup(widget(), 1, gtk_get_current_event_time());
+}
+
+// static
+void BackForwardButtonGtk::OnClick(GtkWidget* widget,
+ BackForwardButtonGtk* button) {
+ button->show_menu_factory_.RevokeAll();
+
+ button->browser_->ExecuteCommand(button->is_forward_ ?
+ IDC_FORWARD : IDC_BACK);
+}
+
+// static
+gboolean BackForwardButtonGtk::OnButtonPress(GtkWidget* widget,
+ GdkEventButton* event, BackForwardButtonGtk* button) {
+ if (event->button != 1)
+ return FALSE;
+
+ button->y_position_of_last_press_ = event->y;
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ button->show_menu_factory_.NewRunnableMethod(
+ &BackForwardButtonGtk::ShowBackForwardMenu),
+ kMenuTimerDelay);
+ return FALSE;
+}
+
+// static
+gboolean BackForwardButtonGtk::OnMouseMove(GtkWidget* widget,
+ GdkEventMotion* event, BackForwardButtonGtk* button) {
+ // If we aren't waiting to show the back forward menu, do nothing.
+ if (button->show_menu_factory_.empty())
+ return FALSE;
+
+ // We only count moves about a certain threshold.
+ GtkSettings* settings = gtk_widget_get_settings(widget);
+ int drag_min_distance;
+ g_object_get(settings, "gtk-dnd-drag-threshold", &drag_min_distance, NULL);
+ if (event->y - button->y_position_of_last_press_ < drag_min_distance)
+ return FALSE;
+
+ // We will show the menu now. Cancel the delayed event.
+ button->show_menu_factory_.RevokeAll();
+ button->ShowBackForwardMenu();
+ return FALSE;
+}
diff --git a/chrome/browser/gtk/back_forward_button_gtk.h b/chrome/browser/gtk/back_forward_button_gtk.h
new file mode 100644
index 0000000..64af330
--- /dev/null
+++ b/chrome/browser/gtk/back_forward_button_gtk.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2009 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_GTK_BACK_FORWARD_BUTTON_GTK_
+#define CHROME_BROWSER_GTK_BACK_FORWARD_BUTTON_GTK_
+
+#include "base/scoped_ptr.h"
+#include "base/task.h"
+#include "chrome/browser/gtk/custom_button.h"
+
+class BackForwardMenuModelGtk;
+class Browser;
+class MenuGtk;
+
+typedef struct _GtkWidget GtkWidget;
+
+// When clicked, these buttons will navigate forward or backward. When
+// pressed and held, they show a dropdown menu of recent web sites.
+class BackForwardButtonGtk {
+ public:
+ BackForwardButtonGtk(Browser* browser, bool is_forward);
+ virtual ~BackForwardButtonGtk();
+
+ // The dropdown menu is no longer showing.
+ void StoppedShowingMenu();
+
+ GtkWidget* widget() { return button_->widget(); }
+
+ private:
+ // Executes the browser command.
+ static void OnClick(GtkWidget* widget, BackForwardButtonGtk* button);
+
+ // Starts a timer to show the dropdown menu.
+ static gboolean OnButtonPress(GtkWidget* button,
+ GdkEventButton* event,
+ BackForwardButtonGtk* toolbar);
+
+ // If there is a timer to show the dropdown menu, and the mouse has moved
+ // sufficiently down the screen, cancel the timer and immediately show the
+ // menu.
+ static gboolean OnMouseMove(GtkWidget* widget,
+ GdkEventMotion* event,
+ BackForwardButtonGtk* toolbar);
+
+ // Shows the dropdown menu.
+ void ShowBackForwardMenu();
+
+ // The menu gets reset every time it is shown.
+ scoped_ptr<MenuGtk> menu_;
+
+ scoped_ptr<CustomDrawButton> button_;
+
+ // The browser to which we will send commands.
+ Browser* browser_;
+
+ // Whether this button is a forward button.
+ bool is_forward_;
+
+ // The dropdown menu delegate.
+ scoped_ptr<BackForwardMenuModelGtk> menu_model_;
+
+ // The y position of the last mouse down event.
+ int y_position_of_last_press_;
+
+ ScopedRunnableMethodFactory<BackForwardButtonGtk> show_menu_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackForwardButtonGtk);
+};
+
+#endif // CHROME_BROWSER_GTK_BACK_FORWARD_BUTTON_GTK_
diff --git a/chrome/browser/gtk/back_forward_menu_model_gtk.cc b/chrome/browser/gtk/back_forward_menu_model_gtk.cc
index 6db3234..99d9ee4 100644
--- a/chrome/browser/gtk/back_forward_menu_model_gtk.cc
+++ b/chrome/browser/gtk/back_forward_menu_model_gtk.cc
@@ -5,15 +5,12 @@
#include "chrome/browser/gtk/back_forward_menu_model_gtk.h"
#include "base/string_util.h"
-
-// static
-BackForwardMenuModel* BackForwardMenuModel::Create(Browser* browser,
- ModelType model_type) {
- return new BackForwardMenuModelGtk(browser, model_type);
-}
+#include "chrome/browser/gtk/back_forward_button_gtk.h"
BackForwardMenuModelGtk::BackForwardMenuModelGtk(Browser* browser,
- ModelType model_type) {
+ ModelType model_type,
+ BackForwardButtonGtk* button)
+ : button_(button) {
browser_ = browser;
model_type_ = model_type;
}
@@ -45,3 +42,7 @@ bool BackForwardMenuModelGtk::IsCommandEnabled(int command_id) const {
void BackForwardMenuModelGtk::ExecuteCommand(int command_id) {
ExecuteCommandById(command_id);
}
+
+void BackForwardMenuModelGtk::StoppedShowing() {
+ button_->StoppedShowingMenu();
+}
diff --git a/chrome/browser/gtk/back_forward_menu_model_gtk.h b/chrome/browser/gtk/back_forward_menu_model_gtk.h
index 2056194..0704b98 100644
--- a/chrome/browser/gtk/back_forward_menu_model_gtk.h
+++ b/chrome/browser/gtk/back_forward_menu_model_gtk.h
@@ -10,12 +10,15 @@
#include "chrome/browser/back_forward_menu_model.h"
#include "chrome/browser/gtk/menu_gtk.h"
+class BackForwardButtonGtk;
+
// For the most part, this class simply passes calls through to
// the BackForwardMenuModel.
class BackForwardMenuModelGtk : public BackForwardMenuModel,
public MenuGtk::Delegate {
public:
- BackForwardMenuModelGtk(Browser* browser, ModelType model_type);
+ BackForwardMenuModelGtk(Browser* browser, ModelType model_type,
+ BackForwardButtonGtk* button);
// MenuGtk::Delegate
virtual int GetItemCount() const;
@@ -25,8 +28,11 @@ class BackForwardMenuModelGtk : public BackForwardMenuModel,
virtual const SkBitmap* GetIcon(int menu_id) const;
virtual bool IsCommandEnabled(int command_id) const;
virtual void ExecuteCommand(int command_id);
+ virtual void StoppedShowing();
private:
+ BackForwardButtonGtk* button_;
+
DISALLOW_COPY_AND_ASSIGN(BackForwardMenuModelGtk);
};
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index 72148b1..f55016c1 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -14,7 +14,7 @@
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_theme_provider.h"
-#include "chrome/browser/gtk/back_forward_menu_model_gtk.h"
+#include "chrome/browser/gtk/back_forward_button_gtk.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/go_button_gtk.h"
#include "chrome/browser/gtk/gtk_chrome_button.h"
@@ -46,10 +46,6 @@ const int kPopupTopMargin = 0;
// to leave 1 pixel on both side here so that the borders line up.
const int kPopupLeftRightMargin = 1;
-// For the back/forward dropdown menus, the time in milliseconds between
-// when the user clicks and the popup menu appears.
-const int kMenuTimerDelay = 500;
-
} // namespace
// BrowserToolbarGtk, public ---------------------------------------------------
@@ -61,30 +57,23 @@ BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser)
this)),
model_(browser->toolbar_model()),
browser_(browser),
- profile_(NULL),
- show_menu_factory_(this) {
+ profile_(NULL) {
browser_->command_updater()->AddCommandObserver(IDC_BACK, this);
browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this);
browser_->command_updater()->AddCommandObserver(IDC_RELOAD, this);
browser_->command_updater()->AddCommandObserver(IDC_HOME, this);
browser_->command_updater()->AddCommandObserver(IDC_STAR, this);
- back_menu_model_.reset(new BackForwardMenuModelGtk(
- browser, BackForwardMenuModel::BACKWARD_MENU_DELEGATE));
- forward_menu_model_.reset(new BackForwardMenuModelGtk(
- browser, BackForwardMenuModel::FORWARD_MENU_DELEGATE));
-
InitNineBox();
}
BrowserToolbarGtk::~BrowserToolbarGtk() {
// When we created our MenuGtk objects, we pass them a pointer to our accel
- // group. Make sure to tear them down before |accel_group_|.
+ // group. Make sure to tear them down before |accel_group_|.
page_menu_.reset();
app_menu_.reset();
page_menu_button_.Destroy();
app_menu_button_.Destroy();
- back_forward_menu_.reset();
g_object_unref(accel_group_);
}
@@ -100,7 +89,7 @@ void BrowserToolbarGtk::Init(Profile* profile,
// Demand we're always at least kToolbarHeight tall.
// -1 for width means "let GTK do its normal sizing".
gtk_widget_set_size_request(toolbar_, -1, kToolbarHeight);
- g_signal_connect(G_OBJECT(toolbar_), "expose-event",
+ g_signal_connect(toolbar_, "expose-event",
G_CALLBACK(&OnToolbarExpose), this);
// A GtkAccelGroup is not InitiallyUnowned, meaning we get a real reference
@@ -111,28 +100,28 @@ void BrowserToolbarGtk::Init(Profile* profile,
accel_group_ = gtk_accel_group_new();
gtk_window_add_accel_group(top_level_window, accel_group_);
- back_.reset(BuildBackForwardButton(IDR_BACK, IDR_BACK_P, IDR_BACK_H,
- IDR_BACK_D,
- l10n_util::GetStringUTF8(IDS_TOOLTIP_BACK)));
- AddAcceleratorToButton(back_, GDK_Left, GDK_MOD1_MASK);
- AddAcceleratorToButton(back_, GDK_BackSpace, 0);
- forward_.reset(BuildBackForwardButton(IDR_FORWARD, IDR_FORWARD_P,
- IDR_FORWARD_H, IDR_FORWARD_D,
- l10n_util::GetStringUTF8(IDS_TOOLTIP_FORWARD)));
- AddAcceleratorToButton(forward_, GDK_Right, GDK_MOD1_MASK);
- AddAcceleratorToButton(forward_, GDK_BackSpace, GDK_SHIFT_MASK);
-
- // TODO(estade): These blank labels are kind of ghetto. Padding should be
- // handled differently (via spacing parameters or padding widgets that use
- // gtk_widget_set_size_request).
+ back_.reset(new BackForwardButtonGtk(browser_, false));
+ gtk_box_pack_start(GTK_BOX(toolbar_), back_->widget(), FALSE, FALSE, 0);
+ AddAcceleratorToButton(back_->widget(), GDK_Left, GDK_MOD1_MASK);
+ AddAcceleratorToButton(back_->widget(), GDK_BackSpace, 0);
+
+ forward_.reset(new BackForwardButtonGtk(browser_, true));
+ gtk_box_pack_start(GTK_BOX(toolbar_), forward_->widget(), FALSE, FALSE, 0);
+ AddAcceleratorToButton(forward_->widget(), GDK_Right, GDK_MOD1_MASK);
+ AddAcceleratorToButton(forward_->widget(), GDK_BackSpace, GDK_SHIFT_MASK);
+
+ // TODO(estade): These blank labels will change size when the user changes
+ // system font size. We should hard code their size in pixels.
gtk_box_pack_start(GTK_BOX(toolbar_), gtk_label_new(" "), FALSE, FALSE, 0);
reload_.reset(BuildToolbarButton(IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0,
l10n_util::GetStringUTF8(IDS_TOOLTIP_RELOAD)));
- AddAcceleratorToButton(reload_, GDK_r, GDK_CONTROL_MASK);
+ AddAcceleratorToButton(reload_->widget(),
+ GDK_r, GDK_CONTROL_MASK);
// Any modifier except alt can be combined with f5 (this matches windows
// chromium).
- AddAcceleratorToButton(reload_, GDK_F5, GDK_MODIFIER_MASK & ~GDK_MOD1_MASK);
+ AddAcceleratorToButton(reload_->widget(),
+ GDK_F5, GDK_MODIFIER_MASK & ~GDK_MOD1_MASK);
// TODO(port): we need to dynamically react to changes in show_home_button_
// and hide/show home appropriately. But we don't have a UI for it yet.
@@ -294,7 +283,7 @@ CustomDrawButton* BrowserToolbarGtk::BuildToolbarButton(
gtk_widget_set_tooltip_text(button->widget(),
localized_tooltip.c_str());
- g_signal_connect(G_OBJECT(button->widget()), "clicked",
+ g_signal_connect(button->widget(), "clicked",
G_CALLBACK(OnButtonClick), this);
gtk_box_pack_start(GTK_BOX(toolbar_), button->widget(), FALSE, FALSE, 0);
@@ -307,7 +296,7 @@ ToolbarStarToggleGtk* BrowserToolbarGtk::BuildStarButton(
gtk_widget_set_tooltip_text(button->widget(),
localized_tooltip.c_str());
- g_signal_connect(G_OBJECT(button->widget()), "clicked",
+ g_signal_connect(button->widget(), "clicked",
G_CALLBACK(OnButtonClick), this);
gtk_box_pack_start(GTK_BOX(toolbar_), button->widget(), FALSE, FALSE, 0);
@@ -327,7 +316,7 @@ void BrowserToolbarGtk::BuildToolbarMenuButton(
gtk_image_new_from_pixbuf(rb.GetPixbufNamed(icon_id)));
gtk_widget_set_tooltip_text(button, localized_tooltip.c_str());
- g_signal_connect(G_OBJECT(button), "button-press-event",
+ g_signal_connect(button, "button-press-event",
G_CALLBACK(OnMenuButtonPressEvent), this);
GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS);
@@ -358,116 +347,41 @@ void BrowserToolbarGtk::OnButtonClick(GtkWidget* button,
BrowserToolbarGtk* toolbar) {
int tag = -1;
if (button == toolbar->back_->widget())
- tag = IDC_BACK;
- else if (button == toolbar->forward_->widget())
- tag = IDC_FORWARD;
- else if (button == toolbar->reload_->widget())
tag = IDC_RELOAD;
else if (toolbar->home_.get() && button == toolbar->home_->widget())
tag = IDC_HOME;
else if (button == toolbar->star_->widget())
tag = IDC_STAR;
- if (tag == IDC_BACK || tag == IDC_FORWARD)
- toolbar->show_menu_factory_.RevokeAll();
-
DCHECK_NE(tag, -1) << "Impossible button click callback";
toolbar->browser_->ExecuteCommand(tag);
}
// static
gboolean BrowserToolbarGtk::OnMenuButtonPressEvent(GtkWidget* button,
- GdkEvent* event,
+ GdkEventButton* event,
BrowserToolbarGtk* toolbar) {
- if (event->type == GDK_BUTTON_PRESS) {
- GdkEventButton* event_button = reinterpret_cast<GdkEventButton*>(event);
- if (event_button->button == 1) {
- // We have a button press we should respond to.
- if (button == toolbar->page_menu_button_.get()) {
- gtk_chrome_button_set_paint_state(
- GTK_CHROME_BUTTON(toolbar->page_menu_button_.get()),
- GTK_STATE_ACTIVE);
- toolbar->RunPageMenu(event);
- return TRUE;
- } else if (button == toolbar->app_menu_button_.get()) {
- gtk_chrome_button_set_paint_state(
- GTK_CHROME_BUTTON(toolbar->app_menu_button_.get()),
- GTK_STATE_ACTIVE);
- toolbar->RunAppMenu(event);
- return TRUE;
- }
- }
- }
+ if (event->button != 1)
+ return FALSE;
- return FALSE;
-}
+ gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(button),
+ GTK_STATE_ACTIVE);
+ MenuGtk* menu = button == toolbar->page_menu_button_.get() ?
+ toolbar->page_menu_.get() : toolbar->app_menu_.get();
+ menu->Popup(button, reinterpret_cast<GdkEvent*>(event));
-CustomDrawButton* BrowserToolbarGtk::BuildBackForwardButton(
- int normal_id,
- int active_id,
- int highlight_id,
- int depressed_id,
- const std::string& localized_tooltip) {
- CustomDrawButton* button = new CustomDrawButton(normal_id, active_id,
- highlight_id, depressed_id);
-
- gtk_widget_set_tooltip_text(button->widget(),
- localized_tooltip.c_str());
-
- g_signal_connect(G_OBJECT(button->widget()), "button-press-event",
- G_CALLBACK(OnBackForwardPressEvent), this);
- g_signal_connect(G_OBJECT(button->widget()), "clicked",
- G_CALLBACK(OnButtonClick), this);
-
- gtk_box_pack_start(GTK_BOX(toolbar_), button->widget(), FALSE, FALSE, 0);
- // Popup the menu as left-aligned relative to this widget rather than the
- // default of right aligned.
- g_object_set_data(G_OBJECT(button->widget()), "left-align-popup",
- reinterpret_cast<void*>(true));
- return button;
+ return TRUE;
}
void BrowserToolbarGtk::AddAcceleratorToButton(
- const scoped_ptr<CustomDrawButton>& button,
+ GtkWidget* widget,
unsigned int accelerator,
unsigned int accelerator_mod) {
gtk_widget_add_accelerator(
- button->widget(), "clicked", accel_group_, accelerator,
+ widget, "clicked", accel_group_, accelerator,
GdkModifierType(accelerator_mod), GtkAccelFlags(0));
}
-// static
-gboolean BrowserToolbarGtk::OnBackForwardPressEvent(GtkWidget* widget,
- GdkEventButton* event,
- BrowserToolbarGtk* toolbar) {
- // TODO(port): only allow left clicks to open the menu.
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- toolbar->show_menu_factory_.NewRunnableMethod(
- &BrowserToolbarGtk::ShowBackForwardMenu,
- widget, event->button),
- kMenuTimerDelay);
- return FALSE;
-}
-
-void BrowserToolbarGtk::ShowBackForwardMenu(GtkWidget* widget,
- gint button_type) {
- if (widget == back_->widget()) {
- back_forward_menu_.reset(new MenuGtk(back_menu_model_.get(), true));
- } else {
- back_forward_menu_.reset(new MenuGtk(forward_menu_model_.get(), true));
- }
-
- back_forward_menu_->Popup(widget, button_type, gtk_get_current_event_time());
-}
-
-void BrowserToolbarGtk::RunPageMenu(GdkEvent* button_press_event) {
- page_menu_->Popup(page_menu_button_.get(), button_press_event);
-}
-
-void BrowserToolbarGtk::RunAppMenu(GdkEvent* button_press_event) {
- app_menu_->Popup(app_menu_button_.get(), button_press_event);
-}
-
CustomDrawButton* BrowserToolbarGtk::MakeHomeButton() {
return BuildToolbarButton(IDR_HOME, IDR_HOME_P, IDR_HOME_H, 0,
l10n_util::GetStringUTF8(IDS_TOOLTIP_HOME));
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h
index 2cda352..ceafeba 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_toolbar_gtk.h
@@ -9,13 +9,12 @@
#include <string>
#include "base/scoped_ptr.h"
-#include "base/task.h"
#include "chrome/browser/autocomplete/autocomplete_popup_view.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/gtk/menu_gtk.h"
#include "chrome/common/pref_member.h"
-class BackForwardMenuModelGtk;
+class BackForwardButtonGtk;
class Browser;
class CustomDrawButton;
class GoButtonGtk;
@@ -94,9 +93,7 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Adds a keyboard accelerator which triggers a button (e.g., ctrl+r is now
// equivalent to a reload click).
void AddAcceleratorToButton(
- const scoped_ptr<CustomDrawButton>& button,
- unsigned int accelerator,
- unsigned int accelerator_mod);
+ GtkWidget*, unsigned int accelerator, unsigned int accelerator_mod);
// Gtk callback for the "expose-event" signal.
static gboolean OnToolbarExpose(GtkWidget* widget, GdkEventExpose* e,
@@ -107,15 +104,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Gtk callback to intercept mouse clicks to the menu buttons.
static gboolean OnMenuButtonPressEvent(GtkWidget* button,
- GdkEvent *event,
+ GdkEventButton* event,
BrowserToolbarGtk* toolbar);
- // Displays the page menu.
- void RunPageMenu(GdkEvent* button_press_event);
-
- // Displays the app menu.
- void RunAppMenu(GdkEvent* button_press_event);
-
// Construct the Home button.
CustomDrawButton* MakeHomeButton();
@@ -136,7 +127,7 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
GtkAccelGroup* accel_group_;
// All the buttons in the toolbar.
- scoped_ptr<CustomDrawButton> back_, forward_;
+ scoped_ptr<BackForwardButtonGtk> back_, forward_;
scoped_ptr<CustomDrawButton> reload_;
scoped_ptr<CustomDrawButton> home_; // May be NULL.
scoped_ptr<ToolbarStarToggleGtk> star_;
@@ -155,36 +146,7 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Controls whether or not a home button should be shown on the toolbar.
BooleanPrefMember show_home_button_;
- // Back/Forward menus ------------------------------------------------------
- // When clicked, these buttons will navigate forward or backward. When
- // pressed and held, they show a dropdown menu of recent web sites.
- // TODO(port): to match windows, we need to immediately show the back/forward
- // menu when the user starts dragging the mouse.
-
- // Builds a toolbar button for the back or forward dropdown menus.
- CustomDrawButton* BuildBackForwardButton(
- int normal_id,
- int active_id,
- int highlight_id,
- int depressed_id,
- const std::string& localized_tooltip);
-
- // Starts a timer to show the dropdown menu.
- static gboolean OnBackForwardPressEvent(GtkWidget* button,
- GdkEventButton* event,
- BrowserToolbarGtk* toolbar);
-
- // Shows the dropdown menu when the timer fires. |button_type| refers to the
- // click that originated the button press event.
- void ShowBackForwardMenu(GtkWidget* button, gint button_type);
-
- // The back/forward menu gets reset every time it is shown.
- scoped_ptr<MenuGtk> back_forward_menu_;
-
- scoped_ptr<BackForwardMenuModelGtk> back_menu_model_;
- scoped_ptr<BackForwardMenuModelGtk> forward_menu_model_;
-
- ScopedRunnableMethodFactory<BrowserToolbarGtk> show_menu_factory_;
+ DISALLOW_COPY_AND_ASSIGN(BrowserToolbarGtk);
};
#endif // CHROME_BROWSER_GTK_BROWSER_TOOLBAR_GTK_H_
diff --git a/chrome/browser/gtk/custom_button.cc b/chrome/browser/gtk/custom_button.cc
index ed1f0b3..e438016 100644
--- a/chrome/browser/gtk/custom_button.cc
+++ b/chrome/browser/gtk/custom_button.cc
@@ -14,7 +14,8 @@ CustomDrawButtonBase::CustomDrawButtonBase(
int normal_id,
int active_id,
int highlight_id,
- int depressed_id) {
+ int depressed_id)
+ : paint_override_(-1) {
// Load the button images from the resource bundle.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
pixbufs_[GTK_STATE_NORMAL] = normal_id ? rb.GetPixbufNamed(normal_id) : NULL;
@@ -30,11 +31,12 @@ CustomDrawButtonBase::~CustomDrawButtonBase() {
}
gboolean CustomDrawButtonBase::OnExpose(GtkWidget* widget, GdkEventExpose* e) {
- GdkPixbuf* pixbuf = pixbufs(GTK_WIDGET_STATE(widget));
+ GdkPixbuf* pixbuf = pixbufs_[paint_override_ >= 0 ?
+ paint_override_ : GTK_WIDGET_STATE(widget)];
// Fall back to the default image if we don't have one for this state.
if (!pixbuf)
- pixbuf = pixbufs(GTK_STATE_NORMAL);
+ pixbuf = pixbufs_[GTK_STATE_NORMAL];
if (!pixbuf)
return FALSE;
@@ -73,6 +75,16 @@ CustomDrawButton::~CustomDrawButton() {
widget_.Destroy();
}
+void CustomDrawButton::SetPaintOverride(GtkStateType state) {
+ button_base_.set_paint_override(state);
+ gtk_widget_queue_draw(widget_.get());
+}
+
+void CustomDrawButton::UnsetPaintOverride() {
+ button_base_.set_paint_override(-1);
+ gtk_widget_queue_draw(widget_.get());
+}
+
// static
gboolean CustomDrawButton::OnExpose(GtkWidget* widget,
GdkEventExpose* e,
diff --git a/chrome/browser/gtk/custom_button.h b/chrome/browser/gtk/custom_button.h
index f5e21ce..92f9d72 100644
--- a/chrome/browser/gtk/custom_button.h
+++ b/chrome/browser/gtk/custom_button.h
@@ -33,11 +33,16 @@ class CustomDrawButtonBase {
gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e);
+ void set_paint_override(int state) { paint_override_ = state; }
+
private:
// We store one GdkPixbuf* for each possible state of the button;
// INSENSITIVE is the last available state;
GdkPixbuf* pixbufs_[GTK_STATE_INSENSITIVE + 1];
+ // If non-negative, the state to paint the button.
+ int paint_override_;
+
DISALLOW_COPY_AND_ASSIGN(CustomDrawButtonBase);
};
@@ -65,6 +70,13 @@ class CustomDrawButton {
int width() const { return widget_.get()->allocation.width; }
+ // Set the state to draw. We will paint the widget as if it were in this
+ // state.
+ void SetPaintOverride(GtkStateType state);
+
+ // Resume normal drawing of the widget's state.
+ void UnsetPaintOverride();
+
// This is a convenience function for creating a widget that closes
// a bar (find bar, download shelf, info bars). The button will be packed in
// |hbox|.
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 99874f3..9287372 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -874,6 +874,8 @@
'browser/google_util.h',
'browser/gtk/about_chrome_dialog.cc',
'browser/gtk/about_chrome_dialog.h',
+ 'browser/gtk/back_forward_button_gtk.cc',
+ 'browser/gtk/back_forward_button_gtk.h',
'browser/gtk/back_forward_menu_model_gtk.cc',
'browser/gtk/back_forward_menu_model_gtk.h',
'browser/gtk/bookmark_bar_gtk.cc',