diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-24 16:54:46 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-24 16:54:46 +0000 |
commit | 5e56a3a8e84ee5b4417077f5f3ec17b7dbe73bd1 (patch) | |
tree | ba6052962bcb4cd3eb60f7308ef19db86fff9e7d | |
parent | 6d39d49d2001775bf486299261613298e1aab12a (diff) | |
download | chromium_src-5e56a3a8e84ee5b4417077f5f3ec17b7dbe73bd1.zip chromium_src-5e56a3a8e84ee5b4417077f5f3ec17b7dbe73bd1.tar.gz chromium_src-5e56a3a8e84ee5b4417077f5f3ec17b7dbe73bd1.tar.bz2 |
GTK Themes: Theme the bookmark bubble. (And first run bubble).
http://crbug.com/16783
Review URL: http://codereview.chromium.org/160025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21535 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/bookmark_bubble_gtk.cc | 30 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_bubble_gtk.h | 20 | ||||
-rw-r--r-- | chrome/browser/gtk/edit_search_engine_dialog.cc | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/first_run_bubble.cc | 31 | ||||
-rw-r--r-- | chrome/browser/gtk/first_run_bubble.h | 27 | ||||
-rw-r--r-- | chrome/browser/gtk/info_bubble_gtk.cc | 38 | ||||
-rw-r--r-- | chrome/browser/gtk/info_bubble_gtk.h | 7 | ||||
-rw-r--r-- | chrome/common/gtk_util.cc | 8 | ||||
-rw-r--r-- | chrome/common/gtk_util.h | 17 |
9 files changed, 148 insertions, 32 deletions
diff --git a/chrome/browser/gtk/bookmark_bubble_gtk.cc b/chrome/browser/gtk/bookmark_bubble_gtk.cc index c08cdf9..67c9dc6 100644 --- a/chrome/browser/gtk/bookmark_bubble_gtk.cc +++ b/chrome/browser/gtk/bookmark_bubble_gtk.cc @@ -16,6 +16,7 @@ #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/gtk/gtk_chrome_link_button.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/info_bubble_gtk.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profile.h" @@ -112,6 +113,24 @@ void BookmarkBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble, NotificationService::NoDetails()); } +void BookmarkBubbleGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); + + if (theme_provider_->UseGtkTheme()) { + for (std::vector<GtkWidget*>::iterator it = labels_.begin(); + it != labels_.end(); ++it) { + gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, NULL); + } + } else { + for (std::vector<GtkWidget*>::iterator it = labels_.begin(); + it != labels_.end(); ++it) { + gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, &gfx::kGdkBlack); + } + } +} + BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, const gfx::Rect& rect, Profile* profile, @@ -119,6 +138,7 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, bool newly_bookmarked) : url_(url), profile_(profile), + theme_provider_(GtkThemeProvider::GetFrom(profile_)), transient_toplevel_(transient_toplevel), content_(NULL), name_entry_(NULL), @@ -131,7 +151,7 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, GtkWidget* label = gtk_label_new(l10n_util::GetStringUTF8( newly_bookmarked_ ? IDS_BOOMARK_BUBBLE_PAGE_BOOKMARKED : IDS_BOOMARK_BUBBLE_PAGE_BOOKMARK).c_str()); - gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack); + labels_.push_back(label); GtkWidget* remove_button = gtk_chrome_link_button_new( l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_REMOVE_BOOKMARK).c_str()); GtkWidget* edit_button = gtk_button_new_with_label( @@ -166,7 +186,7 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, // We use a table to allow the labels to line up with each other, along // with the entry and folder combo lining up. GtkWidget* table = gtk_util::CreateLabeledControlsGroup( - &gfx::kGdkBlack, + &labels_, l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_TITLE_TEXT).c_str(), name_entry_, l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_FOLDER_TEXT).c_str(), @@ -190,7 +210,7 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, gtk_container_set_focus_child(GTK_CONTAINER(content), table); bubble_ = InfoBubbleGtk::Show(transient_toplevel_, - rect, content, this); + rect, content, theme_provider_, this); if (!bubble_) { NOTREACHED(); return; @@ -208,6 +228,10 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, G_CALLBACK(&HandleCloseButtonThunk), this); g_signal_connect(remove_button, "clicked", G_CALLBACK(&HandleRemoveButtonThunk), this); + + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); + theme_provider_->InitThemesFor(this); } BookmarkBubbleGtk::~BookmarkBubbleGtk() { diff --git a/chrome/browser/gtk/bookmark_bubble_gtk.h b/chrome/browser/gtk/bookmark_bubble_gtk.h index 48890b6..3b86a6b 100644 --- a/chrome/browser/gtk/bookmark_bubble_gtk.h +++ b/chrome/browser/gtk/bookmark_bubble_gtk.h @@ -14,11 +14,14 @@ #include <gtk/gtk.h> +#include <string> #include <vector> #include "base/basictypes.h" #include "base/task.h" #include "chrome/browser/gtk/info_bubble_gtk.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" #include "googleurl/src/gurl.h" class BookmarkNode; @@ -27,7 +30,8 @@ namespace gfx { class Rect; } -class BookmarkBubbleGtk : public InfoBubbleGtkDelegate { +class BookmarkBubbleGtk : public InfoBubbleGtkDelegate, + public NotificationObserver { public: // Shows the bookmark bubble, pointing at |rect|. static void Show(GtkWindow* transient_toplevel, @@ -42,6 +46,11 @@ class BookmarkBubbleGtk : public InfoBubbleGtkDelegate { virtual void InfoBubbleClosing(InfoBubbleGtk* info_bubble, bool closed_by_escape); + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + private: BookmarkBubbleGtk(GtkWindow* transient_toplevel, const gfx::Rect& rect, @@ -107,6 +116,9 @@ class BookmarkBubbleGtk : public InfoBubbleGtkDelegate { // Our current profile (used to access the bookmark system). Profile* profile_; + // Provides colors and stuff. + GtkThemeProvider* theme_provider_; + // The toplevel window our dialogs should be transient for. GtkWindow* transient_toplevel_; @@ -114,6 +126,10 @@ class BookmarkBubbleGtk : public InfoBubbleGtkDelegate { // when the widget is destroyed (when the InfoBubble is destroyed). GtkWidget* content_; + // The various labels in the interface. We keep track of them for theme + // changes. + std::vector<GtkWidget*> labels_; + // The GtkEntry for editing the bookmark name / title. GtkWidget* name_entry_; @@ -135,6 +151,8 @@ class BookmarkBubbleGtk : public InfoBubbleGtkDelegate { bool apply_edits_; bool remove_bookmark_; + NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(BookmarkBubbleGtk); }; diff --git a/chrome/browser/gtk/edit_search_engine_dialog.cc b/chrome/browser/gtk/edit_search_engine_dialog.cc index 72373d1..509d538 100644 --- a/chrome/browser/gtk/edit_search_engine_dialog.cc +++ b/chrome/browser/gtk/edit_search_engine_dialog.cc @@ -53,7 +53,7 @@ void LowercaseInsertTextHandler(GtkEditable *editable, const gchar *text, } } -} // namespace +} // namespace EditSearchEngineDialog::EditSearchEngineDialog( GtkWindow* parent_window, diff --git a/chrome/browser/gtk/first_run_bubble.cc b/chrome/browser/gtk/first_run_bubble.cc index 88bbc3f9..12127bd 100644 --- a/chrome/browser/gtk/first_run_bubble.cc +++ b/chrome/browser/gtk/first_run_bubble.cc @@ -8,9 +8,11 @@ #include "app/l10n_util.h" #include "base/gfx/gtk_util.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/options_window.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/common/gtk_util.h" +#include "chrome/common/notification_service.h" #include "grit/chromium_strings.h" #include "grit/locale_settings.h" #include "grit/generated_resources.h" @@ -50,23 +52,45 @@ void FirstRunBubble::InfoBubbleClosing(InfoBubbleGtk* info_bubble, // TODO(port): Enable parent window } +void FirstRunBubble::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); + + if (theme_provider_->UseGtkTheme()) { + for (std::vector<GtkWidget*>::iterator it = labels_.begin(); + it != labels_.end(); ++it) { + gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, NULL); + } + } else { + for (std::vector<GtkWidget*>::iterator it = labels_.begin(); + it != labels_.end(); ++it) { + gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, &gfx::kGdkBlack); + } + } +} + FirstRunBubble::FirstRunBubble(Profile* profile, GtkWindow* parent, const gfx::Rect& rect) : profile_(profile), + theme_provider_(GtkThemeProvider::GetFrom(profile_)), parent_(parent), content_(NULL), bubble_(NULL) { GtkWidget* label1 = gtk_label_new(NULL); + labels_.push_back(label1); char* markup = g_markup_printf_escaped(kSearchLabelMarkup, l10n_util::GetStringUTF8(IDS_FR_BUBBLE_TITLE).c_str()); gtk_label_set_markup(GTK_LABEL(label1), markup); g_free(markup); gtk_misc_set_alignment(GTK_MISC(label1), 0, .5); + // TODO(erg): Theme these colors. gtk_widget_modify_fg(label1, GTK_STATE_NORMAL, &gfx::kGdkBlack); GtkWidget* label2 = gtk_label_new( l10n_util::GetStringUTF8(IDS_FR_BUBBLE_SUBTEXT).c_str()); + labels_.push_back(label2); gtk_misc_set_alignment(GTK_MISC(label2), 0, .5); gtk_label_set_line_wrap(GTK_LABEL(label2), TRUE); gtk_widget_modify_fg(label2, GTK_STATE_NORMAL, &gfx::kGdkBlack); @@ -74,6 +98,7 @@ FirstRunBubble::FirstRunBubble(Profile* profile, string16 search_engine = GetDefaultSearchEngineName(profile_); GtkWidget* label3 = gtk_label_new( l10n_util::GetStringFUTF8(IDS_FR_BUBBLE_QUESTION, search_engine).c_str()); + labels_.push_back(label3); gtk_misc_set_alignment(GTK_MISC(label3), 0, .5); gtk_label_set_line_wrap(GTK_LABEL(label3), TRUE); gtk_widget_modify_fg(label3, GTK_STATE_NORMAL, &gfx::kGdkBlack); @@ -114,7 +139,7 @@ FirstRunBubble::FirstRunBubble(Profile* profile, // We want the focus to start on the keep entry, not on the change button. gtk_container_set_focus_child(GTK_CONTAINER(content_), keep_button); - bubble_ = InfoBubbleGtk::Show(parent_, rect, content_, this); + bubble_ = InfoBubbleGtk::Show(parent_, rect, content_, theme_provider_, this); if (!bubble_) { NOTREACHED(); return; @@ -126,6 +151,10 @@ FirstRunBubble::FirstRunBubble(Profile* profile, G_CALLBACK(&HandleKeepButtonThunk), this); g_signal_connect(change_button, "clicked", G_CALLBACK(&HandleChangeButtonThunk), this); + + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); + theme_provider_->InitThemesFor(this); } void FirstRunBubble::HandleChangeButton() { diff --git a/chrome/browser/gtk/first_run_bubble.h b/chrome/browser/gtk/first_run_bubble.h index 6e7c817..b52dc98 100644 --- a/chrome/browser/gtk/first_run_bubble.h +++ b/chrome/browser/gtk/first_run_bubble.h @@ -6,16 +6,21 @@ // presented on first run of Chromium. There can only ever be a single // bubble open, so the class presents only static methods. -#ifndef CHROME_BROWSER_GTK_FIRST_RUN_BUBBLE_GTK_H_ -#define CHROME_BROWSER_GTK_FIRST_RUN_BUBBLE_GTK_H_ +#ifndef CHROME_BROWSER_GTK_FIRST_RUN_BUBBLE_H_ +#define CHROME_BROWSER_GTK_FIRST_RUN_BUBBLE_H_ #include <gtk/gtk.h> +#include <vector> + #include "base/basictypes.h" #include "chrome/browser/gtk/info_bubble_gtk.h" #include "chrome/browser/profile.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" -class FirstRunBubble : public InfoBubbleGtkDelegate { +class FirstRunBubble : public InfoBubbleGtkDelegate, + public NotificationObserver { public: // Shows the first run bubble, pointing at |rect|. static void Show(Profile* profile, @@ -29,6 +34,11 @@ class FirstRunBubble : public InfoBubbleGtkDelegate { bool closed_by_escape); virtual bool CloseOnEscape() { return true; } + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + private: FirstRunBubble(Profile* profile, GtkWindow* parent, @@ -53,6 +63,9 @@ class FirstRunBubble : public InfoBubbleGtkDelegate { // Our current profile. Profile* profile_; + // Provides colors and stuff. + GtkThemeProvider* theme_provider_; + // The toplevel window our dialogs should be transient for. GtkWindow* parent_; @@ -60,9 +73,15 @@ class FirstRunBubble : public InfoBubbleGtkDelegate { // when the widget is destroyed (when the InfoBubble is destroyed). GtkWidget* content_; + // The various labels in the interface. We keep track of them for theme + // changes. + std::vector<GtkWidget*> labels_; + InfoBubbleGtk* bubble_; + NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(FirstRunBubble); }; -#endif // CHROME_BROWSER_GTK_FIRST_RUN_BUBBLE_GTK_H_ +#endif // CHROME_BROWSER_GTK_FIRST_RUN_BUBBLE_H_ diff --git a/chrome/browser/gtk/info_bubble_gtk.cc b/chrome/browser/gtk/info_bubble_gtk.cc index 892d08e..de099ac 100644 --- a/chrome/browser/gtk/info_bubble_gtk.cc +++ b/chrome/browser/gtk/info_bubble_gtk.cc @@ -12,6 +12,7 @@ #include "base/gfx/gtk_util.h" #include "base/gfx/rect.h" #include "base/logging.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/common/notification_service.h" namespace { @@ -123,16 +124,18 @@ gboolean HandleExpose(GtkWidget* widget, InfoBubbleGtk* InfoBubbleGtk::Show(GtkWindow* transient_toplevel, const gfx::Rect& rect, GtkWidget* content, + GtkThemeProvider* provider, InfoBubbleGtkDelegate* delegate) { - InfoBubbleGtk* bubble = new InfoBubbleGtk(); + InfoBubbleGtk* bubble = new InfoBubbleGtk(provider); bubble->Init(transient_toplevel, rect, content); bubble->set_delegate(delegate); return bubble; } -InfoBubbleGtk::InfoBubbleGtk() +InfoBubbleGtk::InfoBubbleGtk(GtkThemeProvider* provider) : delegate_(NULL), window_(NULL), + theme_provider_(provider), accel_group_(gtk_accel_group_new()), screen_x_(0), screen_y_(0) { @@ -156,8 +159,6 @@ void InfoBubbleGtk::Init(GtkWindow* transient_toplevel, gtk_widget_set_app_paintable(window_, TRUE); // Have GTK double buffer around the expose signal. gtk_widget_set_double_buffered(window_, TRUE); - // Set the background color, so we don't need to paint it manually. - gtk_widget_modify_bg(window_, GTK_STATE_NORMAL, &kBackgroundColor); // Make sure that our window can be focused. GTK_WIDGET_SET_FLAGS(window_, GTK_CAN_FOCUS); @@ -220,22 +221,37 @@ void InfoBubbleGtk::Init(GtkWindow* transient_toplevel, registrar_.Add(this, NotificationType::ACTIVE_WINDOW_CHANGED, NotificationService::AllSources()); + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); + theme_provider_->InitThemesFor(this); } void InfoBubbleGtk::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { - DCHECK(type.value == NotificationType::ACTIVE_WINDOW_CHANGED); - - // If we are no longer the active toplevel for whatever reason (whether - // another toplevel gained focus or our browser did), close. - if (window_->window != Details<const GdkWindow>(details).ptr()) - Close(); + switch (type.value) { + case NotificationType::ACTIVE_WINDOW_CHANGED: + // If we are no longer the active toplevel for whatever reason (whether + // another toplevel gained focus or our browser did), close. + if (window_->window != Details<const GdkWindow>(details).ptr()) + Close(); + break; + case NotificationType::BROWSER_THEME_CHANGED: + if (theme_provider_->UseGtkTheme()) { + gtk_widget_modify_bg(window_, GTK_STATE_NORMAL, NULL); + } else { + // Set the background color, so we don't need to paint it manually. + gtk_widget_modify_bg(window_, GTK_STATE_NORMAL, &kBackgroundColor); + } + break; + default: + NOTREACHED(); + } } // static GtkWindow* InfoBubbleGtk::GetToplevelForInfoBubble( - const GdkWindow* bubble_window){ + const GdkWindow* bubble_window) { if (!bubble_window) return NULL; diff --git a/chrome/browser/gtk/info_bubble_gtk.h b/chrome/browser/gtk/info_bubble_gtk.h index 2707187..7bc45b9 100644 --- a/chrome/browser/gtk/info_bubble_gtk.h +++ b/chrome/browser/gtk/info_bubble_gtk.h @@ -18,6 +18,7 @@ #include "base/basictypes.h" #include "chrome/common/notification_registrar.h" +class GtkThemeProvider; class InfoBubbleGtk; namespace gfx { class Rect; @@ -43,6 +44,7 @@ class InfoBubbleGtk : public NotificationObserver { static InfoBubbleGtk* Show(GtkWindow* transient_toplevel, const gfx::Rect& rect, GtkWidget* content, + GtkThemeProvider* provider, InfoBubbleGtkDelegate* delegate); // Close the bubble if it's open. This will delete the widgets and object, @@ -60,7 +62,7 @@ class InfoBubbleGtk : public NotificationObserver { static GtkWindow* GetToplevelForInfoBubble(const GdkWindow* bubble_window); private: - InfoBubbleGtk(); + explicit InfoBubbleGtk(GtkThemeProvider* provider); virtual ~InfoBubbleGtk(); // Creates the InfoBubble. @@ -121,6 +123,9 @@ class InfoBubbleGtk : public NotificationObserver { // it deletes us when it is destroyed. GtkWidget* window_; + // Provides colors and stuff. + GtkThemeProvider* theme_provider_; + // The accel group attached to |window_|, to handle closing with escape. GtkAccelGroup* accel_group_; diff --git a/chrome/common/gtk_util.cc b/chrome/common/gtk_util.cc index dfb0ac8..19eb595b 100644 --- a/chrome/common/gtk_util.cc +++ b/chrome/common/gtk_util.cc @@ -140,8 +140,8 @@ guint32 GetGdkEventTime(GdkEvent* event) { namespace gtk_util { -GtkWidget* CreateLabeledControlsGroup(const GdkColor* text_color, - const char* text, ...) { +GtkWidget* CreateLabeledControlsGroup(std::vector<GtkWidget*>* labels, + const char* text, ...) { va_list ap; va_start(ap, text); GtkWidget* table = gtk_table_new(0, 2, FALSE); @@ -153,8 +153,8 @@ GtkWidget* CreateLabeledControlsGroup(const GdkColor* text_color, GtkWidget* control = va_arg(ap, GtkWidget*); GtkWidget* label = gtk_label_new(text); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - if (text_color) - gtk_widget_modify_fg(label, GTK_STATE_NORMAL, text_color); + if (labels) + labels->push_back(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, diff --git a/chrome/common/gtk_util.h b/chrome/common/gtk_util.h index 4a17c21..399cb42 100644 --- a/chrome/common/gtk_util.h +++ b/chrome/common/gtk_util.h @@ -7,6 +7,7 @@ #include <gtk/gtk.h> #include <string> +#include <vector> #include "base/gfx/point.h" #include "base/gfx/rect.h" @@ -50,16 +51,20 @@ const int kContentAreaBorder = 12; const int kContentAreaSpacing = 18; // Create a table of labeled controls, using proper spacing and alignment. -// Arguments should be pairs of const char*, GtkWidget*, concluding with a NULL. -// The first argument is a color to force the label text to. It can be NULL to -// get the system default. +// Arguments should be pairs of const char*, GtkWidget*, concluding with a +// NULL. The first argument is a vector in which to place all labels +// produced. It can be NULL if you don't need to keep track of the label +// widgets. The second argument is a color to force the label text to. It can +// be NULL to get the system default. +// // For example: -// controls = CreateLabeledControlsGroup(&gfx::kGdkBlack, +// controls = CreateLabeledControlsGroup(NULL, &gfx::kGdkBlack, // "Name:", title_entry_, // "Folder:", folder_combobox_, // NULL); -GtkWidget* CreateLabeledControlsGroup(const GdkColor* color, - const char* text, ...); +GtkWidget* CreateLabeledControlsGroup( + std::vector<GtkWidget*>* labels, + const char* text, ...); // Create a GtkBin with |child| as its child widget. This bin will paint a // border of color |color| with the sizes specified in pixels. |