summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-04 00:12:48 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-04 00:12:48 +0000
commit27538b19124450f43392a965bb080817469f643c (patch)
tree5e5475a44d4b7051812f6d1cfe65c5b36c8b3846 /chrome/browser/gtk
parent2c1f5f7d9cc0b21a08fa876dc2bcc5f28b5428c6 (diff)
downloadchromium_src-27538b19124450f43392a965bb080817469f643c.zip
chromium_src-27538b19124450f43392a965bb080817469f643c.tar.gz
chromium_src-27538b19124450f43392a965bb080817469f643c.tar.bz2
[GTK] More m6 toolbar fixes.
- make wrench menu a custom button rather than gtk_chrome_button (changes appearance slightly) - correct sizing/spacing of wrench menu - new overflow chevron graphic (also a CustomDrawButton converted from a gtk_chrome_button) - fix things I broke when I was hastily fixing the build earlier BUG=50682 TEST=visual Review URL: http://codereview.chromium.org/3053038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54850 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.cc145
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.h25
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc101
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h18
-rw-r--r--chrome/browser/gtk/custom_button.cc82
-rw-r--r--chrome/browser/gtk/custom_button.h37
-rw-r--r--chrome/browser/gtk/owned_widget_gtk.cc3
7 files changed, 231 insertions, 180 deletions
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
index 198b0e1..3edb179 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
@@ -33,20 +33,19 @@
#include "gfx/canvas_skia_paint.h"
#include "gfx/gtk_util.h"
#include "grit/app_resources.h"
+#include "grit/theme_resources.h"
namespace {
-// The size of each button on the toolbar.
-const int kButtonSize = 29;
+// The width of the browser action buttons.
+const int kButtonWidth = 27;
-// The padding between browser action buttons. Visually, the actual number of
-// "empty" (non-drawing) pixels is this value + 2 when adjacent browser icons
-// use their maximum allowed size.
-const int kButtonPadding = 1;
+// The padding between browser action buttons.
+const int kButtonPadding = 4;
// The padding to the right of the browser action buttons (between the buttons
-// and the separator, or chevron if it's showing).
-const int kPaddingToRightOfButtons = 5;
+// and chevron if they are both showing).
+const int kButtonChevronPadding = 2;
// The padding to the left, top and bottom of the browser actions toolbar
// separator.
@@ -69,7 +68,7 @@ GtkTargetEntry GetDragTargetEntry() {
// The minimum width in pixels of the button hbox if |icon_count| icons are
// showing.
gint WidthForIconCount(gint icon_count) {
- return std::max((kButtonSize + kButtonPadding) * icon_count - kButtonPadding,
+ return std::max((kButtonWidth + kButtonPadding) * icon_count - kButtonPadding,
0);
}
@@ -83,20 +82,24 @@ class BrowserActionButton : public NotificationObserver,
public MenuGtk::Delegate {
public:
BrowserActionButton(BrowserActionsToolbarGtk* toolbar,
- Extension* extension)
+ Extension* extension,
+ GtkThemeProvider* theme_provider)
: toolbar_(toolbar),
extension_(extension),
image_(NULL),
tracker_(this),
tab_specific_icon_(NULL),
default_icon_(NULL) {
- button_.Own(
- GtkThemeProvider::GetFrom(toolbar->profile_)->BuildChromeButton());
+ button_.reset(new CustomDrawButton(
+ theme_provider,
+ IDR_BROWSER_ACTION,
+ IDR_BROWSER_ACTION_P,
+ IDR_BROWSER_ACTION_H,
+ 0,
+ NULL));
DCHECK(extension_->browser_action());
- gtk_widget_set_size_request(button_.get(), kButtonSize, kButtonSize);
-
UpdateState();
// The Browser Action API does not allow the default icon path to be
@@ -109,13 +112,13 @@ class BrowserActionButton : public NotificationObserver,
ImageLoadingTracker::DONT_CACHE);
}
- signals_.Connect(button_.get(), "button-press-event",
+ signals_.Connect(button_->widget(), "button-press-event",
G_CALLBACK(OnButtonPress), this);
- signals_.Connect(button_.get(), "clicked",
+ signals_.Connect(button_->widget(), "clicked",
G_CALLBACK(OnClicked), this);
- signals_.ConnectAfter(button_.get(), "expose-event",
+ signals_.ConnectAfter(button_->widget(), "expose-event",
G_CALLBACK(OnExposeEvent), this);
- signals_.Connect(button_.get(), "drag-begin",
+ signals_.Connect(button_->widget(), "drag-begin",
G_CALLBACK(&OnDragBegin), this);
registrar_.Add(this, NotificationType::EXTENSION_BROWSER_ACTION_UPDATED,
@@ -128,11 +131,9 @@ class BrowserActionButton : public NotificationObserver,
if (default_icon_)
g_object_unref(default_icon_);
-
- button_.Destroy();
}
- GtkWidget* widget() { return button_.get(); }
+ GtkWidget* widget() { return button_->widget(); }
Extension* extension() { return extension_; }
@@ -164,9 +165,9 @@ class BrowserActionButton : public NotificationObserver,
std::string tooltip = extension_->browser_action()->GetTitle(tab_id);
if (tooltip.empty())
- gtk_widget_set_has_tooltip(button_.get(), FALSE);
+ gtk_widget_set_has_tooltip(button_->widget(), FALSE);
else
- gtk_widget_set_tooltip_text(button_.get(), tooltip.c_str());
+ gtk_widget_set_tooltip_text(button_->widget(), tooltip.c_str());
SkBitmap image = extension_->browser_action()->GetIcon(tab_id);
if (!image.isNull()) {
@@ -178,7 +179,7 @@ class BrowserActionButton : public NotificationObserver,
} else if (default_icon_) {
SetImage(default_icon_);
}
- gtk_widget_queue_draw(button_.get());
+ gtk_widget_queue_draw(button_->widget());
}
SkBitmap GetIcon() {
@@ -202,7 +203,7 @@ class BrowserActionButton : public NotificationObserver,
private:
// MenuGtk::Delegate implementation.
virtual void StoppedShowing() {
- gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(button_.get()));
+ button_->UnsetPaintOverride();
// If the context menu was showing for the overflow menu, re-assert the
// grab that was shadowed.
@@ -246,7 +247,7 @@ class BrowserActionButton : public NotificationObserver,
void SetImage(GdkPixbuf* image) {
if (!image_) {
image_ = gtk_image_new_from_pixbuf(image);
- gtk_button_set_image(GTK_BUTTON(button_.get()), image_);
+ gtk_button_set_image(GTK_BUTTON(button_->widget()), image_);
} else {
gtk_image_set_from_pixbuf(GTK_IMAGE(image_), image);
}
@@ -258,8 +259,7 @@ class BrowserActionButton : public NotificationObserver,
if (event->button.button != 3)
return FALSE;
- gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(action->button_.get()),
- GTK_STATE_PRELIGHT);
+ action->button_->SetPaintOverride(GTK_STATE_ACTIVE);
action->GetContextMenu()->Popup(widget, event);
return TRUE;
@@ -306,8 +306,8 @@ class BrowserActionButton : public NotificationObserver,
// The extension that contains this browser action.
Extension* extension_;
- // The gtk widget for this browser action.
- OwnedWidgetGtk button_;
+ // The button for this browser action.
+ scoped_ptr<CustomDrawButton> button_;
// 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
@@ -346,8 +346,6 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
model_(NULL),
hbox_(gtk_hbox_new(FALSE, 0)),
button_hbox_(gtk_chrome_shrinkable_hbox_new(TRUE, FALSE, kButtonPadding)),
- overflow_button_(browser->profile()),
- separator_(theme_provider_->CreateToolbarSeparator()),
drag_button_(NULL),
drop_index_(-1),
resize_animation_(this),
@@ -359,6 +357,14 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
if (!extension_service)
return;
+ overflow_button_.reset(new CustomDrawButton(
+ theme_provider_,
+ 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_UNSET_FLAGS(gripper, GTK_CAN_FOCUS);
@@ -375,19 +381,31 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
G_CALLBACK(OnGripperButtonReleaseThunk), this);
signals_.Connect(gripper, "button-press-event",
G_CALLBACK(OnGripperButtonPressThunk), this);
- signals_.Connect(overflow_button_.widget(), "button-press-event",
+ signals_.Connect(overflow_button_->widget(), "button-press-event",
G_CALLBACK(OnOverflowButtonPressThunk), this);
- overflow_spacer_ = gtk_alignment_new(0, 0, 1, 1);
- gtk_alignment_set_padding(GTK_ALIGNMENT(overflow_spacer_), 0, 0,
- kPaddingToRightOfButtons, 0);
- gtk_container_add(GTK_CONTAINER(overflow_spacer_), overflow_button_.widget());
- gtk_widget_show(overflow_button_.widget());
+ // |overflow_alignment| adds padding to the right of the browser action
+ // buttons, but only appears when the overflow menu is showing.
+ overflow_alignment_ = gtk_alignment_new(0, 0, 1, 1);
+ gtk_container_add(GTK_CONTAINER(overflow_alignment_),
+ overflow_button_->widget());
+
+ // |overflow_area_| holds the overflow chevron and the separator, which
+ // is only shown in GTK+ theme mode.
+ overflow_area_ = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(overflow_area_), overflow_alignment_,
+ FALSE, FALSE, 0);
+
+ separator_ = gtk_vseparator_new();
+ gtk_box_pack_start(GTK_BOX(overflow_area_), separator_,
+ FALSE, FALSE, 0);
+ gtk_widget_set_no_show_all(separator_, TRUE);
+
+ gtk_widget_show_all(overflow_area_);
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_spacer_, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox_.get()), separator_, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox_.get()), overflow_area_, FALSE, FALSE, 0);
model_ = extension_service->toolbar_model();
model_->AddObserver(this);
@@ -404,6 +422,11 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
G_CALLBACK(OnHierarchyChangedThunk), this);
ViewIDUtil::SetID(button_hbox_.get(), VIEW_ID_BROWSER_ACTION_TOOLBAR);
+
+ registrar_.Add(this,
+ NotificationType::BROWSER_THEME_CHANGED,
+ NotificationService::AllSources());
+ theme_provider_->InitThemesFor(this);
}
BrowserActionsToolbarGtk::~BrowserActionsToolbarGtk() {
@@ -428,6 +451,16 @@ void BrowserActionsToolbarGtk::Update() {
}
}
+void BrowserActionsToolbarGtk::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(NotificationType::BROWSER_THEME_CHANGED == type);
+ if (theme_provider_->UseGtkTheme())
+ gtk_widget_show(separator_);
+ else
+ gtk_widget_hide(separator_);
+}
+
void BrowserActionsToolbarGtk::SetupDrags() {
GtkTargetEntry drag_target = GetDragTargetEntry();
gtk_drag_dest_set(button_hbox_.get(), GTK_DEST_DEFAULT_DROP, &drag_target, 1,
@@ -463,7 +496,7 @@ void BrowserActionsToolbarGtk::CreateButtonForExtension(Extension* extension,
RemoveButtonForExtension(extension);
linked_ptr<BrowserActionButton> button(
- new BrowserActionButton(this, extension));
+ new BrowserActionButton(this, extension, theme_provider_));
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);
@@ -544,7 +577,7 @@ void BrowserActionsToolbarGtk::BrowserActionAdded(Extension* extension,
return;
// Animate the addition if we are showing all browser action buttons.
- if (!GTK_WIDGET_VISIBLE(overflow_spacer_)) {
+ if (!GTK_WIDGET_VISIBLE(overflow_area_)) {
AnimateToShowNIcons(button_count());
model_->SetVisibleIconCount(button_count());
}
@@ -560,7 +593,7 @@ void BrowserActionsToolbarGtk::BrowserActionRemoved(Extension* extension) {
RemoveButtonForExtension(extension);
- if (!GTK_WIDGET_VISIBLE(overflow_spacer_)) {
+ if (!GTK_WIDGET_VISIBLE(overflow_area_)) {
AnimateToShowNIcons(button_count());
model_->SetVisibleIconCount(button_count());
}
@@ -616,7 +649,7 @@ void BrowserActionsToolbarGtk::ExecuteCommand(int command_id) {
if (browser_action->HasPopup(tab_id)) {
ExtensionPopupGtk::Show(
browser_action->GetPopupUrl(tab_id), browser(),
- overflow_button_.widget(),
+ overflow_button_->widget(),
false);
} else {
ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
@@ -625,8 +658,7 @@ void BrowserActionsToolbarGtk::ExecuteCommand(int command_id) {
}
void BrowserActionsToolbarGtk::StoppedShowing() {
- gtk_chrome_button_unset_paint_state(
- GTK_CHROME_BUTTON(overflow_button_.widget()));
+ overflow_button_->UnsetPaintOverride();
}
void BrowserActionsToolbarGtk::DragStarted(BrowserActionButton* button,
@@ -651,15 +683,21 @@ 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_), 0, 0, 0, 0);
+ } else {
+ gtk_alignment_set_padding(GTK_ALIGNMENT(overflow_alignment_), 0, 0,
+ kButtonChevronPadding, 0);
+ }
if (button_count() > showing_icon_count) {
- if (!GTK_WIDGET_VISIBLE(overflow_spacer_)) {
+ if (!GTK_WIDGET_VISIBLE(overflow_area_)) {
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(overflow_spacer_, &req);
+ gtk_widget_size_request(overflow_button_->widget(), &req);
gint overflow_width = req.width;
gtk_widget_size_request(button_hbox_.get(), &req);
gint button_hbox_width = req.width;
@@ -667,10 +705,10 @@ void BrowserActionsToolbarGtk::UpdateChevronVisibility() {
gtk_widget_set_size_request(button_hbox_.get(), button_hbox_width, -1);
}
- gtk_widget_show(overflow_spacer_);
+ gtk_widget_show(overflow_area_);
}
} else {
- gtk_widget_hide(overflow_spacer_);
+ gtk_widget_hide(overflow_area_);
}
}
@@ -683,7 +721,7 @@ gboolean BrowserActionsToolbarGtk::OnDragMotion(GtkWidget* widget,
if (base::i18n::IsRTL())
x = widget->allocation.width - x;
- drop_index_ = x < kButtonSize ? 0 : x / (kButtonSize + kButtonPadding);
+ 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
@@ -831,9 +869,8 @@ gboolean BrowserActionsToolbarGtk::OnOverflowButtonPress(
signals_.Connect(overflow_menu_->widget(), "button-press-event",
G_CALLBACK(OnOverflowMenuButtonPressThunk), this);
- gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(overflow),
- GTK_STATE_ACTIVE);
- overflow_menu_->PopupAsFromKeyEvent(overflow);
+ overflow_button_->SetPaintOverride(GTK_STATE_ACTIVE);
+ overflow_menu_->PopupAsFromKeyEvent(overflow_button_->widget());
return FALSE;
}
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.h b/chrome/browser/gtk/browser_actions_toolbar_gtk.h
index 9d2e44d..672e9c3 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -16,6 +16,7 @@
#include "base/linked_ptr.h"
#include "base/task.h"
#include "chrome/browser/extensions/extension_toolbar_model.h"
+#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/menu_gtk.h"
#include "chrome/browser/gtk/overflow_button.h"
#include "chrome/browser/gtk/owned_widget_gtk.h"
@@ -34,7 +35,8 @@ typedef struct _GtkWidget GtkWidget;
class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer,
public AnimationDelegate,
public MenuGtk::Delegate,
- public menus::SimpleMenuModel::Delegate {
+ public menus::SimpleMenuModel::Delegate,
+ public NotificationObserver {
public:
explicit BrowserActionsToolbarGtk(Browser* browser);
virtual ~BrowserActionsToolbarGtk();
@@ -56,6 +58,11 @@ class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer,
// Update the display of all buttons.
void Update();
+ // NotificationObserver implementation.
+ void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
private:
friend class BrowserActionButton;
@@ -169,14 +176,16 @@ class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer,
// Contains the browser action buttons.
OwnedWidgetGtk button_hbox_;
- OverflowButton overflow_button_;
+ // The overflow button for chrome theme mode.
+ scoped_ptr<CustomDrawButton> overflow_button_;
+ // The separator just next to the overflow button. Only shown in GTK+ theme
+ // mode. In Chrome theme mode, the overflow button has a separator built in.
+ GtkWidget* separator_;
scoped_ptr<MenuGtk> overflow_menu_;
scoped_ptr<menus::SimpleMenuModel> overflow_menu_model_;
+ GtkWidget* overflow_area_;
// A widget for adding extra padding to the left of the overflow button.
- GtkWidget* overflow_spacer_;
-
- // The vertical separator between the overflow button and the page/app menus.
- GtkWidget* separator_;
+ GtkWidget* overflow_alignment_;
// The button that is currently being dragged, or NULL.
BrowserActionButton* drag_button_;
@@ -200,6 +209,8 @@ class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer,
GtkSignalRegistrar signals_;
+ NotificationRegistrar registrar_;
+
ScopedRunnableMethodFactory<BrowserActionsToolbarGtk> method_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserActionsToolbarGtk);
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index b56a65b..d89e747 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -124,9 +124,8 @@ BrowserToolbarGtk::~BrowserToolbarGtk() {
offscreen_entry_.Destroy();
- app_menu_.reset();
- app_menu_button_.Destroy();
- app_menu_image_.Destroy();
+ wrench_menu_.reset();
+ wrench_menu_image_.Destroy();
}
void BrowserToolbarGtk::Init(Profile* profile,
@@ -175,8 +174,7 @@ void BrowserToolbarGtk::Init(Profile* profile,
0);
home_.reset(new CustomDrawButton(GtkThemeProvider::GetFrom(profile_),
- IDR_HOME, IDR_HOME_P, IDR_HOME_H, 0, GTK_STOCK_HOME,
- GTK_ICON_SIZE_SMALL_TOOLBAR));
+ IDR_HOME, IDR_HOME_P, IDR_HOME_H, 0, NULL));
gtk_widget_set_tooltip_text(home_->widget(),
l10n_util::GetStringUTF8(IDS_TOOLTIP_HOME).c_str());
g_signal_connect(home_->widget(), "clicked",
@@ -198,35 +196,34 @@ void BrowserToolbarGtk::Init(Profile* profile,
gtk_box_pack_start(GTK_BOX(toolbar_), location_hbox_, TRUE, TRUE,
ShouldOnlyShowLocation() ? 1 : 0);
- toolbar_right_ = gtk_hbox_new(FALSE, 0);
-
if (!ShouldOnlyShowLocation()) {
actions_toolbar_.reset(new BrowserActionsToolbarGtk(browser_));
- gtk_box_pack_start(GTK_BOX(toolbar_right_), actions_toolbar_->widget(),
+ gtk_box_pack_start(GTK_BOX(toolbar_), actions_toolbar_->widget(),
FALSE, FALSE, 0);
}
- // We need another hbox for the menu buttons so we can place them together,
- // but still have some padding to their collective left/right.
- GtkWidget* menus_hbox = gtk_hbox_new(FALSE, 0);
- GtkWidget* chrome_menu = BuildToolbarMenuButton(
+ wrench_menu_button_.reset(new CustomDrawButton(
+ GtkThemeProvider::GetFrom(profile_),
+ IDR_TOOLS, IDR_TOOLS_P, IDR_TOOLS_H, 0,
+ gtk_image_new_from_pixbuf(
+ theme_provider_->GetRTLEnabledPixbufNamed(IDR_TOOLS))));
+ GtkWidget* wrench_button = wrench_menu_button_->widget();
+
+ gtk_widget_set_tooltip_text(
+ wrench_button,
l10n_util::GetStringFUTF8(IDS_APPMENU_TOOLTIP,
- WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))),
- &app_menu_button_);
- app_menu_image_.Own(gtk_image_new_from_pixbuf(
- theme_provider_->GetRTLEnabledPixbufNamed(IDR_TOOLS)));
- gtk_container_add(GTK_CONTAINER(chrome_menu), app_menu_image_.get());
- g_signal_connect_after(app_menu_image_.get(), "expose-event",
- G_CALLBACK(OnAppMenuImageExposeThunk), this);
-
- app_menu_.reset(new MenuGtk(this, &wrench_menu_model_));
- gtk_box_pack_start(GTK_BOX(menus_hbox), chrome_menu, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(toolbar_right_), menus_hbox, FALSE, FALSE,
- kToolbarWidgetSpacing);
- g_signal_connect(app_menu_->widget(), "show",
- G_CALLBACK(OnAppMenuShowThunk), this);
+ WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))).c_str());
+ g_signal_connect(wrench_button, "button-press-event",
+ G_CALLBACK(OnMenuButtonPressEventThunk), this);
+ GTK_WIDGET_UNSET_FLAGS(wrench_button, GTK_CAN_FOCUS);
+ g_signal_connect_after(wrench_button, "expose-event",
+ G_CALLBACK(OnWrenchMenuImageExposeThunk), this);
+ gtk_box_pack_start(GTK_BOX(toolbar_), wrench_menu_button_->widget(),
+ FALSE, FALSE, 4);
- gtk_box_pack_start(GTK_BOX(toolbar_), toolbar_right_, FALSE, FALSE, 0);
+ wrench_menu_.reset(new MenuGtk(this, &wrench_menu_model_));
+ g_signal_connect(wrench_menu_->widget(), "show",
+ G_CALLBACK(OnWrenchMenuShowThunk), this);
if (ShouldOnlyShowLocation()) {
gtk_widget_show(event_box_);
@@ -257,7 +254,7 @@ void BrowserToolbarGtk::SetViewIDs() {
ViewIDUtil::SetID(reload_->widget(), VIEW_ID_RELOAD_BUTTON);
ViewIDUtil::SetID(home_->widget(), VIEW_ID_HOME_BUTTON);
ViewIDUtil::SetID(location_bar_->widget(), VIEW_ID_LOCATION_BAR);
- ViewIDUtil::SetID(app_menu_button_.get(), VIEW_ID_APP_MENU);
+ ViewIDUtil::SetID(wrench_menu_button_->widget(), VIEW_ID_APP_MENU);
}
void BrowserToolbarGtk::Show() {
@@ -281,10 +278,9 @@ void BrowserToolbarGtk::UpdateForBookmarkBarVisibility(
}
void BrowserToolbarGtk::ShowAppMenu() {
- app_menu_->Cancel();
- gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(app_menu_button_.get()),
- GTK_STATE_ACTIVE);
- app_menu_->PopupAsFromKeyEvent(app_menu_button_.get());
+ wrench_menu_->Cancel();
+ wrench_menu_button_->SetPaintOverride(GTK_STATE_ACTIVE);
+ wrench_menu_->PopupAsFromKeyEvent(wrench_menu_button_->widget());
}
// CommandUpdater::CommandObserver ---------------------------------------------
@@ -321,9 +317,8 @@ void BrowserToolbarGtk::StoppedShowing() {
// Without these calls, the hover state can get stuck since the leave-notify
// event is not sent when clicking a button brings up the menu.
gtk_chrome_button_set_hover_state(
- GTK_CHROME_BUTTON(app_menu_button_.get()), 0.0);
- gtk_chrome_button_unset_paint_state(
- GTK_CHROME_BUTTON(app_menu_button_.get()));
+ GTK_CHROME_BUTTON(wrench_menu_button_->widget()), 0.0);
+ wrench_menu_button_->UnsetPaintOverride();
}
GtkIconSet* BrowserToolbarGtk::GetIconSetForId(int idr) {
@@ -380,11 +375,7 @@ void BrowserToolbarGtk::Observe(NotificationType type,
bool use_gtk = theme_provider_->UseGtkTheme();
int border = use_gtk ? 0 : 2;
gtk_container_set_border_width(
- GTK_CONTAINER(app_menu_button_.get()), border);
-
- // Update the menu button image.
- gtk_image_set_from_pixbuf(GTK_IMAGE(app_menu_image_.get()),
- theme_provider_->GetRTLEnabledPixbufNamed(IDR_TOOLS));
+ GTK_CONTAINER(wrench_menu_button_->widget()), border);
// Force the height of the toolbar so we get the right amount of padding
// above and below the location bar. We always force the size of the hboxes
@@ -394,7 +385,6 @@ void BrowserToolbarGtk::Observe(NotificationType type,
int toolbar_height = ShouldOnlyShowLocation() ?
kToolbarHeightLocationBarOnly : kToolbarHeight;
gtk_widget_set_size_request(toolbar_left_, -1, toolbar_height);
- gtk_widget_set_size_request(toolbar_right_, -1, toolbar_height);
gtk_widget_set_size_request(location_hbox_, -1,
use_gtk ? -1 : toolbar_height);
@@ -431,20 +421,6 @@ void BrowserToolbarGtk::UpdateTabContents(TabContents* contents,
// BrowserToolbarGtk, private --------------------------------------------------
-GtkWidget* BrowserToolbarGtk::BuildToolbarMenuButton(
- const std::string& localized_tooltip,
- OwnedWidgetGtk* owner) {
- GtkWidget* button = theme_provider_->BuildChromeButton();
- owner->Own(button);
-
- gtk_widget_set_tooltip_text(button, localized_tooltip.c_str());
- g_signal_connect(button, "button-press-event",
- G_CALLBACK(OnMenuButtonPressEventThunk), this);
- GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS);
-
- return button;
-}
-
void BrowserToolbarGtk::SetUpDragForHomeButton(bool enable) {
if (enable) {
gtk_drag_dest_set(home_->widget(), GTK_DEST_DEFAULT_ALL,
@@ -618,9 +594,8 @@ gboolean BrowserToolbarGtk::OnMenuButtonPressEvent(GtkWidget* button,
if (event->button != 1)
return FALSE;
- gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(button),
- GTK_STATE_ACTIVE);
- app_menu_->Popup(button, reinterpret_cast<GdkEvent*>(event));
+ wrench_menu_button_->SetPaintOverride(GTK_STATE_ACTIVE);
+ wrench_menu_->Popup(button, reinterpret_cast<GdkEvent*>(event));
return TRUE;
}
@@ -677,13 +652,13 @@ bool BrowserToolbarGtk::ShouldOnlyShowLocation() const {
void BrowserToolbarGtk::AnimationEnded(const Animation* animation) {
DCHECK_EQ(animation, &upgrade_reminder_animation_);
- gtk_widget_queue_draw(app_menu_image_.get());
+ gtk_widget_queue_draw(wrench_menu_image_.get());
}
void BrowserToolbarGtk::AnimationProgressed(const Animation* animation) {
DCHECK_EQ(animation, &upgrade_reminder_animation_);
if (UpgradeAnimationIsFaded())
- gtk_widget_queue_draw(app_menu_image_.get());
+ gtk_widget_queue_draw(wrench_menu_image_.get());
}
void BrowserToolbarGtk::AnimationCanceled(const Animation* animation) {
@@ -694,15 +669,15 @@ void BrowserToolbarGtk::ActiveWindowChanged(GdkWindow* active_window) {
MaybeShowUpgradeReminder();
}
-void BrowserToolbarGtk::OnAppMenuShow(GtkWidget* sender) {
+void BrowserToolbarGtk::OnWrenchMenuShow(GtkWidget* sender) {
if (upgrade_reminder_animation_.is_animating()) {
upgrade_reminder_canceled_ = true;
MaybeShowUpgradeReminder();
}
}
-gboolean BrowserToolbarGtk::OnAppMenuImageExpose(GtkWidget* sender,
- GdkEventExpose* expose) {
+gboolean BrowserToolbarGtk::OnWrenchMenuImageExpose(GtkWidget* sender,
+ GdkEventExpose* expose) {
if (!Singleton<UpgradeDetector>::get()->notify_upgrade())
return FALSE;
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h
index 29dd47b..b0ade49 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_toolbar_gtk.h
@@ -73,7 +73,7 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
ReloadButtonGtk* GetReloadButton() { return reload_.get(); }
- GtkWidget* GetAppMenuButton() { return app_menu_button_.get(); }
+ GtkWidget* GetAppMenuButton() { return wrench_menu_button_->widget(); }
BrowserActionsToolbarGtk* GetBrowserActionsToolbar() {
return actions_toolbar_.get();
@@ -121,11 +121,6 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
virtual void ActiveWindowChanged(GdkWindow* active_window);
private:
- // Create a menu for the toolbar given the icon id and tooltip. Returns the
- // widget created.
- GtkWidget* BuildToolbarMenuButton(const std::string& localized_tooltip,
- OwnedWidgetGtk* owner);
-
// Connect/Disconnect signals for dragging a url onto the home button.
void SetUpDragForHomeButton(bool enable);
@@ -158,10 +153,10 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
guint, guint);
// Used to stop the upgrade notification animation.
- CHROMEGTK_CALLBACK_0(BrowserToolbarGtk, void, OnAppMenuShow);
+ CHROMEGTK_CALLBACK_0(BrowserToolbarGtk, void, OnWrenchMenuShow);
// Used to draw the upgrade notification badge.
- CHROMEGTK_CALLBACK_1(BrowserToolbarGtk, gboolean, OnAppMenuImageExpose,
+ CHROMEGTK_CALLBACK_1(BrowserToolbarGtk, gboolean, OnWrenchMenuImageExpose,
GdkEventExpose*);
// Updates preference-dependent state.
@@ -195,7 +190,6 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// set their minimum sizes independently of |location_hbox_| which needs to
// grow/shrink in GTK+ mode.
GtkWidget* toolbar_left_;
- GtkWidget* toolbar_right_;
// Contains all the widgets of the location bar.
GtkWidget* location_hbox_;
@@ -208,18 +202,18 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
scoped_ptr<CustomDrawButton> home_;
scoped_ptr<ReloadButtonGtk> reload_;
scoped_ptr<BrowserActionsToolbarGtk> actions_toolbar_;
- OwnedWidgetGtk app_menu_button_;
+ scoped_ptr<CustomDrawButton> wrench_menu_button_;
// Keep a pointer to the menu button image because we change it when the theme
// changes.
- OwnedWidgetGtk app_menu_image_;
+ OwnedWidgetGtk wrench_menu_image_;
// The model that contains the security level, text, icon to display...
ToolbarModel* model_;
GtkThemeProvider* theme_provider_;
- scoped_ptr<MenuGtk> app_menu_;
+ scoped_ptr<MenuGtk> wrench_menu_;
WrenchMenuModel wrench_menu_model_;
diff --git a/chrome/browser/gtk/custom_button.cc b/chrome/browser/gtk/custom_button.cc
index 603b6a7..08cd54d 100644
--- a/chrome/browser/gtk/custom_button.cc
+++ b/chrome/browser/gtk/custom_button.cc
@@ -117,6 +117,10 @@ gboolean CustomDrawButtonBase::OnExpose(GtkWidget* widget,
cairo_destroy(cairo_context);
+ GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget));
+ if (child)
+ gtk_container_propagate_expose(GTK_CONTAINER(widget), child, e);
+
return TRUE;
}
@@ -182,9 +186,9 @@ void CustomDrawHoverController::Init(GtkWidget* widget) {
DCHECK(widget_ == NULL);
widget_ = widget;
g_signal_connect(widget_, "enter-notify-event",
- G_CALLBACK(OnEnter), this);
+ G_CALLBACK(OnEnterThunk), this);
g_signal_connect(widget_, "leave-notify-event",
- G_CALLBACK(OnLeave), this);
+ G_CALLBACK(OnLeaveThunk), this);
}
void CustomDrawHoverController::AnimationProgressed(
@@ -192,25 +196,21 @@ void CustomDrawHoverController::AnimationProgressed(
gtk_widget_queue_draw(widget_);
}
-// static
gboolean CustomDrawHoverController::OnEnter(
GtkWidget* widget,
- GdkEventCrossing* event,
- CustomDrawHoverController* controller) {
- controller->slide_animation_.Show();
+ GdkEventCrossing* event) {
+ slide_animation_.Show();
return FALSE;
}
-// static
gboolean CustomDrawHoverController::OnLeave(
GtkWidget* widget,
- GdkEventCrossing* event,
- CustomDrawHoverController* controller) {
+ GdkEventCrossing* event) {
// When the user is holding a mouse button, we don't want to animate.
if (event->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK))
- controller->slide_animation_.Reset();
+ slide_animation_.Reset();
else
- controller->slide_animation_.Hide();
+ slide_animation_.Hide();
return FALSE;
}
@@ -221,9 +221,7 @@ CustomDrawButton::CustomDrawButton(int normal_id,
int hover_id,
int disabled_id)
: button_base_(NULL, normal_id, pressed_id, hover_id, disabled_id),
- theme_provider_(NULL),
- gtk_stock_name_(NULL),
- icon_size_(GTK_ICON_SIZE_INVALID) {
+ theme_provider_(NULL) {
Init();
// Initialize the theme stuff with no theme_provider.
@@ -239,9 +237,27 @@ CustomDrawButton::CustomDrawButton(GtkThemeProvider* theme_provider,
GtkIconSize stock_size)
: button_base_(theme_provider, normal_id, pressed_id, hover_id,
disabled_id),
- theme_provider_(theme_provider),
- gtk_stock_name_(stock_id),
- icon_size_(stock_size) {
+ theme_provider_(theme_provider) {
+ native_widget_.Own(gtk_image_new_from_stock(stock_id, stock_size));
+
+ Init();
+
+ theme_provider_->InitThemesFor(this);
+ registrar_.Add(this,
+ NotificationType::BROWSER_THEME_CHANGED,
+ NotificationService::AllSources());
+}
+
+CustomDrawButton::CustomDrawButton(GtkThemeProvider* theme_provider,
+ int normal_id,
+ int pressed_id,
+ int hover_id,
+ int disabled_id,
+ GtkWidget* native_widget)
+ : button_base_(theme_provider, normal_id, pressed_id, hover_id,
+ disabled_id),
+ native_widget_(native_widget),
+ theme_provider_(theme_provider) {
Init();
theme_provider_->InitThemesFor(this);
@@ -252,13 +268,14 @@ CustomDrawButton::CustomDrawButton(GtkThemeProvider* theme_provider,
CustomDrawButton::~CustomDrawButton() {
widget_.Destroy();
+ native_widget_.Destroy();
}
void CustomDrawButton::Init() {
widget_.Own(gtk_chrome_button_new());
GTK_WIDGET_UNSET_FLAGS(widget(), GTK_CAN_FOCUS);
g_signal_connect(widget(), "expose-event",
- G_CALLBACK(OnCustomExpose), this);
+ G_CALLBACK(OnCustomExposeThunk), this);
hover_controller_.Init(widget());
}
@@ -285,16 +302,14 @@ void CustomDrawButton::SetBackground(SkColor color,
button_base_.SetBackground(color, image, mask);
}
-// static
-gboolean CustomDrawButton::OnCustomExpose(GtkWidget* widget,
- GdkEventExpose* e,
- CustomDrawButton* button) {
- if (button->theme_provider_ && button->theme_provider_->UseGtkTheme()) {
+gboolean CustomDrawButton::OnCustomExpose(GtkWidget* sender,
+ GdkEventExpose* e) {
+ if (UseGtkTheme()) {
// Continue processing this expose event.
return FALSE;
} else {
- double hover_state = button->hover_controller_.GetCurrentValue();
- return button->button_base_.OnExpose(widget, e, hover_state);
+ double hover_state = hover_controller_.GetCurrentValue();
+ return button_base_.OnExpose(sender, e, hover_state);
}
}
@@ -307,15 +322,14 @@ CustomDrawButton* CustomDrawButton::CloseButton(
}
void CustomDrawButton::SetBrowserTheme() {
- bool use_gtk = theme_provider_ && theme_provider_->UseGtkTheme();
-
- if (use_gtk && gtk_stock_name_) {
- gtk_button_set_image(
- GTK_BUTTON(widget()),
- gtk_image_new_from_stock(gtk_stock_name_, icon_size_));
+ if (UseGtkTheme()) {
+ if (native_widget_.get())
+ gtk_button_set_image(GTK_BUTTON(widget()), native_widget_.get());
gtk_widget_set_size_request(widget(), -1, -1);
gtk_widget_set_app_paintable(widget(), FALSE);
} else {
+ if (native_widget_.get())
+ gtk_button_set_image(GTK_BUTTON(widget()), NULL);
gtk_widget_set_size_request(widget(), button_base_.Width(),
button_base_.Height());
@@ -323,5 +337,9 @@ void CustomDrawButton::SetBrowserTheme() {
}
gtk_chrome_button_set_use_gtk_rendering(
- GTK_CHROME_BUTTON(widget()), use_gtk);
+ GTK_CHROME_BUTTON(widget()), UseGtkTheme());
+}
+
+bool CustomDrawButton::UseGtkTheme() {
+ return theme_provider_ && theme_provider_->UseGtkTheme();
}
diff --git a/chrome/browser/gtk/custom_button.h b/chrome/browser/gtk/custom_button.h
index 5cb38cb..387a6e2 100644
--- a/chrome/browser/gtk/custom_button.h
+++ b/chrome/browser/gtk/custom_button.h
@@ -10,6 +10,7 @@
#include <string>
+#include "app/gtk_signal.h"
#include "app/slide_animation.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/gtk/owned_widget_gtk.h"
@@ -114,10 +115,10 @@ class CustomDrawHoverController : public AnimationDelegate {
private:
virtual void AnimationProgressed(const Animation* animation);
- static gboolean OnEnter(GtkWidget* widget, GdkEventCrossing* event,
- CustomDrawHoverController* controller);
- static gboolean OnLeave(GtkWidget* widget, GdkEventCrossing* event,
- CustomDrawHoverController* controller);
+ CHROMEGTK_CALLBACK_1(CustomDrawHoverController, gboolean, OnEnter,
+ GdkEventCrossing*);
+ CHROMEGTK_CALLBACK_1(CustomDrawHoverController, gboolean, OnLeave,
+ GdkEventCrossing*);
SlideAnimation slide_animation_;
GtkWidget* widget_;
@@ -135,7 +136,8 @@ class CustomDrawButton : public NotificationObserver {
int hover_id,
int disabled_id);
- // Same as above, but uses themed (and possibly tinted) images.
+ // Same as above, but uses themed (and possibly tinted) images. |stock_id| and
+ // |stock_size| are used for GTK+ theme mode.
CustomDrawButton(GtkThemeProvider* theme_provider,
int normal_id,
int pressed_id,
@@ -144,6 +146,15 @@ class CustomDrawButton : public NotificationObserver {
const char* stock_id,
GtkIconSize stock_size);
+ // As above, but uses an arbitrary GtkImage rather than a stock icon. This
+ // constructor takes ownership of |native_widget|.
+ CustomDrawButton(GtkThemeProvider* theme_provider,
+ int normal_id,
+ int pressed_id,
+ int hover_id,
+ int disabled_id,
+ GtkWidget* native_widget);
+
~CustomDrawButton();
void Init();
@@ -187,10 +198,13 @@ class CustomDrawButton : public NotificationObserver {
// Sets the button to themed or not.
void SetBrowserTheme();
+ // Whether to use the GTK+ theme. For this to be true, we have to be in GTK+
+ // theme mode and we must have a valid stock icon resource.
+ bool UseGtkTheme();
+
// Callback for custom button expose, used to draw the custom graphics.
- static gboolean OnCustomExpose(GtkWidget* widget,
- GdkEventExpose* e,
- CustomDrawButton* obj);
+ CHROMEGTK_CALLBACK_1(CustomDrawButton, gboolean, OnCustomExpose,
+ GdkEventExpose*);
// The actual button widget.
OwnedWidgetGtk widget_;
@@ -199,13 +213,12 @@ class CustomDrawButton : public NotificationObserver {
CustomDrawHoverController hover_controller_;
+ // The widget to use when we are displaying in GTK+ theme mode.
+ OwnedWidgetGtk native_widget_;
+
// Our theme provider.
GtkThemeProvider* theme_provider_;
- // The stock icon name and size.
- const char* gtk_stock_name_;
- GtkIconSize icon_size_;
-
// Used to listen for theme change notifications.
NotificationRegistrar registrar_;
diff --git a/chrome/browser/gtk/owned_widget_gtk.cc b/chrome/browser/gtk/owned_widget_gtk.cc
index db3bd30..2315371 100644
--- a/chrome/browser/gtk/owned_widget_gtk.cc
+++ b/chrome/browser/gtk/owned_widget_gtk.cc
@@ -13,6 +13,9 @@ OwnedWidgetGtk::~OwnedWidgetGtk() {
}
void OwnedWidgetGtk::Own(GtkWidget* widget) {
+ if (!widget)
+ return;
+
DCHECK(!widget_);
// We want to make sure that Own() was called properly, right after the
// widget was created. There should be a floating reference.