diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-26 20:18:21 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-26 20:18:21 +0000 |
commit | 6463cb2a117dcd866a12becb513cfdba935c16e5 (patch) | |
tree | 929c60acd2a4bd78e9b6f4ccbbf0c3bfa4bcf495 | |
parent | 32d0ef5d82ef2e972635245107825e776072dc82 (diff) | |
download | chromium_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.cc | 121 | ||||
-rw-r--r-- | chrome/browser/gtk/back_forward_button_gtk.h | 71 | ||||
-rw-r--r-- | chrome/browser/gtk/back_forward_menu_model_gtk.cc | 15 | ||||
-rw-r--r-- | chrome/browser/gtk/back_forward_menu_model_gtk.h | 8 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.cc | 154 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.h | 48 | ||||
-rw-r--r-- | chrome/browser/gtk/custom_button.cc | 18 | ||||
-rw-r--r-- | chrome/browser/gtk/custom_button.h | 12 | ||||
-rw-r--r-- | chrome/chrome.gyp | 2 |
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', |