diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-16 23:09:39 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-16 23:09:39 +0000 |
commit | 42e8de911a526f8c86a7f5e5fc7dce82a647f6d0 (patch) | |
tree | cdc0bc11f5308d862b0023f6df6af58d731cc80a /chrome/browser/gtk | |
parent | 9d6ad02b8c83feeefa57d6131aa4b00cabb9e914 (diff) | |
download | chromium_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.cc | 50 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/go_button_gtk.cc | 68 | ||||
-rw-r--r-- | chrome/browser/gtk/go_button_gtk.h | 16 | ||||
-rw-r--r-- | chrome/browser/gtk/location_bar_view_gtk.cc | 30 | ||||
-rw-r--r-- | chrome/browser/gtk/toolbar_star_toggle_gtk.cc | 62 | ||||
-rw-r--r-- | chrome/browser/gtk/toolbar_star_toggle_gtk.h | 21 |
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_; |