summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-16 23:09:39 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-16 23:09:39 +0000
commit42e8de911a526f8c86a7f5e5fc7dce82a647f6d0 (patch)
treecdc0bc11f5308d862b0023f6df6af58d731cc80a /chrome/browser/gtk
parent9d6ad02b8c83feeefa57d6131aa4b00cabb9e914 (diff)
downloadchromium_src-42e8de911a526f8c86a7f5e5fc7dce82a647f6d0.zip
chromium_src-42e8de911a526f8c86a7f5e5fc7dce82a647f6d0.tar.gz
chromium_src-42e8de911a526f8c86a7f5e5fc7dce82a647f6d0.tar.bz2
GTK Themes: Make the location bar area look native.
Replace the star and go buttons with a native looking thing, where we manually draw the theme's button image for the full omnibox area and then position the star/go buttons on top of that. Also adds stand in versions of star_noborder and starred_noborder until Glen can make real icons. http://crbug.com/16227 http://crbug.com/13967 http://crbug.com/16915 Review URL: http://codereview.chromium.org/149681 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20914 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc50
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h3
-rw-r--r--chrome/browser/gtk/go_button_gtk.cc68
-rw-r--r--chrome/browser/gtk/go_button_gtk.h16
-rw-r--r--chrome/browser/gtk/location_bar_view_gtk.cc30
-rw-r--r--chrome/browser/gtk/toolbar_star_toggle_gtk.cc62
-rw-r--r--chrome/browser/gtk/toolbar_star_toggle_gtk.h21
7 files changed, 214 insertions, 36 deletions
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index a608d96..3fd79b5 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -145,18 +145,20 @@ void BrowserToolbarGtk::Init(Profile* profile,
SetUpDragForHomeButton();
// Group the start, omnibox, and go button into an hbox.
- GtkWidget* omnibox_hbox_ = gtk_hbox_new(FALSE, 0);
+ GtkWidget* location_hbox = gtk_hbox_new(FALSE, 0);
star_.reset(BuildStarButton(l10n_util::GetStringUTF8(IDS_TOOLTIP_STAR)));
- gtk_box_pack_start(GTK_BOX(omnibox_hbox_), star_->widget(), FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(location_hbox), star_->widget(), FALSE, FALSE, 0);
location_bar_->Init();
- gtk_box_pack_start(GTK_BOX(omnibox_hbox_), location_bar_->widget(), TRUE,
+ gtk_box_pack_start(GTK_BOX(location_hbox), location_bar_->widget(), TRUE,
TRUE, 0);
go_.reset(new GoButtonGtk(location_bar_.get(), browser_));
- gtk_box_pack_start(GTK_BOX(omnibox_hbox_), go_->widget(), FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(location_hbox), go_->widget(), FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(toolbar_), omnibox_hbox_, TRUE, TRUE, 0);
+ g_signal_connect(location_hbox, "expose-event",
+ G_CALLBACK(OnLocationHboxExpose), this);
+ gtk_box_pack_start(GTK_BOX(toolbar_), location_hbox, TRUE, TRUE, 0);
// Group the menu buttons together in an hbox.
GtkWidget* menus_hbox_ = gtk_hbox_new(FALSE, 0);
@@ -441,6 +443,44 @@ gboolean BrowserToolbarGtk::OnToolbarExpose(GtkWidget* widget,
}
// static
+gboolean BrowserToolbarGtk::OnLocationHboxExpose(GtkWidget* location_hbox,
+ GdkEventExpose* e,
+ BrowserToolbarGtk* toolbar) {
+ if (toolbar->theme_provider_->UseGtkTheme()) {
+ // To get the proper look surrounding the location bar, we fake out the
+ // theme engine into drawing a button. We fake out GTK by constructing a
+ // box that's from the top left corner of the bookmark button to the bottom
+ // right of the go button and fill it with a button's box (or the opposite
+ // if in RTL mode).
+ GtkWidget* star = toolbar->star_->widget();
+ GtkWidget* left = NULL;
+ GtkWidget* right = NULL;
+ if (gtk_widget_get_direction(star) ==
+ GTK_TEXT_DIR_LTR) {
+ left = toolbar->star_->widget();
+ right = toolbar->go_->widget();
+ } else {
+ left = toolbar->go_->widget();
+ right = toolbar->star_->widget();
+ }
+
+ gint x = left->allocation.x;
+ gint y = left->allocation.y;
+ gint width = (right->allocation.x - left->allocation.x) +
+ right->allocation.width;
+ gint height = (right->allocation.y - left->allocation.y) +
+ right->allocation.height;
+
+ gtk_paint_box(star->style, location_hbox->window,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL,
+ location_hbox, "button",
+ x, y, width, height);
+ }
+
+ return FALSE;
+}
+
+// static
void BrowserToolbarGtk::OnButtonClick(GtkWidget* button,
BrowserToolbarGtk* toolbar) {
int tag = -1;
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h
index ab86f41..37a2c3f 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_toolbar_gtk.h
@@ -114,6 +114,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Gtk callback for the "expose-event" signal.
static gboolean OnToolbarExpose(GtkWidget* widget, GdkEventExpose* e,
BrowserToolbarGtk* toolbar);
+ static gboolean OnLocationHboxExpose(GtkWidget* omnibox_hbox,
+ GdkEventExpose* e,
+ BrowserToolbarGtk* toolbar);
// Gtk callback for the "clicked" signal.
static void OnButtonClick(GtkWidget* button, BrowserToolbarGtk* toolbar);
diff --git a/chrome/browser/gtk/go_button_gtk.cc b/chrome/browser/gtk/go_button_gtk.cc
index 6ea9369..34455de 100644
--- a/chrome/browser/gtk/go_button_gtk.cc
+++ b/chrome/browser/gtk/go_button_gtk.cc
@@ -9,9 +9,10 @@
#include "base/message_loop.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser.h"
-#include "chrome/browser/gtk/location_bar_view_gtk.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
+#include "chrome/browser/gtk/location_bar_view_gtk.h"
#include "chrome/browser/profile.h"
+#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -23,10 +24,10 @@ GoButtonGtk::GoButtonGtk(LocationBarViewGtk* location_bar, Browser* browser)
intended_mode_(MODE_GO),
visible_mode_(MODE_GO),
state_(BS_NORMAL),
- go_(browser ? GtkThemeProvider::GetFrom(browser->profile()) : NULL,
- IDR_GO, IDR_GO_P, IDR_GO_H, 0),
- stop_(browser ? GtkThemeProvider::GetFrom(browser->profile()) : NULL,
- IDR_STOP, IDR_STOP_P, IDR_STOP_H, 0),
+ theme_provider_(browser ?
+ GtkThemeProvider::GetFrom(browser->profile()) : NULL),
+ go_(theme_provider_, IDR_GO, IDR_GO_P, IDR_GO_H, 0),
+ stop_(theme_provider_, IDR_STOP, IDR_STOP_P, IDR_STOP_H, 0),
widget_(gtk_button_new()) {
gtk_widget_set_size_request(widget_.get(),
gdk_pixbuf_get_width(go_.pixbufs(0)),
@@ -47,6 +48,13 @@ GoButtonGtk::GoButtonGtk(LocationBarViewGtk* location_bar, Browser* browser)
GTK_WIDGET_UNSET_FLAGS(widget_.get(), GTK_CAN_FOCUS);
SetTooltip();
+
+ if (theme_provider_) {
+ theme_provider_->InitThemesFor(this);
+ registrar_.Add(this,
+ NotificationType::BROWSER_THEME_CHANGED,
+ NotificationService::AllSources());
+ }
}
GoButtonGtk::~GoButtonGtk() {
@@ -65,9 +73,21 @@ void GoButtonGtk::ChangeMode(Mode mode, bool force) {
gtk_widget_queue_draw(widget_.get());
SetTooltip();
visible_mode_ = mode;
+
+ UpdateThemeButtons();
}
}
+void GoButtonGtk::Observe(NotificationType type,
+ const NotificationSource& source, const NotificationDetails& details) {
+ DCHECK(NotificationType::BROWSER_THEME_CHANGED == type);
+
+ GtkThemeProvider* provider = static_cast<GtkThemeProvider*>(
+ Source<GtkThemeProvider>(source).ptr());
+ DCHECK(provider == theme_provider_);
+ UpdateThemeButtons();
+}
+
Task* GoButtonGtk::CreateButtonTimerTask() {
return stop_timer_.NewRunnableMethod(&GoButtonGtk::OnButtonTimer);
}
@@ -81,10 +101,14 @@ void GoButtonGtk::OnButtonTimer() {
gboolean GoButtonGtk::OnExpose(GtkWidget* widget,
GdkEventExpose* e,
GoButtonGtk* button) {
- if (button->visible_mode_ == MODE_GO) {
- return button->go_.OnExpose(widget, e);
+ if (button->theme_provider_->UseGtkTheme()) {
+ return FALSE;
} else {
- return button->stop_.OnExpose(widget, e);
+ if (button->visible_mode_ == MODE_GO) {
+ return button->go_.OnExpose(widget, e);
+ } else {
+ return button->stop_.OnExpose(widget, e);
+ }
}
}
@@ -173,3 +197,31 @@ void GoButtonGtk::SetTooltip() {
widget_.get(), l10n_util::GetStringUTF8(IDS_TOOLTIP_STOP).c_str());
}
}
+
+void GoButtonGtk::UpdateThemeButtons() {
+ if (theme_provider_->UseGtkTheme()) {
+ // TODO(erg): Waiting for Glen to make a version of these that don't have a
+ // button border on it.
+ if (intended_mode_ == MODE_GO) {
+ gtk_button_set_image(
+ GTK_BUTTON(widget_.get()),
+ gtk_image_new_from_stock(GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_BUTTON));
+ } else {
+ gtk_button_set_image(
+ GTK_BUTTON(widget_.get()),
+ gtk_image_new_from_stock(GTK_STOCK_STOP, GTK_ICON_SIZE_BUTTON));
+ }
+
+ gtk_widget_set_size_request(widget_.get(), -1, -1);
+ gtk_widget_set_app_paintable(widget_.get(), FALSE);
+ gtk_widget_set_double_buffered(widget_.get(), TRUE);
+ } else {
+ gtk_widget_set_size_request(widget_.get(),
+ gdk_pixbuf_get_width(go_.pixbufs(0)),
+ gdk_pixbuf_get_height(go_.pixbufs(0)));
+
+ gtk_widget_set_app_paintable(widget_.get(), TRUE);
+ // We effectively double-buffer by virtue of having only one image...
+ gtk_widget_set_double_buffered(widget_.get(), FALSE);
+ }
+}
diff --git a/chrome/browser/gtk/go_button_gtk.h b/chrome/browser/gtk/go_button_gtk.h
index 0b41c6a..3ab3661 100644
--- a/chrome/browser/gtk/go_button_gtk.h
+++ b/chrome/browser/gtk/go_button_gtk.h
@@ -10,13 +10,16 @@
#include "base/basictypes.h"
#include "base/task.h"
#include "chrome/browser/gtk/custom_button.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
#include "chrome/common/owned_widget_gtk.h"
class Browser;
+class GtkThemeProvider;
class LocationBarViewGtk;
class Task;
-class GoButtonGtk {
+class GoButtonGtk : public NotificationObserver {
public:
enum Mode { MODE_GO = 0, MODE_STOP };
enum ButtonState { BS_NORMAL = 0, BS_HOT };
@@ -31,6 +34,11 @@ class GoButtonGtk {
// immediately.
void ChangeMode(Mode mode, bool force);
+ // Provide NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
private:
friend class GoButtonGtkPeer;
@@ -47,6 +55,10 @@ class GoButtonGtk {
Task* CreateButtonTimerTask();
void OnButtonTimer();
void SetTooltip();
+ void UpdateThemeButtons();
+
+ // Used to listen for theme change notifications.
+ NotificationRegistrar registrar_;
LocationBarViewGtk* const location_bar_;
@@ -66,6 +78,8 @@ class GoButtonGtk {
ButtonState state_;
+ GtkThemeProvider* theme_provider_;
+
CustomDrawButtonBase go_;
CustomDrawButtonBase stop_;
diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc
index 211f997..503a476 100644
--- a/chrome/browser/gtk/location_bar_view_gtk.cc
+++ b/chrome/browser/gtk/location_bar_view_gtk.cc
@@ -389,19 +389,23 @@ gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget,
// window, set a clip to make sure that we don't draw outside.
gdk_gc_set_clip_rectangle(gc, &inner_rect);
- // Draw our 1px border. TODO(deanm): Maybe this would be cleaner as an
- // overdrawn stroked rect with a clip to the allocation?
- gdk_gc_set_rgb_fg_color(gc, &kBorderColor);
- gdk_draw_rectangle(drawable, gc, TRUE,
- inner_rect.x,
- inner_rect.y,
- inner_rect.width,
- kBorderThickness);
- gdk_draw_rectangle(drawable, gc, TRUE,
- inner_rect.x,
- inner_rect.y + inner_rect.height - kBorderThickness,
- inner_rect.width,
- kBorderThickness);
+ // If we're not using GTK theming, draw our own border.
+ if (!profile_ ||
+ !GtkThemeProvider::GetFrom(profile_)->UseGtkTheme()) {
+ // Draw our 1px border. TODO(deanm): Maybe this would be cleaner as an
+ // overdrawn stroked rect with a clip to the allocation?
+ gdk_gc_set_rgb_fg_color(gc, &kBorderColor);
+ gdk_draw_rectangle(drawable, gc, TRUE,
+ inner_rect.x,
+ inner_rect.y,
+ inner_rect.width,
+ kBorderThickness);
+ gdk_draw_rectangle(drawable, gc, TRUE,
+ inner_rect.x,
+ inner_rect.y + inner_rect.height - kBorderThickness,
+ inner_rect.width,
+ kBorderThickness);
+ }
// Draw the background within the border.
gdk_gc_set_rgb_fg_color(gc,
diff --git a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc
index 0fd1045..631ad2c 100644
--- a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc
+++ b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc
@@ -10,16 +10,16 @@
#include "chrome/browser/gtk/browser_toolbar_gtk.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/profile.h"
+#include "chrome/common/notification_service.h"
#include "grit/theme_resources.h"
ToolbarStarToggleGtk::ToolbarStarToggleGtk(BrowserToolbarGtk* host)
: host_(host),
widget_(gtk_button_new()),
is_starred_(false),
- unstarred_(GtkThemeProvider::GetFrom(host->profile()),
- IDR_STAR, IDR_STAR_P, IDR_STAR_H, IDR_STAR_D),
- starred_(GtkThemeProvider::GetFrom(host->profile()),
- IDR_STARRED, IDR_STARRED_P, IDR_STARRED_H, 0) {
+ theme_provider_(GtkThemeProvider::GetFrom(host->profile())),
+ unstarred_(theme_provider_, IDR_STAR, IDR_STAR_P, IDR_STAR_H, IDR_STAR_D),
+ starred_(theme_provider_, IDR_STARRED, IDR_STARRED_P, IDR_STARRED_H, 0) {
gtk_widget_set_size_request(widget_.get(),
gdk_pixbuf_get_width(unstarred_.pixbufs(0)),
gdk_pixbuf_get_height(unstarred_.pixbufs(0)));
@@ -27,15 +27,31 @@ ToolbarStarToggleGtk::ToolbarStarToggleGtk(BrowserToolbarGtk* host)
gtk_widget_set_app_paintable(widget_.get(), TRUE);
// We effectively double-buffer by virtue of having only one image...
gtk_widget_set_double_buffered(widget_.get(), FALSE);
+
g_signal_connect(G_OBJECT(widget_.get()), "expose-event",
G_CALLBACK(OnExpose), this);
GTK_WIDGET_UNSET_FLAGS(widget_.get(), GTK_CAN_FOCUS);
+
+ theme_provider_->InitThemesFor(this);
+ registrar_.Add(this,
+ NotificationType::BROWSER_THEME_CHANGED,
+ NotificationService::AllSources());
}
ToolbarStarToggleGtk::~ToolbarStarToggleGtk() {
widget_.Destroy();
}
+void ToolbarStarToggleGtk::Observe(NotificationType type,
+ const NotificationSource& source, const NotificationDetails& details) {
+ DCHECK(NotificationType::BROWSER_THEME_CHANGED == type);
+
+ GtkThemeProvider* provider = static_cast<GtkThemeProvider*>(
+ Source<GtkThemeProvider>(source).ptr());
+ DCHECK(provider == theme_provider_);
+ UpdateGTKButton();
+}
+
void ToolbarStarToggleGtk::ShowStarBubble(const GURL& url,
bool newly_bookmarked) {
GtkWidget* widget = widget_.get();
@@ -56,14 +72,46 @@ void ToolbarStarToggleGtk::ShowStarBubble(const GURL& url,
void ToolbarStarToggleGtk::SetStarred(bool starred) {
is_starred_ = starred;
gtk_widget_queue_draw(widget_.get());
+ UpdateGTKButton();
}
// static
gboolean ToolbarStarToggleGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e,
ToolbarStarToggleGtk* button) {
- if (button->is_starred_) {
- return button->starred_.OnExpose(widget, e);
+ if (button->theme_provider_->UseGtkTheme()) {
+ return FALSE;
+ } else {
+ if (button->is_starred_) {
+ return button->starred_.OnExpose(widget, e);
+ } else {
+ return button->unstarred_.OnExpose(widget, e);
+ }
+ }
+}
+
+void ToolbarStarToggleGtk::UpdateGTKButton() {
+ if (theme_provider_->UseGtkTheme()) {
+ GdkPixbuf* pixbuf = NULL;
+ if (is_starred_) {
+ pixbuf = theme_provider_->GetPixbufNamed(IDR_STARRED_NOBORDER);
+ } else {
+ pixbuf = theme_provider_->GetPixbufNamed(IDR_STAR_NOBORDER);
+ }
+
+ gtk_button_set_image(
+ GTK_BUTTON(widget_.get()),
+ gtk_image_new_from_pixbuf(pixbuf));
+
+ gtk_widget_set_size_request(widget_.get(), -1, -1);
+ gtk_widget_set_app_paintable(widget_.get(), FALSE);
+ gtk_widget_set_double_buffered(widget_.get(), TRUE);
} else {
- return button->unstarred_.OnExpose(widget, e);
+ gtk_widget_set_size_request(widget_.get(),
+ gdk_pixbuf_get_width(unstarred_.pixbufs(0)),
+ gdk_pixbuf_get_height(unstarred_.pixbufs(0)));
+
+ gtk_widget_set_app_paintable(widget_.get(), TRUE);
+ // We effectively double-buffer by virtue of having only one image...
+ gtk_widget_set_double_buffered(widget_.get(), FALSE);
}
}
diff --git a/chrome/browser/gtk/toolbar_star_toggle_gtk.h b/chrome/browser/gtk/toolbar_star_toggle_gtk.h
index afa61a3..2284415 100644
--- a/chrome/browser/gtk/toolbar_star_toggle_gtk.h
+++ b/chrome/browser/gtk/toolbar_star_toggle_gtk.h
@@ -9,17 +9,25 @@
#include "base/basictypes.h"
#include "chrome/browser/gtk/custom_button.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
#include "chrome/common/owned_widget_gtk.h"
class BrowserToolbarGtk;
+class GtkThemeProvider;
class GURL;
// Displays the bookmark star button, which toggles between two images.
-class ToolbarStarToggleGtk {
+class ToolbarStarToggleGtk : public NotificationObserver {
public:
- ToolbarStarToggleGtk(BrowserToolbarGtk* host);
+ explicit ToolbarStarToggleGtk(BrowserToolbarGtk* host);
~ToolbarStarToggleGtk();
+ // Provide NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
// If the bubble isn't showing, shows it above the star button.
void ShowStarBubble(const GURL& url, bool newly_bookmarked);
@@ -28,10 +36,17 @@ class ToolbarStarToggleGtk {
GtkWidget* widget() const { return widget_.get(); }
private:
+ // Updates the properties of |widget_| when we would need to change its
+ // state.
+ void UpdateGTKButton();
+
// Callback for expose, used to draw the custom graphics.
static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e,
ToolbarStarToggleGtk* obj);
+ // Used to listen for theme change notifications.
+ NotificationRegistrar registrar_;
+
// The browser toolbar hosting this widget, for getting the current profile.
BrowserToolbarGtk* host_;
@@ -41,6 +56,8 @@ class ToolbarStarToggleGtk {
// Whether we show the yellow star.
bool is_starred_;
+ GtkThemeProvider* theme_provider_;
+
CustomDrawButtonBase unstarred_;
CustomDrawButtonBase starred_;