diff options
31 files changed, 569 insertions, 426 deletions
diff --git a/chrome/browser/browser_theme_provider.cc b/chrome/browser/browser_theme_provider.cc index b8e6b6d..4626006 100644 --- a/chrome/browser/browser_theme_provider.cc +++ b/chrome/browser/browser_theme_provider.cc @@ -29,78 +29,91 @@ #include "app/win_util.h" #endif - -namespace themes { - // Strings used by themes to identify colors for different parts of our UI. -const char* kColorFrame = "frame"; -const char* kColorFrameInactive = "frame_inactive"; -const char* kColorFrameIncognito = "frame_incognito"; -const char* kColorFrameIncognitoInactive = "frame_incognito_inactive"; -const char* kColorToolbar = "toolbar"; -const char* kColorTabText = "tab_text"; -const char* kColorBackgroundTabText = "background_tab_text"; -const char* kColorBookmarkText = "bookmark_text"; -const char* kColorNTPBackground = "ntp_background"; -const char* kColorNTPText = "ntp_text"; -const char* kColorNTPLink = "ntp_link"; -const char* kColorNTPSection = "ntp_section"; -const char* kColorNTPSectionText = "ntp_section_text"; -const char* kColorNTPSectionLink = "ntp_section_link"; -const char* kColorControlBackground = "control_background"; -const char* kColorButtonBackground = "button_background"; +const char* BrowserThemeProvider::kColorFrame = "frame"; +const char* BrowserThemeProvider::kColorFrameInactive = "frame_inactive"; +const char* BrowserThemeProvider::kColorFrameIncognito = "frame_incognito"; +const char* BrowserThemeProvider::kColorFrameIncognitoInactive = + "frame_incognito_inactive"; +const char* BrowserThemeProvider::kColorToolbar = "toolbar"; +const char* BrowserThemeProvider::kColorTabText = "tab_text"; +const char* BrowserThemeProvider::kColorBackgroundTabText = + "background_tab_text"; +const char* BrowserThemeProvider::kColorBookmarkText = "bookmark_text"; +const char* BrowserThemeProvider::kColorNTPBackground = "ntp_background"; +const char* BrowserThemeProvider::kColorNTPText = "ntp_text"; +const char* BrowserThemeProvider::kColorNTPLink = "ntp_link"; +const char* BrowserThemeProvider::kColorNTPSection = "ntp_section"; +const char* BrowserThemeProvider::kColorNTPSectionText = "ntp_section_text"; +const char* BrowserThemeProvider::kColorNTPSectionLink = "ntp_section_link"; +const char* BrowserThemeProvider::kColorControlBackground = + "control_background"; +const char* BrowserThemeProvider::kColorButtonBackground = "button_background"; // Strings used by themes to identify tints to apply to different parts of // our UI. The frame tints apply to the frame color and produce the // COLOR_FRAME* colors. -const char* kTintButtons = "buttons"; -const char* kTintFrame = "frame"; -const char* kTintFrameInactive = "frame_inactive"; -const char* kTintFrameIncognito = "frame_incognito"; -const char* kTintFrameIncognitoInactive = "frame_incognito_inactive"; -const char* kTintBackgroundTab = "background_tab"; +const char* BrowserThemeProvider::kTintButtons = "buttons"; +const char* BrowserThemeProvider::kTintFrame = "frame"; +const char* BrowserThemeProvider::kTintFrameInactive = "frame_inactive"; +const char* BrowserThemeProvider::kTintFrameIncognito = "frame_incognito"; +const char* BrowserThemeProvider::kTintFrameIncognitoInactive = + "frame_incognito_inactive"; +const char* BrowserThemeProvider::kTintBackgroundTab = "background_tab"; // Strings used by themes to identify miscellaneous numerical properties. -const char* kDisplayPropertyNTPAlignment = "ntp_background_alignment"; +const char* BrowserThemeProvider::kDisplayPropertyNTPAlignment = + "ntp_background_alignment"; // Strings used in alignment properties. -const char* kAlignmentTop = "top"; -const char* kAlignmentBottom = "bottom"; -const char* kAlignmentLeft = "left"; -const char* kAlignmentRight = "right"; +const char* BrowserThemeProvider::kAlignmentTop = "top"; +const char* BrowserThemeProvider::kAlignmentBottom = "bottom"; +const char* BrowserThemeProvider::kAlignmentLeft = "left"; +const char* BrowserThemeProvider::kAlignmentRight = "right"; // Default colors. -const SkColor kDefaultColorFrame = SkColorSetRGB(77, 139, 217); -const SkColor kDefaultColorFrameInactive = SkColorSetRGB(152, 188, 233); -const SkColor kDefaultColorFrameIncognito = SkColorSetRGB(83, 106, 139); -const SkColor kDefaultColorFrameIncognitoInactive = +const SkColor BrowserThemeProvider::kDefaultColorFrame = + SkColorSetRGB(77, 139, 217); +const SkColor BrowserThemeProvider::kDefaultColorFrameInactive = + SkColorSetRGB(152, 188, 233); +const SkColor BrowserThemeProvider::kDefaultColorFrameIncognito = + SkColorSetRGB(83, 106, 139); +const SkColor BrowserThemeProvider::kDefaultColorFrameIncognitoInactive = SkColorSetRGB(126, 139, 156); -const SkColor kDefaultColorToolbar = SkColorSetRGB(210, 225, 246); -const SkColor kDefaultColorTabText = SkColorSetRGB(0, 0, 0); -const SkColor kDefaultColorBackgroundTabText = SkColorSetRGB(64, 64, 64); -const SkColor kDefaultColorBookmarkText = SkColorSetRGB(64, 64, 64); -const SkColor kDefaultColorNTPBackground = SkColorSetRGB(255, 255, 255); -const SkColor kDefaultColorNTPText = SkColorSetRGB(0, 0, 0); -const SkColor kDefaultColorNTPLink = SkColorSetRGB(0, 0, 204); -const SkColor kDefaultColorNTPSection = SkColorSetRGB(225, 236, 254); -const SkColor kDefaultColorNTPSectionText = SkColorSetRGB(0, 0, 0); -const SkColor kDefaultColorNTPSectionLink = SkColorSetRGB(0, 0, 204); -const SkColor kDefaultColorControlBackground = NULL; -const SkColor kDefaultColorButtonBackground = NULL; +const SkColor BrowserThemeProvider::kDefaultColorToolbar = + SkColorSetRGB(210, 225, 246); +const SkColor BrowserThemeProvider::kDefaultColorTabText = + SkColorSetRGB(0, 0, 0); +const SkColor BrowserThemeProvider::kDefaultColorBackgroundTabText = + SkColorSetRGB(64, 64, 64); +const SkColor BrowserThemeProvider::kDefaultColorBookmarkText = + SkColorSetRGB(64, 64, 64); +const SkColor BrowserThemeProvider::kDefaultColorNTPBackground = + SkColorSetRGB(255, 255, 255); +const SkColor BrowserThemeProvider::kDefaultColorNTPText = + SkColorSetRGB(0, 0, 0); +const SkColor BrowserThemeProvider::kDefaultColorNTPLink = + SkColorSetRGB(0, 0, 204); +const SkColor BrowserThemeProvider::kDefaultColorNTPSection = + SkColorSetRGB(225, 236, 254); +const SkColor BrowserThemeProvider::kDefaultColorNTPSectionText = + SkColorSetRGB(0, 0, 0); +const SkColor BrowserThemeProvider::kDefaultColorNTPSectionLink = + SkColorSetRGB(0, 0, 204); +const SkColor BrowserThemeProvider::kDefaultColorControlBackground = NULL; +const SkColor BrowserThemeProvider::kDefaultColorButtonBackground = NULL; // Default tints. -const skia::HSL kDefaultTintButtons = { -1, -1, -1 }; -const skia::HSL kDefaultTintFrame = { -1, -1, -1 }; -const skia::HSL kDefaultTintFrameInactive = { -1, 0.5f, 0.72f }; -const skia::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; -const skia::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; -const skia::HSL kDefaultTintBackgroundTab = { -1, 0.5, 0.75 }; -} // namespace themes - -// We really want every member of the previous namespace to be exposed -// here. The alternative is to list every member of namespace themes in a using -// directive. -using namespace themes; +const skia::HSL BrowserThemeProvider::kDefaultTintButtons = { -1, -1, -1 }; +const skia::HSL BrowserThemeProvider::kDefaultTintFrame = { -1, -1, -1 }; +const skia::HSL BrowserThemeProvider::kDefaultTintFrameInactive = + { -1, 0.5f, 0.72f }; +const skia::HSL BrowserThemeProvider::kDefaultTintFrameIncognito = + { -1, 0.2f, 0.35f }; +const skia::HSL BrowserThemeProvider::kDefaultTintFrameIncognitoInactive = + { -1, 0.3f, 0.6f }; +const skia::HSL BrowserThemeProvider::kDefaultTintBackgroundTab = + { -1, 0.5, 0.75 }; // Default display properties. static const int kDefaultDisplayPropertyNTPAlignment = @@ -738,7 +751,7 @@ void BrowserThemeProvider::NotifyThemeChanged() { // Redraw! NotificationService* service = NotificationService::current(); service->Notify(NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources(), + Source<BrowserThemeProvider>(this), NotificationService::NoDetails()); } diff --git a/chrome/browser/browser_theme_provider.h b/chrome/browser/browser_theme_provider.h index b0c1b9c..f91b494 100644 --- a/chrome/browser/browser_theme_provider.h +++ b/chrome/browser/browser_theme_provider.h @@ -20,75 +20,75 @@ class Extension; class Profile; class DictionaryValue; -namespace themes { - -// Strings used by themes to identify colors for different parts of our UI. -extern const char* kColorFrame; -extern const char* kColorFrameInactive; -extern const char* kColorFrameIncognito; -extern const char* kColorFrameIncognitoInactive; -extern const char* kColorToolbar; -extern const char* kColorTabText; -extern const char* kColorBackgroundTabText; -extern const char* kColorBookmarkText; -extern const char* kColorNTPBackground; -extern const char* kColorNTPText; -extern const char* kColorNTPLink; -extern const char* kColorNTPSection; -extern const char* kColorNTPSectionText; -extern const char* kColorNTPSectionLink; -extern const char* kColorControlBackground; -extern const char* kColorButtonBackground; - -// Strings used by themes to identify tints to apply to different parts of -// our UI. The frame tints apply to the frame color and produce the -// COLOR_FRAME* colors. -extern const char* kTintButtons; -extern const char* kTintFrame; -extern const char* kTintFrameInactive; -extern const char* kTintFrameIncognito; -extern const char* kTintFrameIncognitoInactive; -extern const char* kTintBackgroundTab; - -// Strings used by themes to identify miscellaneous numerical properties. -extern const char* kDisplayPropertyNTPAlignment; - -// Strings used in alignment properties. -extern const char* kAlignmentTop; -extern const char* kAlignmentBottom; -extern const char* kAlignmentLeft; -extern const char* kAlignmentRight; - -// Default colors. -extern const SkColor kDefaultColorFrame; -extern const SkColor kDefaultColorFrameInactive; -extern const SkColor kDefaultColorFrameIncognito; -extern const SkColor kDefaultColorFrameIncognitoInactive; -extern const SkColor kDefaultColorToolbar; -extern const SkColor kDefaultColorTabText; -extern const SkColor kDefaultColorBackgroundTabText; -extern const SkColor kDefaultColorBookmarkText; -extern const SkColor kDefaultColorNTPBackground; -extern const SkColor kDefaultColorNTPText; -extern const SkColor kDefaultColorNTPLink; -extern const SkColor kDefaultColorNTPSection; -extern const SkColor kDefaultColorNTPSectionText; -extern const SkColor kDefaultColorNTPSectionLink; -extern const SkColor kDefaultColorControlBackground; -extern const SkColor kDefaultColorButtonBackground; - -extern const skia::HSL kDefaultTintButtons; -extern const skia::HSL kDefaultTintFrame; -extern const skia::HSL kDefaultTintFrameInactive; -extern const skia::HSL kDefaultTintFrameIncognito; -extern const skia::HSL kDefaultTintFrameIncognitoInactive; -extern const skia::HSL kDefaultTintBackgroundTab; -} // namespace themes - class BrowserThemeProvider : public base::RefCounted<BrowserThemeProvider>, public NonThreadSafe, public ThemeProvider { public: + // Public constants used in BrowserThemeProvider and its subclasses: + + // Strings used by themes to identify colors for different parts of our UI. + static const char* kColorFrame; + static const char* kColorFrameInactive; + static const char* kColorFrameIncognito; + static const char* kColorFrameIncognitoInactive; + static const char* kColorToolbar; + static const char* kColorTabText; + static const char* kColorBackgroundTabText; + static const char* kColorBookmarkText; + static const char* kColorNTPBackground; + static const char* kColorNTPText; + static const char* kColorNTPLink; + static const char* kColorNTPSection; + static const char* kColorNTPSectionText; + static const char* kColorNTPSectionLink; + static const char* kColorControlBackground; + static const char* kColorButtonBackground; + + // Strings used by themes to identify tints to apply to different parts of + // our UI. The frame tints apply to the frame color and produce the + // COLOR_FRAME* colors. + static const char* kTintButtons; + static const char* kTintFrame; + static const char* kTintFrameInactive; + static const char* kTintFrameIncognito; + static const char* kTintFrameIncognitoInactive; + static const char* kTintBackgroundTab; + + // Strings used by themes to identify miscellaneous numerical properties. + static const char* kDisplayPropertyNTPAlignment; + + // Strings used in alignment properties. + static const char* kAlignmentTop; + static const char* kAlignmentBottom; + static const char* kAlignmentLeft; + static const char* kAlignmentRight; + + // Default colors. + static const SkColor kDefaultColorFrame; + static const SkColor kDefaultColorFrameInactive; + static const SkColor kDefaultColorFrameIncognito; + static const SkColor kDefaultColorFrameIncognitoInactive; + static const SkColor kDefaultColorToolbar; + static const SkColor kDefaultColorTabText; + static const SkColor kDefaultColorBackgroundTabText; + static const SkColor kDefaultColorBookmarkText; + static const SkColor kDefaultColorNTPBackground; + static const SkColor kDefaultColorNTPText; + static const SkColor kDefaultColorNTPLink; + static const SkColor kDefaultColorNTPSection; + static const SkColor kDefaultColorNTPSectionText; + static const SkColor kDefaultColorNTPSectionLink; + static const SkColor kDefaultColorControlBackground; + static const SkColor kDefaultColorButtonBackground; + + static const skia::HSL kDefaultTintButtons; + static const skia::HSL kDefaultTintFrame; + static const skia::HSL kDefaultTintFrameInactive; + static const skia::HSL kDefaultTintFrameIncognito; + static const skia::HSL kDefaultTintFrameIncognitoInactive; + static const skia::HSL kDefaultTintBackgroundTab; + + public: BrowserThemeProvider(); virtual ~BrowserThemeProvider(); @@ -127,7 +127,7 @@ class BrowserThemeProvider : public base::RefCounted<BrowserThemeProvider>, ALIGN_BOTTOM = 0x8, } AlignmentMasks; - void Init(Profile* profile); + virtual void Init(Profile* profile); // ThemeProvider implementation. virtual SkBitmap* GetBitmapNamed(int id); @@ -181,7 +181,7 @@ class BrowserThemeProvider : public base::RefCounted<BrowserThemeProvider>, virtual void LoadThemePrefs(); // Let all the browser views know that themes have changed. - void NotifyThemeChanged(); + virtual void NotifyThemeChanged(); // Loads a bitmap from the theme, which may be tinted or // otherwise modified, or an application default. diff --git a/chrome/browser/gtk/back_forward_button_gtk.cc b/chrome/browser/gtk/back_forward_button_gtk.cc index bc5238e..ff2ddb8 100644 --- a/chrome/browser/gtk/back_forward_button_gtk.cc +++ b/chrome/browser/gtk/back_forward_button_gtk.cc @@ -11,6 +11,7 @@ #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/browser.h" #include "chrome/browser/gtk/back_forward_menu_model_gtk.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/profile.h" #include "chrome/common/gtk_util.h" @@ -42,7 +43,8 @@ BackForwardButtonGtk::BackForwardButtonGtk(Browser* browser, bool is_forward) tooltip = IDS_TOOLTIP_BACK; stock = GTK_STOCK_GO_BACK; } - button_.reset(new CustomDrawButton(browser_->profile()->GetThemeProvider(), + button_.reset(new CustomDrawButton( + GtkThemeProvider::GetFrom(browser_->profile()), normal, active, highlight, depressed, stock)); gtk_widget_set_tooltip_text(widget(), l10n_util::GetStringUTF8(tooltip).c_str()); @@ -77,10 +79,6 @@ void BackForwardButtonGtk::StoppedShowingMenu() { button_->UnsetPaintOverride(); } -void BackForwardButtonGtk::SetUseSystemTheme(bool use_gtk) { - button_->SetUseSystemTheme(use_gtk); -} - void BackForwardButtonGtk::ShowBackForwardMenu() { menu_.reset(new MenuGtk(menu_model_.get(), true)); button_->SetPaintOverride(GTK_STATE_ACTIVE); diff --git a/chrome/browser/gtk/back_forward_button_gtk.h b/chrome/browser/gtk/back_forward_button_gtk.h index d63412f..cb4c1ab 100644 --- a/chrome/browser/gtk/back_forward_button_gtk.h +++ b/chrome/browser/gtk/back_forward_button_gtk.h @@ -27,9 +27,6 @@ class BackForwardButtonGtk { GtkWidget* widget() { return button_->widget(); } - // Advises our CustomDrawButtons on how to render. - void SetUseSystemTheme(bool use_gtk); - private: // Executes the browser command. static void OnClick(GtkWidget* widget, BackForwardButtonGtk* button); diff --git a/chrome/browser/gtk/blocked_popup_container_view_gtk.cc b/chrome/browser/gtk/blocked_popup_container_view_gtk.cc index 785da3f..6224ff2 100644 --- a/chrome/browser/gtk/blocked_popup_container_view_gtk.cc +++ b/chrome/browser/gtk/blocked_popup_container_view_gtk.cc @@ -61,14 +61,6 @@ void BlockedPopupContainerViewGtk::GetURLAndTitleForPopup( *title = tab_contents->GetTitle(); } -void BlockedPopupContainerViewGtk::UserChangedTheme( - GtkThemeProperties* properties) { - use_gtk_rendering_ = properties->use_gtk_rendering; - - gtk_chrome_button_set_use_gtk_rendering( - GTK_CHROME_BUTTON(menu_button_), use_gtk_rendering_); -} - // Overridden from BlockedPopupContainerView: void BlockedPopupContainerViewGtk::SetPosition() { // No-op. Not required with the GTK version. @@ -131,16 +123,13 @@ void BlockedPopupContainerViewGtk::ExecuteCommand(int id) { BlockedPopupContainerViewGtk::BlockedPopupContainerViewGtk( BlockedPopupContainer* container) : model_(container), - use_gtk_rendering_(false), + theme_provider_(GtkThemeProvider::GetFrom(container->profile())), close_button_(CustomDrawButton::CloseButton()) { Init(); - - GtkThemeProperties properties(container->profile()); - UserChangedTheme(&properties); } void BlockedPopupContainerViewGtk::Init() { - menu_button_ = gtk_chrome_button_new(); + menu_button_ = theme_provider_->BuildChromeButton(); UpdateLabel(); g_signal_connect(menu_button_, "clicked", G_CALLBACK(OnMenuButtonClicked), this); @@ -209,7 +198,7 @@ gboolean BlockedPopupContainerViewGtk::OnContainerExpose( event->area.width, event->area.height); cairo_clip(cr); - if (!container->use_gtk_rendering_) { + if (!container->theme_provider_->UseGtkTheme()) { // TODO(erg): We draw the gradient background only when GTK themes are // off. This isn't a perfect solution as this isn't themed! The views // version doesn't appear to be themed either, so at least for now, diff --git a/chrome/browser/gtk/blocked_popup_container_view_gtk.h b/chrome/browser/gtk/blocked_popup_container_view_gtk.h index dab57f4..02bd791 100644 --- a/chrome/browser/gtk/blocked_popup_container_view_gtk.h +++ b/chrome/browser/gtk/blocked_popup_container_view_gtk.h @@ -15,7 +15,7 @@ class BlockedPopupContainerInternalView; class CustomDrawButton; -class GtkThemeProperties; +class GtkThemeProvider; class MenuGtk; class PrefService; class Profile; @@ -42,10 +42,6 @@ class BlockedPopupContainerViewGtk : public BlockedPopupContainerView, string16* url, string16* title) const; - // Notification that the theme has changed at that we should detect new - // values. - void UserChangedTheme(GtkThemeProperties* properties); - GtkWidget* widget() { return container_.get(); } // Overridden from BlockedPopupContainerView: @@ -89,8 +85,8 @@ class BlockedPopupContainerViewGtk : public BlockedPopupContainerView, // The "Blocked Popups: XXX" button. GtkWidget* menu_button_; - // Whether we should let GTK paint the background and the button decorations. - bool use_gtk_rendering_; + // Our theme provider. + GtkThemeProvider* theme_provider_; // Closes the container. scoped_ptr<CustomDrawButton> close_button_; diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc index 2d98d34..dcfda55 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.cc +++ b/chrome/browser/gtk/bookmark_bar_gtk.cc @@ -29,6 +29,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/gtk_util.h" +#include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #include "grit/app_resources.h" @@ -59,9 +60,13 @@ BookmarkBarGtk::BookmarkBarGtk(Profile* profile, Browser* browser, ignore_button_release_(false), dragged_node_(NULL), toolbar_drop_item_(NULL), + theme_provider_(GtkThemeProvider::GetFrom(profile)), show_instructions_(true) { Init(profile); SetProfile(profile); + + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); } BookmarkBarGtk::~BookmarkBarGtk() { @@ -147,7 +152,7 @@ void BookmarkBarGtk::Init(Profile* profile) { // We pack the button manually (rather than using gtk_button_set_*) so that // we can have finer control over its label. - other_bookmarks_button_ = gtk_chrome_button_new(); + other_bookmarks_button_ = theme_provider_->BuildChromeButton(); ConnectFolderButtonEvents(other_bookmarks_button_); gtk_box_pack_start(GTK_BOX(bookmark_hbox_.get()), other_bookmarks_button_, FALSE, FALSE, 0); @@ -278,8 +283,7 @@ void BookmarkBarGtk::BookmarkNodeChanged(BookmarkModel* model, GtkToolItem* item = gtk_toolbar_get_nth_item( GTK_TOOLBAR(bookmark_toolbar_.get()), index); GtkWidget* button = gtk_bin_get_child(GTK_BIN(item)); - GtkThemeProperties properties(profile_); - bookmark_utils::ConfigureButtonForNode(node, model, button, &properties); + bookmark_utils::ConfigureButtonForNode(node, model, button, theme_provider_); } void BookmarkBarGtk::BookmarkNodeFavIconLoaded(BookmarkModel* model, @@ -307,9 +311,8 @@ void BookmarkBarGtk::CreateAllBookmarkButtons() { gtk_toolbar_insert(GTK_TOOLBAR(bookmark_toolbar_.get()), item, -1); } - GtkThemeProperties properties(profile_); bookmark_utils::ConfigureButtonForNode(model_->other_node(), - model_, other_bookmarks_button_, &properties); + model_, other_bookmarks_button_, theme_provider_); SetInstructionState(); } @@ -339,18 +342,6 @@ bool BookmarkBarGtk::IsAlwaysShown() { return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); } -void BookmarkBarGtk::UserChangedTheme(GtkThemeProperties* properties) { - if (model_) { - // Regenerate the bookmark bar with all new objects with their theme - // properties set correctly for the new theme. - RemoveAllBookmarkButtons(); - CreateAllBookmarkButtons(); - } else { - DLOG(ERROR) << "Received a theme change notification while we don't have a " - << "BookmarkModel. Taking no action."; - } -} - void BookmarkBarGtk::AnimationProgressed(const Animation* animation) { DCHECK_EQ(animation, slide_animation_.get()); @@ -366,10 +357,25 @@ void BookmarkBarGtk::AnimationEnded(const Animation* animation) { gtk_widget_hide(bookmark_hbox_.get()); } +void BookmarkBarGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::BROWSER_THEME_CHANGED) { + if (model_) { + // Regenerate the bookmark bar with all new objects with their theme + // properties set correctly for the new theme. + RemoveAllBookmarkButtons(); + CreateAllBookmarkButtons(); + } else { + DLOG(ERROR) << "Received a theme change notification while we " + << "don't have a BookmarkModel. Taking no action."; + } + } +} + GtkWidget* BookmarkBarGtk::CreateBookmarkButton(const BookmarkNode* node) { - GtkWidget* button = gtk_chrome_button_new(); - GtkThemeProperties properties(profile_); - bookmark_utils::ConfigureButtonForNode(node, model_, button, &properties); + GtkWidget* button = theme_provider_->BuildChromeButton(); + bookmark_utils::ConfigureButtonForNode(node, model_, button, theme_provider_); // The tool item is also a source for dragging gtk_drag_source_set(button, GDK_BUTTON1_MASK, @@ -562,9 +568,8 @@ void BookmarkBarGtk::OnButtonDragBegin(GtkWidget* button, bar->dragged_node_ = node; DCHECK(bar->dragged_node_); - GtkThemeProperties properties(bar->profile_); - GtkWidget* window = bookmark_utils::GetDragRepresentation(node, bar->model_, - &properties); + GtkWidget* window = bookmark_utils::GetDragRepresentation( + node, bar->model_, bar->theme_provider_); gint x, y; gtk_widget_get_pointer(button, &x, &y); gtk_drag_set_icon_widget(drag_context, window, x, y); diff --git a/chrome/browser/gtk/bookmark_bar_gtk.h b/chrome/browser/gtk/bookmark_bar_gtk.h index f179b15..102a646 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.h +++ b/chrome/browser/gtk/bookmark_bar_gtk.h @@ -10,8 +10,10 @@ #include <string> #include "app/slide_animation.h" -#include "chrome/common/owned_widget_gtk.h" #include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" +#include "chrome/common/owned_widget_gtk.h" class BookmarkContextMenu; class BookmarkMenuController; @@ -21,10 +23,11 @@ class CustomContainerButton; class NineBox; class PageNavigator; class Profile; -struct GtkThemeProperties; +struct GtkThemeProvider; class BookmarkBarGtk : public AnimationDelegate, - public BookmarkModelObserver { + public BookmarkModelObserver, + public NotificationObserver { public: explicit BookmarkBarGtk(Profile* profile, Browser* browser, BrowserWindowGtk* window); @@ -68,9 +71,6 @@ class BookmarkBarGtk : public AnimationDelegate, // Returns true if the bookmarks bar preference is set to 'always show'. bool IsAlwaysShown(); - // Alerts us that the theme changed, and we might need to change theme images. - void UserChangedTheme(GtkThemeProperties* properties); - // AnimationDelegate implementation ------------------------------------------ virtual void AnimationProgressed(const Animation* animation); virtual void AnimationEnded(const Animation* animation); @@ -120,6 +120,11 @@ class BookmarkBarGtk : public AnimationDelegate, virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, const BookmarkNode* node); + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + GtkWidget* CreateBookmarkButton(const BookmarkNode* node); GtkToolItem* CreateBookmarkToolItem(const BookmarkNode* node); @@ -228,6 +233,9 @@ class BookmarkBarGtk : public AnimationDelegate, // We create a GtkToolbarItem from |dragged_node_| for display. GtkToolItem* toolbar_drop_item_; + // Theme provider for building buttons. + GtkThemeProvider* theme_provider_; + // Whether we should show the instructional text in the bookmark bar. bool show_instructions_; @@ -243,6 +251,8 @@ class BookmarkBarGtk : public AnimationDelegate, scoped_ptr<NineBox> background_ninebox_; scoped_ptr<SlideAnimation> slide_animation_; + + NotificationRegistrar registrar_; }; #endif // CHROME_BROWSER_GTK_BOOKMARK_BAR_GTK_H_ diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc index 23e198a..58629b8 100644 --- a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc +++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc @@ -244,9 +244,9 @@ void BookmarkMenuController::OnMenuItemDragBegin( controller->ignore_button_release_ = true; const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(menu_item); - GtkThemeProperties properties(controller->profile_); GtkWidget* window = bookmark_utils::GetDragRepresentation( - node, controller->model_, &properties); + node, controller->model_, + GtkThemeProvider::GetFrom(controller->profile_)); gint x, y; gtk_widget_get_pointer(menu_item, &x, &y); gtk_drag_set_icon_widget(drag_context, window, x, y); diff --git a/chrome/browser/gtk/bookmark_utils_gtk.cc b/chrome/browser/gtk/bookmark_utils_gtk.cc index b388dfc..b83553f 100644 --- a/chrome/browser/gtk/bookmark_utils_gtk.cc +++ b/chrome/browser/gtk/bookmark_utils_gtk.cc @@ -86,10 +86,10 @@ GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model) { GtkWidget* GetDragRepresentation(const BookmarkNode* node, BookmarkModel* model, - GtkThemeProperties* properties) { + GtkThemeProvider* provider) { // Build a windowed representation for our button. GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); - if (!properties->use_gtk_rendering) { + if (!provider->UseGtkTheme()) { // TODO(erg): Theme wise, which color should I be picking here? // COLOR_BUTTON_BACKGROUND doesn't match the default theme! gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &kBackgroundColor); @@ -101,9 +101,9 @@ GtkWidget* GetDragRepresentation(const BookmarkNode* node, gtk_container_add(GTK_CONTAINER(window), frame); gtk_widget_show(frame); - GtkWidget* floating_button = gtk_chrome_button_new(); + GtkWidget* floating_button = provider->BuildChromeButton(); bookmark_utils::ConfigureButtonForNode(node, model, floating_button, - properties); + provider); gtk_container_add(GTK_CONTAINER(frame), floating_button); gtk_widget_show(floating_button); @@ -111,7 +111,7 @@ GtkWidget* GetDragRepresentation(const BookmarkNode* node, } void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model, - GtkWidget* button, GtkThemeProperties* properties) { + GtkWidget* button, GtkThemeProvider* provider) { GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button)); if (former_child) gtk_container_remove(GTK_CONTAINER(button), former_child); @@ -141,13 +141,10 @@ void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model, gtk_container_add(GTK_CONTAINER(alignment), box); gtk_container_add(GTK_CONTAINER(button), alignment); - SetButtonTextColors(label, properties); + SetButtonTextColors(label, provider); g_object_set_data(G_OBJECT(button), bookmark_utils::kBookmarkNode, AsVoid(node)); - gtk_chrome_button_set_use_gtk_rendering(GTK_CHROME_BUTTON(button), - properties->use_gtk_rendering); - gtk_widget_show_all(alignment); } @@ -162,14 +159,14 @@ const BookmarkNode* BookmarkNodeForWidget(GtkWidget* widget) { g_object_get_data(G_OBJECT(widget), bookmark_utils::kBookmarkNode)); } -void SetButtonTextColors(GtkWidget* label, GtkThemeProperties* properties) { - if (properties->use_gtk_rendering) { +void SetButtonTextColors(GtkWidget* label, GtkThemeProvider* provider) { + if (provider->UseGtkTheme()) { gtk_widget_modify_fg(label, GTK_STATE_NORMAL, NULL); gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, NULL); gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, NULL); gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, NULL); } else { - GdkColor color = properties->GetGdkColor( + GdkColor color = provider->GetGdkColor( BrowserThemeProvider::COLOR_BOOKMARK_TEXT); gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &color); gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &color); diff --git a/chrome/browser/gtk/bookmark_utils_gtk.h b/chrome/browser/gtk/bookmark_utils_gtk.h index a78402b..9f252c6 100644 --- a/chrome/browser/gtk/bookmark_utils_gtk.h +++ b/chrome/browser/gtk/bookmark_utils_gtk.h @@ -11,8 +11,8 @@ class BookmarkModel; class BookmarkNode; +class GtkThemeProvider; class Profile; -struct GtkThemeProperties; namespace bookmark_utils { @@ -34,12 +34,12 @@ GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model); // gtk_drag_set_icon_widget(). GtkWidget* GetDragRepresentation(const BookmarkNode* node, BookmarkModel* model, - GtkThemeProperties* properties); + GtkThemeProvider* provider); // Helper function that sets visual properties of GtkButton |button| to the // contents of |node|. void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model, - GtkWidget* button, GtkThemeProperties* properties); + GtkWidget* button, GtkThemeProvider* provider); // Returns the tooltip. std::string BuildTooltipFor(const BookmarkNode* node); @@ -49,7 +49,7 @@ const BookmarkNode* BookmarkNodeForWidget(GtkWidget* widget); // This function is a temporary hack to fix fonts on dark system themes. // TODO(estade): remove this function. -void SetButtonTextColors(GtkWidget* label, GtkThemeProperties* properties); +void SetButtonTextColors(GtkWidget* label, GtkThemeProvider* provider); // Drag and drop. -------------------------------------------------------------- diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index 03639be..453fea6 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -94,6 +94,8 @@ void BrowserToolbarGtk::Init(Profile* profile, // Make sure to tell the location bar the profile before calling its Init. SetProfile(profile); + theme_provider_ = GtkThemeProvider::GetFrom(profile); + show_home_button_.Init(prefs::kShowHomeButton, profile->GetPrefs(), this); event_box_ = gtk_event_box_new(); @@ -176,9 +178,6 @@ void BrowserToolbarGtk::Init(Profile* profile, gtk_box_pack_start(GTK_BOX(toolbar_), menus_hbox_, FALSE, FALSE, 0); - // Force all the CustomDrawButtons to load the correct rendering style. - UserChangedTheme(); - gtk_widget_show_all(event_box_); if (show_home_button_.GetValue()) { @@ -291,19 +290,6 @@ void BrowserToolbarGtk::UpdateTabContents(TabContents* contents, location_bar_->Update(should_restore_state ? contents : NULL); } -void BrowserToolbarGtk::UserChangedTheme() { - bool use_gtk = GtkThemeProvider::UseSystemThemeGraphics(profile_); - back_->SetUseSystemTheme(use_gtk); - forward_->SetUseSystemTheme(use_gtk); - reload_->SetUseSystemTheme(use_gtk); - home_->SetUseSystemTheme(use_gtk); - - gtk_chrome_button_set_use_gtk_rendering( - GTK_CHROME_BUTTON(page_menu_button_.get()), use_gtk); - gtk_chrome_button_set_use_gtk_rendering( - GTK_CHROME_BUTTON(app_menu_button_.get()), use_gtk); -} - gfx::Rect BrowserToolbarGtk::GetPopupBounds() const { GtkWidget* star = star_->widget(); GtkWidget* go = go_->widget(); @@ -328,7 +314,8 @@ gfx::Rect BrowserToolbarGtk::GetPopupBounds() const { CustomDrawButton* BrowserToolbarGtk::BuildToolbarButton( int normal_id, int active_id, int highlight_id, int depressed_id, const std::string& localized_tooltip, const char* stock_id) { - CustomDrawButton* button = new CustomDrawButton(profile_->GetThemeProvider(), + CustomDrawButton* button = new CustomDrawButton( + GtkThemeProvider::GetFrom(profile_), normal_id, active_id, highlight_id, depressed_id, stock_id); gtk_widget_set_tooltip_text(button->widget(), @@ -358,12 +345,14 @@ GtkWidget* BrowserToolbarGtk::BuildToolbarMenuButton( int icon_id, const std::string& localized_tooltip, OwnedWidgetGtk* owner) { - GtkWidget* button = gtk_chrome_button_new(); + GtkWidget* button = theme_provider_->BuildChromeButton(); owner->Own(button); ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - if (!GtkThemeProvider::UseSystemThemeGraphics(profile_)) - gtk_container_set_border_width(GTK_CONTAINER(button), 2); + // TODO(erg): This was under conditional for gtk, but after playing around + // with not having it under conditional, I actually think this is correct + // instead. Investigate more later. + gtk_container_set_border_width(GTK_CONTAINER(button), 2); gtk_container_add(GTK_CONTAINER(button), gtk_image_new_from_pixbuf(rb.GetPixbufNamed(icon_id))); diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h index fefb000..9aeee9a 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_toolbar_gtk.h @@ -18,6 +18,7 @@ class BackForwardButtonGtk; class Browser; class BrowserWindowGtk; class CustomDrawButton; +class GtkThemeProvider; class GoButtonGtk; class LocationBar; class LocationBarViewGtk; @@ -78,9 +79,6 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, ToolbarStarToggleGtk* star() { return star_.get(); } - // Alerts us that the theme changed, and we might need to change theme images. - void UserChangedTheme(); - // Implement AutocompletePopupPositioner, return the position of where the // Omnibox results popup should go (from the star to the go buttons). virtual gfx::Rect GetPopupBounds() const; @@ -179,6 +177,8 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // The model that contains the security level, text, icon to display... ToolbarModel* model_; + GtkThemeProvider* theme_provider_; + scoped_ptr<MenuGtk> page_menu_; scoped_ptr<MenuGtk> app_menu_; diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index fc5780b..8b38146 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -760,15 +760,6 @@ void BrowserWindowGtk::UserChangedTheme() { SetBackgroundColor(); gdk_window_invalidate_rect(GTK_WIDGET(window_)->window, >K_WIDGET(window_)->allocation, TRUE); - - toolbar_->UserChangedTheme(); - GtkThemeProperties properties(browser_->profile()); - bookmark_bar_->UserChangedTheme(&properties); - status_bubble_->UserChangedTheme(&properties); - tabstrip_->UserChangedTheme(&properties); - if (download_shelf_.get()) { - download_shelf_->UserChangedTheme(&properties); - } } int BrowserWindowGtk::GetExtraRenderViewHeight() const { diff --git a/chrome/browser/gtk/custom_button.cc b/chrome/browser/gtk/custom_button.cc index cbe0f94..d2e092f 100644 --- a/chrome/browser/gtk/custom_button.cc +++ b/chrome/browser/gtk/custom_button.cc @@ -9,10 +9,11 @@ #include "app/theme_provider.h" #include "base/basictypes.h" #include "base/gfx/gtk_util.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/common/notification_service.h" #include "grit/theme_resources.h" -CustomDrawButtonBase::CustomDrawButtonBase(ThemeProvider* theme_provider, +CustomDrawButtonBase::CustomDrawButtonBase(GtkThemeProvider* theme_provider, int normal_id, int active_id, int highlight_id, int depressed_id) : paint_override_(-1), normal_id_(normal_id), @@ -23,9 +24,7 @@ CustomDrawButtonBase::CustomDrawButtonBase(ThemeProvider* theme_provider, if (theme_provider) { // Load images by pretending that we got a BROWSER_THEME_CHANGED // notification. - Observe(NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources(), - NotificationService::NoDetails()); + theme_provider->InitThemesFor(this); registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, @@ -99,9 +98,12 @@ CustomDrawButton::CustomDrawButton(int normal_id, int active_id, gtk_stock_name_(stock_id), has_expose_signal_handler_(false) { Init(); + + // Initialize the theme stuff with no theme_provider. + SetBrowserTheme(NULL); } -CustomDrawButton::CustomDrawButton(ThemeProvider* theme_provider, +CustomDrawButton::CustomDrawButton(GtkThemeProvider* theme_provider, int normal_id, int active_id, int highlight_id, int depressed_id, const char* stock_id) : button_base_(theme_provider, normal_id, active_id, highlight_id, @@ -109,6 +111,11 @@ CustomDrawButton::CustomDrawButton(ThemeProvider* theme_provider, gtk_stock_name_(stock_id), has_expose_signal_handler_(false) { Init(); + + theme_provider->InitThemesFor(this); + registrar_.Add(this, + NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); } CustomDrawButton::~CustomDrawButton() { @@ -118,33 +125,15 @@ CustomDrawButton::~CustomDrawButton() { void CustomDrawButton::Init() { widget_.Own(gtk_button_new()); GTK_WIDGET_UNSET_FLAGS(widget_.get(), GTK_CAN_FOCUS); - SetUseSystemTheme(false); } -void CustomDrawButton::SetUseSystemTheme(bool use_gtk) { - if (use_gtk && gtk_stock_name_) { - gtk_button_set_image( - GTK_BUTTON(widget_.get()), - gtk_image_new_from_stock(gtk_stock_name_, 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); - - if (has_expose_signal_handler_) - gtk_signal_disconnect_by_data(GTK_OBJECT(widget_.get()), this); - has_expose_signal_handler_ = false; - } else { - gtk_widget_set_size_request(widget_.get(), - gdk_pixbuf_get_width(button_base_.pixbufs(0)), - gdk_pixbuf_get_height(button_base_.pixbufs(0))); +void CustomDrawButton::Observe(NotificationType type, + const NotificationSource& source, const NotificationDetails& details) { + DCHECK(NotificationType::BROWSER_THEME_CHANGED == type); - 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(OnCustomExpose), this); - has_expose_signal_handler_ = true; - } + GtkThemeProvider* provider = static_cast<GtkThemeProvider*>( + Source<GtkThemeProvider>(source).ptr()); + SetBrowserTheme(provider); } void CustomDrawButton::SetPaintOverride(GtkStateType state) { @@ -171,3 +160,29 @@ CustomDrawButton* CustomDrawButton::CloseButton() { IDR_CLOSE_BAR_H, 0, NULL); return button; } + +void CustomDrawButton::SetBrowserTheme(GtkThemeProvider* theme_provider) { + if (theme_provider && theme_provider->UseGtkTheme() && gtk_stock_name_) { + gtk_button_set_image( + GTK_BUTTON(widget_.get()), + gtk_image_new_from_stock(gtk_stock_name_, 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); + + if (has_expose_signal_handler_) + gtk_signal_disconnect_by_data(GTK_OBJECT(widget_.get()), this); + has_expose_signal_handler_ = false; + } else { + gtk_widget_set_size_request(widget_.get(), + gdk_pixbuf_get_width(button_base_.pixbufs(0)), + gdk_pixbuf_get_height(button_base_.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); + g_signal_connect(G_OBJECT(widget_.get()), "expose-event", + G_CALLBACK(OnCustomExpose), this); + has_expose_signal_handler_ = true; + } +} diff --git a/chrome/browser/gtk/custom_button.h b/chrome/browser/gtk/custom_button.h index 2c6bc68..4cdb9a5 100644 --- a/chrome/browser/gtk/custom_button.h +++ b/chrome/browser/gtk/custom_button.h @@ -15,7 +15,7 @@ #include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" -class ThemeProvider; +class GtkThemeProvider; // These classes implement two kinds of custom-drawn buttons. They're // used on the toolbar and the bookmarks bar. @@ -27,7 +27,7 @@ class CustomDrawButtonBase : public NotificationObserver { public: // If the images come from ResourceBundle rather than the theme provider, // pass in NULL for |theme_provider|. - CustomDrawButtonBase(ThemeProvider* theme_provider, + CustomDrawButtonBase(GtkThemeProvider* theme_provider, int normal_id, int active_id, int highlight_id, @@ -60,7 +60,7 @@ class CustomDrawButtonBase : public NotificationObserver { int active_id_; int highlight_id_; int depressed_id_; - ThemeProvider* theme_provider_; + GtkThemeProvider* theme_provider_; // Used to listen for theme change notifications. NotificationRegistrar registrar_; @@ -71,7 +71,7 @@ class CustomDrawButtonBase : public NotificationObserver { // CustomDrawButton is a plain button where all its various states are drawn // with static images. In GTK rendering mode, it will show the standard button // with GTK |stock_id|. -class CustomDrawButton { +class CustomDrawButton : public NotificationObserver { public: // The constructor takes 4 resource ids. If a resource doesn't exist for a // button, pass in 0. @@ -82,7 +82,7 @@ class CustomDrawButton { const char* stock_id); // Same as above, but uses themed (and possibly tinted) images. - CustomDrawButton(ThemeProvider* theme_provider, + CustomDrawButton(GtkThemeProvider* theme_provider, int normal_id, int active_id, int highlight_id, @@ -105,12 +105,6 @@ class CustomDrawButton { int width() const { return widget_->allocation.width; } int height() const { return widget_->allocation.height; } - // Sets properties on the GtkButton returned by widget(). By default, the - // button is very boring. This will either give it an image from the - // |gtk_stock_name_| if |use_gtk| is true or will use the chrome frame - // images. - void SetUseSystemTheme(bool use_gtk); - // Set the state to draw. We will paint the widget as if it were in this // state. void SetPaintOverride(GtkStateType state); @@ -118,10 +112,19 @@ class CustomDrawButton { // Resume normal drawing of the widget's state. void UnsetPaintOverride(); + // Provide NotificationObserver implementation. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + // Returns a standard close button. static CustomDrawButton* CloseButton(); private: + // Sets the button to themed or not. Buttons that don't take a theme_provider + // can safely pass in NULL. + void SetBrowserTheme(GtkThemeProvider* theme_provider); + // Callback for custom button expose, used to draw the custom graphics. static gboolean OnCustomExpose(GtkWidget* widget, GdkEventExpose* e, @@ -138,6 +141,9 @@ class CustomDrawButton { // Whether we have an expose signal handler we may need to remove. bool has_expose_signal_handler_; + // Used to listen for theme change notifications. + NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(CustomDrawButton); }; diff --git a/chrome/browser/gtk/download_item_gtk.cc b/chrome/browser/gtk/download_item_gtk.cc index 4e32462..d779b74 100644 --- a/chrome/browser/gtk/download_item_gtk.cc +++ b/chrome/browser/gtk/download_item_gtk.cc @@ -25,6 +25,7 @@ #include "chrome/browser/gtk/nine_box.h" #include "chrome/browser/gtk/standard_menus.h" #include "chrome/common/gtk_util.h" +#include "chrome/common/notification_service.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -169,7 +170,7 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf, BaseDownloadItemModel* download_model) : parent_shelf_(parent_shelf), menu_showing_(false), - use_gtk_colors_(GtkThemeProvider::UseSystemThemeGraphics( + theme_provider_(GtkThemeProvider::GetFrom( parent_shelf->browser()->profile())), progress_angle_(download_util::kStartAngleDegrees), download_model_(download_model), @@ -181,6 +182,7 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf, body_.Own(gtk_button_new()); gtk_widget_set_app_paintable(body_.get(), TRUE); + g_signal_connect(body_.get(), "expose-event", G_CALLBACK(OnExpose), this); g_signal_connect(body_.get(), "clicked", @@ -337,6 +339,9 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf, dangerous_hbox_start_width_ = dangerous_hbox_full_width_ - req.width; } + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); + new_item_animation_->Show(); } @@ -425,6 +430,15 @@ void DownloadItemGtk::AnimationProgressed(const Animation* animation) { } } +void DownloadItemGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::BROWSER_THEME_CHANGED) { + UpdateNameLabel(); + UpdateStatusLabel(status_label_, status_text_); + } +} + DownloadItem* DownloadItemGtk::get_download() { return download_model_->download(); } @@ -454,13 +468,6 @@ void DownloadItemGtk::StopDownloadProgress() { progress_timer_.Stop(); } -void DownloadItemGtk::UserChangedTheme(GtkThemeProperties* properties) { - use_gtk_colors_ = properties->use_gtk_rendering; - - UpdateNameLabel(); - UpdateStatusLabel(status_label_, status_text_); -} - // Icon loading functions. void DownloadItemGtk::OnLoadIconComplete(IconManager::Handle handle, @@ -480,7 +487,7 @@ void DownloadItemGtk::UpdateNameLabel() { std::wstring elided_filename = gfx::ElideFilename( get_download()->GetFileName(), gfx::Font(), kTextWidth); - if (use_gtk_colors_) { + if (theme_provider_->UseGtkTheme()) { gtk_label_set_markup(GTK_LABEL(name_label_), WideToUTF8(elided_filename).c_str()); } else { @@ -495,7 +502,7 @@ void DownloadItemGtk::UpdateNameLabel() { void DownloadItemGtk::UpdateStatusLabel(GtkWidget* status_label, const std::string& status_text) { if (status_label) { - if (use_gtk_colors_) { + if (theme_provider_->UseGtkTheme()) { gtk_label_set_label(GTK_LABEL(status_label), status_text.c_str()); } else { // TODO(erg): I am not sure which ThemeProvider color I'm supposed to use diff --git a/chrome/browser/gtk/download_item_gtk.h b/chrome/browser/gtk/download_item_gtk.h index bae5cbd..9fd94c9 100644 --- a/chrome/browser/gtk/download_item_gtk.h +++ b/chrome/browser/gtk/download_item_gtk.h @@ -7,22 +7,27 @@ #include <gtk/gtk.h> +#include <string> + #include "app/animation.h" #include "base/scoped_ptr.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/icon_manager.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" class BaseDownloadItemModel; class DownloadShelfContextMenuGtk; class DownloadShelfGtk; -class GtkThemeProperties; +class GtkThemeProvider; class NineBox; class SkBitmap; class SlideAnimation; class DownloadItemGtk : public DownloadItem::Observer, - public AnimationDelegate { + public AnimationDelegate, + public NotificationObserver { public: // DownloadItemGtk takes ownership of |download_item_model|. DownloadItemGtk(DownloadShelfGtk* parent_shelf, @@ -38,8 +43,10 @@ class DownloadItemGtk : public DownloadItem::Observer, // AnimationDelegate implementation. virtual void AnimationProgressed(const Animation* animation); - // Changes the color of the background shelf. - void UserChangedTheme(GtkThemeProperties* properties); + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); // Called when the icon manager has finished loading the icon. We take // ownership of |icon_bitmap|. @@ -143,7 +150,7 @@ class DownloadItemGtk : public DownloadItem::Observer, bool menu_showing_; // Whether we should use the GTK text color - bool use_gtk_colors_; + GtkThemeProvider* theme_provider_; // The widget that contains the animation progress and the file's icon // (as well as the complete animation). @@ -183,6 +190,8 @@ class DownloadItemGtk : public DownloadItem::Observer, // The file icon for the download. May be null. SkBitmap* icon_; + NotificationRegistrar registrar_; + // For canceling an in progress icon request. CancelableRequestConsumerT<int, 0> icon_consumer_; }; diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc index a0f523c..4d165df 100644 --- a/chrome/browser/gtk/download_shelf_gtk.cc +++ b/chrome/browser/gtk/download_shelf_gtk.cc @@ -18,6 +18,7 @@ #include "chrome/browser/gtk/slide_animator_gtk.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/gtk_util.h" +#include "chrome/common/notification_service.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -49,7 +50,8 @@ const int kShelfAnimationDurationMs = 120; DownloadShelfGtk::DownloadShelfGtk(Browser* browser, GtkWidget* parent) : DownloadShelf(browser), - is_showing_(false) { + is_showing_(false), + theme_provider_(GtkThemeProvider::GetFrom(browser->profile())) { // Logically, the shelf is a vbox that contains two children: a one pixel // tall event box, which serves as the top border, and an hbox, which holds // the download items and other shelf widgets (close button, show-all- @@ -118,8 +120,8 @@ DownloadShelfGtk::DownloadShelfGtk(Browser* browser, GtkWidget* parent) kShelfAnimationDurationMs, false, NULL)); - GtkThemeProperties properties(browser->profile()); - UserChangedTheme(&properties); + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); gtk_widget_show_all(shelf_.get()); @@ -166,18 +168,18 @@ void DownloadShelfGtk::Close() { browser_->UpdateDownloadShelfVisibility(false); } -int DownloadShelfGtk::GetHeight() const { - return slide_widget_->widget()->allocation.height; +void DownloadShelfGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::BROWSER_THEME_CHANGED) { + GdkColor color = theme_provider_->GetGdkColor( + BrowserThemeProvider::COLOR_TOOLBAR); + gtk_widget_modify_bg(padding_bg_, GTK_STATE_NORMAL, &color); + } } -void DownloadShelfGtk::UserChangedTheme(GtkThemeProperties* properties) { - GdkColor color = properties->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR); - gtk_widget_modify_bg(padding_bg_, GTK_STATE_NORMAL, &color); - - for (std::vector<DownloadItemGtk*>::iterator it = download_items_.begin(); - it != download_items_.end(); ++it) { - (*it)->UserChangedTheme(properties); - } +int DownloadShelfGtk::GetHeight() const { + return slide_widget_->widget()->allocation.height; } void DownloadShelfGtk::RemoveDownloadItem(DownloadItemGtk* download_item) { diff --git a/chrome/browser/gtk/download_shelf_gtk.h b/chrome/browser/gtk/download_shelf_gtk.h index 9c8e382..ae7923b 100644 --- a/chrome/browser/gtk/download_shelf_gtk.h +++ b/chrome/browser/gtk/download_shelf_gtk.h @@ -12,16 +12,19 @@ #include "base/gfx/native_widget_types.h" #include "base/scoped_ptr.h" #include "chrome/browser/download/download_shelf.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" class BaseDownloadItemModel; class Browser; class CustomDrawButton; class DownloadItemGtk; -class GtkThemeProperties; +class GtkThemeProvider; class SlideAnimatorGtk; -class DownloadShelfGtk : public DownloadShelf { +class DownloadShelfGtk : public DownloadShelf, + public NotificationObserver { public: explicit DownloadShelfGtk(Browser* browser, gfx::NativeView view); @@ -34,12 +37,14 @@ class DownloadShelfGtk : public DownloadShelf { virtual void Show(); virtual void Close(); + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + // Returns the current height of the shelf. int GetHeight() const; - // Changes the color of the background shelf. - void UserChangedTheme(GtkThemeProperties* properties); - private: // Remove |download_item| from the download shelf and delete it. void RemoveDownloadItem(DownloadItemGtk* download_item); @@ -78,6 +83,11 @@ class DownloadShelfGtk : public DownloadShelf { // The download items we have added to our shelf. std::vector<DownloadItemGtk*> download_items_; + // Gives us our colors and theme information. + GtkThemeProvider* theme_provider_; + + NotificationRegistrar registrar_; + friend class DownloadItemGtk; }; diff --git a/chrome/browser/gtk/go_button_gtk.cc b/chrome/browser/gtk/go_button_gtk.cc index 799b7e8..6ea9369 100644 --- a/chrome/browser/gtk/go_button_gtk.cc +++ b/chrome/browser/gtk/go_button_gtk.cc @@ -10,6 +10,7 @@ #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/profile.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -22,9 +23,9 @@ GoButtonGtk::GoButtonGtk(LocationBarViewGtk* location_bar, Browser* browser) intended_mode_(MODE_GO), visible_mode_(MODE_GO), state_(BS_NORMAL), - go_(browser ? browser->profile()->GetThemeProvider() : NULL, + go_(browser ? GtkThemeProvider::GetFrom(browser->profile()) : NULL, IDR_GO, IDR_GO_P, IDR_GO_H, 0), - stop_(browser ? browser->profile()->GetThemeProvider() : NULL, + stop_(browser ? GtkThemeProvider::GetFrom(browser->profile()) : NULL, IDR_STOP, IDR_STOP_P, IDR_STOP_H, 0), widget_(gtk_button_new()) { gtk_widget_set_size_request(widget_.get(), diff --git a/chrome/browser/gtk/gtk_theme_provider.cc b/chrome/browser/gtk/gtk_theme_provider.cc index c42a038..91136db 100644 --- a/chrome/browser/gtk/gtk_theme_provider.cc +++ b/chrome/browser/gtk/gtk_theme_provider.cc @@ -9,7 +9,12 @@ #include "base/gfx/gtk_util.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profile.h" +#include "chrome/browser/gtk/gtk_chrome_button.h" #include "chrome/common/pref_names.h" +#include "chrome/common/notification_details.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" +#include "chrome/common/notification_type.h" #include "grit/theme_resources.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -23,6 +28,11 @@ const int kToolbarImageHeight = 128; } // namespace +// static +GtkThemeProvider* GtkThemeProvider::GetFrom(Profile* profile) { + return static_cast<GtkThemeProvider*>(profile->GetThemeProvider()); +} + GtkThemeProvider::GtkThemeProvider() : BrowserThemeProvider(), fake_window_(gtk_window_new(GTK_WINDOW_TOPLEVEL)) { @@ -33,7 +43,28 @@ GtkThemeProvider::GtkThemeProvider() } GtkThemeProvider::~GtkThemeProvider() { + profile()->GetPrefs()->RemovePrefObserver(prefs::kUsesSystemTheme, this); gtk_widget_destroy(fake_window_); + + // Disconnect from the destroy signal of any redisual widgets in + // |chrome_buttons_|. + for (std::vector<GtkWidget*>::iterator it = chrome_buttons_.begin(); + it != chrome_buttons_.end(); ++it) { + gtk_signal_disconnect_by_data(GTK_OBJECT(*it), this); + } +} + +void GtkThemeProvider::Init(Profile* profile) { + profile->GetPrefs()->AddPrefObserver(prefs::kUsesSystemTheme, this); + use_gtk_ = profile->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme); + + BrowserThemeProvider::Init(profile); +} + +void GtkThemeProvider::InitThemesFor(NotificationObserver* observer) { + observer->Observe(NotificationType::BROWSER_THEME_CHANGED, + Source<ThemeProvider>(this), + NotificationService::NoDetails()); } void GtkThemeProvider::SetTheme(Extension* extension) { @@ -53,21 +84,60 @@ void GtkThemeProvider::SetNativeTheme() { NotifyThemeChanged(); } -// static -bool GtkThemeProvider::UseSystemThemeGraphics(Profile* profile) { - return profile->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme); +void GtkThemeProvider::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::PREF_CHANGED) { + std::wstring key = *Details<std::wstring>(details).ptr(); + if (key == prefs::kUsesSystemTheme) { + use_gtk_ = profile()->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme); + } + } +} + +GtkWidget* GtkThemeProvider::BuildChromeButton() { + GtkWidget* button = gtk_chrome_button_new(); + gtk_chrome_button_set_use_gtk_rendering(GTK_CHROME_BUTTON(button), use_gtk_); + chrome_buttons_.push_back(button); + + g_signal_connect(button, "destroy", G_CALLBACK(OnDestroyChromeButton), + this); + return button; +} + +bool GtkThemeProvider::UseGtkTheme() { + return use_gtk_; +} + +GdkColor GtkThemeProvider::GetGdkColor(int id) { + SkColor color = GetColor(id); + GdkColor gdkcolor = + GDK_COLOR_RGB(SkColorGetR(color), SkColorGetG(color), + SkColorGetB(color)); + return gdkcolor; } void GtkThemeProvider::LoadThemePrefs() { - if (profile()->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme)) { + if (use_gtk_) { LoadGtkValues(); } else { BrowserThemeProvider::LoadThemePrefs(); } } +void GtkThemeProvider::NotifyThemeChanged() { + BrowserThemeProvider::NotifyThemeChanged(); + + // Notify all constructored GtkChromeButtons of their new rendering mode: + for (std::vector<GtkWidget*>::iterator it = chrome_buttons_.begin(); + it != chrome_buttons_.end(); ++it) { + gtk_chrome_button_set_use_gtk_rendering( + GTK_CHROME_BUTTON(*it), use_gtk_); + } +} + SkBitmap* GtkThemeProvider::LoadThemeBitmap(int id) { - if (id == IDR_THEME_TOOLBAR && UseSystemThemeGraphics(profile())) { + if (id == IDR_THEME_TOOLBAR && use_gtk_) { GtkStyle* style = gtk_rc_get_style(fake_window_); GdkColor* color = &style->bg[GTK_STATE_NORMAL]; SkBitmap* bitmap = new SkBitmap; @@ -95,38 +165,38 @@ void GtkThemeProvider::OnStyleSet(GtkWidget* widget, void GtkThemeProvider::LoadGtkValues() { GtkStyle* style = gtk_rc_get_style(fake_window_); - SetThemeColorFromGtk(themes::kColorFrame, &style->bg[GTK_STATE_SELECTED]); + SetThemeColorFromGtk(kColorFrame, &style->bg[GTK_STATE_SELECTED]); // Skip COLOR_FRAME_INACTIVE and the incognito colors, as they will be // autogenerated from tints. - SetThemeColorFromGtk(themes::kColorToolbar, + SetThemeColorFromGtk(kColorToolbar, &style->bg[GTK_STATE_NORMAL]); - SetThemeColorFromGtk(themes::kColorTabText, + SetThemeColorFromGtk(kColorTabText, &style->text[GTK_STATE_NORMAL]); - SetThemeColorFromGtk(themes::kColorBackgroundTabText, + SetThemeColorFromGtk(kColorBackgroundTabText, &style->text[GTK_STATE_NORMAL]); - SetThemeColorFromGtk(themes::kColorBookmarkText, + SetThemeColorFromGtk(kColorBookmarkText, &style->text[GTK_STATE_NORMAL]); - SetThemeColorFromGtk(themes::kColorControlBackground, + SetThemeColorFromGtk(kColorControlBackground, &style->bg[GTK_STATE_NORMAL]); - SetThemeColorFromGtk(themes::kColorButtonBackground, + SetThemeColorFromGtk(kColorButtonBackground, &style->bg[GTK_STATE_NORMAL]); - SetThemeTintFromGtk(themes::kTintButtons, &style->bg[GTK_STATE_SELECTED], - themes::kDefaultTintButtons); - SetThemeTintFromGtk(themes::kTintFrame, &style->bg[GTK_STATE_SELECTED], - themes::kDefaultTintFrame); - SetThemeTintFromGtk(themes::kTintFrameInactive, + SetThemeTintFromGtk(kTintButtons, &style->bg[GTK_STATE_SELECTED], + kDefaultTintButtons); + SetThemeTintFromGtk(kTintFrame, &style->bg[GTK_STATE_SELECTED], + kDefaultTintFrame); + SetThemeTintFromGtk(kTintFrameInactive, &style->bg[GTK_STATE_SELECTED], - themes::kDefaultTintFrameInactive); - SetThemeTintFromGtk(themes::kTintFrameIncognito, + kDefaultTintFrameInactive); + SetThemeTintFromGtk(kTintFrameIncognito, &style->bg[GTK_STATE_SELECTED], - themes::kDefaultTintFrameIncognito); - SetThemeTintFromGtk(themes::kTintFrameIncognitoInactive, + kDefaultTintFrameIncognito); + SetThemeTintFromGtk(kTintFrameIncognitoInactive, &style->bg[GTK_STATE_SELECTED], - themes::kDefaultTintFrameIncognitoInactive); - SetThemeTintFromGtk(themes::kTintBackgroundTab, + kDefaultTintFrameIncognitoInactive); + SetThemeTintFromGtk(kTintBackgroundTab, &style->bg[GTK_STATE_SELECTED], - themes::kDefaultTintBackgroundTab); + kDefaultTintBackgroundTab); GenerateFrameColors(); GenerateFrameImages(); @@ -152,15 +222,11 @@ void GtkThemeProvider::SetThemeTintFromGtk(const char* id, GdkColor* color, SetTint(id, hsl); } -GtkThemeProperties::GtkThemeProperties(Profile* profile) - : use_gtk_rendering(GtkThemeProvider::UseSystemThemeGraphics(profile)), - provider(profile->GetThemeProvider()) { -} - -GdkColor GtkThemeProperties::GetGdkColor(int id) { - SkColor color = provider->GetColor(id); - GdkColor gdkcolor = - GDK_COLOR_RGB(SkColorGetR(color), SkColorGetG(color), - SkColorGetB(color)); - return gdkcolor; +void GtkThemeProvider::OnDestroyChromeButton(GtkWidget* button, + GtkThemeProvider* provider) { + std::vector<GtkWidget*>::iterator it = + find(provider->chrome_buttons_.begin(), provider->chrome_buttons_.end(), + button); + if (it != provider->chrome_buttons_.end()) + provider->chrome_buttons_.erase(it); } diff --git a/chrome/browser/gtk/gtk_theme_provider.h b/chrome/browser/gtk/gtk_theme_provider.h index 408ba0c..ae3537e 100644 --- a/chrome/browser/gtk/gtk_theme_provider.h +++ b/chrome/browser/gtk/gtk_theme_provider.h @@ -5,7 +5,10 @@ #ifndef CHROME_BROWSER_GTK_GTK_THEME_PROVIDER_H_ #define CHROME_BROWSER_GTK_GTK_THEME_PROVIDER_H_ +#include <vector> + #include "chrome/browser/browser_theme_provider.h" +#include "chrome/common/notification_observer.h" #include "skia/ext/skia_utils.h" @@ -15,26 +18,52 @@ typedef struct _GtkStyle GtkStyle; typedef struct _GtkWidget GtkWidget; // Specialization of BrowserThemeProvider which supplies system colors. -class GtkThemeProvider : public BrowserThemeProvider { +class GtkThemeProvider : public BrowserThemeProvider, + public NotificationObserver { public: + // Returns GtkThemeProvider, casted from our superclass. + static GtkThemeProvider* GetFrom(Profile* profile); + GtkThemeProvider(); virtual ~GtkThemeProvider(); + // Calls |observer|.Observe() for the browser theme with this provider as the + // source. + void InitThemesFor(NotificationObserver* observer); + // Overridden from BrowserThemeProvider: // // Sets that we aren't using the system theme, then calls // BrowserThemeProvider's implementation. + virtual void Init(Profile* profile); virtual void SetTheme(Extension* extension); virtual void UseDefaultTheme(); virtual void SetNativeTheme(); + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Creates a GtkChromeButton instance, registered with this theme provider, + // with a "destroy" signal to remove it from our internal list when it goes + // away. + GtkWidget* BuildChromeButton(); + // Whether we should use the GTK system theme. - static bool UseSystemThemeGraphics(Profile* profile); + bool UseGtkTheme(); + + // A wrapper around ThemeProvider::GetColor, transforming the result to a + // GdkColor. + GdkColor GetGdkColor(int id); private: // Load theme data from preferences, possibly picking colors from GTK. virtual void LoadThemePrefs(); + // Let all the browser views know that themes have changed. + virtual void NotifyThemeChanged(); + // Possibly creates a theme specific version of theme_toolbar_default. // (minimally acceptable version right now, which is just a fill of the bg // color; this should instead invoke gtk_draw_box(...) for complex theme @@ -53,25 +82,21 @@ class GtkThemeProvider : public BrowserThemeProvider { void SetThemeTintFromGtk(const char* id, GdkColor* color, const skia::HSL& default_tint); + // A notification from the GtkChromeButton GObject destructor that we should + // remove it from our internal list. + static void OnDestroyChromeButton(GtkWidget* button, + GtkThemeProvider* provider); + + // Whether we should be using gtk rendering. + bool use_gtk_; + // A GtkWidget that exists only so we can look at its properties (and take // its colors). GtkWidget* fake_window_; -}; - -// A Helper struct used throughout the GTK themeing code. It retrieves settings -// from the Profile once at creation time, instead of at every access time. A -// large motivation for making this struct is so that we only have to pass one -// parameter around when configuring things due to a theme event. This way, we -// can use a lot of GTK convenience features likt gtk_container_foreach(). -struct GtkThemeProperties { - GtkThemeProperties(Profile* profile); - - // A wrapper around ThemeProvider::GetColor, transforming the result to a - // GdkColor. - GdkColor GetGdkColor(int id); - bool use_gtk_rendering; - ThemeProvider* provider; + // A list of all GtkChromeButton instances. We hold on to these to notify + // them of theme changes. + std::vector<GtkWidget*> chrome_buttons_; }; #endif // CHROME_BROWSER_GTK_GTK_THEME_PROVIDER_H_ diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc index fe4f548..08eb6fc 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/gtk/location_bar_view_gtk.cc @@ -163,17 +163,14 @@ void LocationBarViewGtk::Init() { gtk_box_pack_start(GTK_BOX(hbox_.get()), tab_to_search_, FALSE, FALSE, 0); GtkWidget* align = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); - // TODO(erg): Redo this so that it adjusts during theme changes. - if (GtkThemeProvider::UseSystemThemeGraphics(profile_)) { - gtk_alignment_set_padding(GTK_ALIGNMENT(align), - 0, 0, - kEditLeftRightPadding, kEditLeftRightPadding); - } else { - gtk_alignment_set_padding(GTK_ALIGNMENT(align), - kTopMargin + kBorderThickness, - kBottomMargin + kBorderThickness, - kEditLeftRightPadding, kEditLeftRightPadding); - } + // TODO(erg): Like in BrowserToolbarGtk, this used to have a code path on + // construction for with GTK themes and without. Doing that only on + // construction was wrong, and I can't see a difference between the two ways + // anyway... Investigate more later. + gtk_alignment_set_padding(GTK_ALIGNMENT(align), + kTopMargin + kBorderThickness, + kBottomMargin + kBorderThickness, + kEditLeftRightPadding, kEditLeftRightPadding); gtk_container_add(GTK_CONTAINER(align), location_entry_->widget()); gtk_box_pack_start(GTK_BOX(hbox_.get()), align, TRUE, TRUE, 0); diff --git a/chrome/browser/gtk/status_bubble_gtk.cc b/chrome/browser/gtk/status_bubble_gtk.cc index 920803e..70e2702 100644 --- a/chrome/browser/gtk/status_bubble_gtk.cc +++ b/chrome/browser/gtk/status_bubble_gtk.cc @@ -12,6 +12,7 @@ #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/slide_animator_gtk.h" #include "chrome/common/gtk_util.h" +#include "chrome/common/notification_service.h" #include "googleurl/src/gurl.h" namespace { @@ -33,11 +34,12 @@ static const int kHideDelay = 250; } // namespace StatusBubbleGtk::StatusBubbleGtk(Profile* profile) - : timer_factory_(this) { + : theme_provider_(GtkThemeProvider::GetFrom(profile)), + timer_factory_(this) { InitWidgets(); - GtkThemeProperties properties(profile); - UserChangedTheme(&properties); + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); } StatusBubbleGtk::~StatusBubbleGtk() { @@ -115,6 +117,14 @@ void StatusBubbleGtk::MouseMoved() { // the way to hide the status bubble on mouseover. } +void StatusBubbleGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::BROWSER_THEME_CHANGED) { + UserChangedTheme(); + } +} + void StatusBubbleGtk::InitWidgets() { label_ = gtk_label_new(NULL); @@ -131,10 +141,12 @@ void StatusBubbleGtk::InitWidgets() { kBorderPadding, kBorderPadding, kBorderPadding, kBorderPadding)); gtk_widget_set_name(container_.get(), "status-bubble"); gtk_widget_set_app_paintable(container_.get(), TRUE); + + UserChangedTheme(); } -void StatusBubbleGtk::UserChangedTheme(GtkThemeProperties* properties) { - if (properties->use_gtk_rendering) { +void StatusBubbleGtk::UserChangedTheme() { + if (theme_provider_->UseGtkTheme()) { gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, NULL); gtk_widget_modify_bg(bg_box_, GTK_STATE_NORMAL, NULL); } else { @@ -142,11 +154,11 @@ void StatusBubbleGtk::UserChangedTheme(GtkThemeProperties* properties) { // toolbar" that I can find. Maybe in later iterations of the theme system, // there will be a better color to pick. GdkColor bookmark_text = - properties->GetGdkColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT); + theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT); gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, &bookmark_text); GdkColor toolbar_color = - properties->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR); + theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR); gtk_widget_modify_bg(bg_box_, GTK_STATE_NORMAL, &toolbar_color); } diff --git a/chrome/browser/gtk/status_bubble_gtk.h b/chrome/browser/gtk/status_bubble_gtk.h index 0ede1f9..f5847aa 100644 --- a/chrome/browser/gtk/status_bubble_gtk.h +++ b/chrome/browser/gtk/status_bubble_gtk.h @@ -12,9 +12,11 @@ #include "base/scoped_ptr.h" #include "base/task.h" #include "chrome/browser/status_bubble.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" -class GtkThemeProperties; +class GtkThemeProvider; class GURL; class Profile; @@ -22,9 +24,10 @@ class Profile; // doesn't have the nice leave-the-window effect since we can't rely on the // window manager to not try to be "helpful" and center our popups, etc. // We therefore position it absolutely in a GtkFixed, that we don't own. -class StatusBubbleGtk : public StatusBubble { +class StatusBubbleGtk : public StatusBubble, + public NotificationObserver { public: - StatusBubbleGtk(Profile* profile); + explicit StatusBubbleGtk(Profile* profile); virtual ~StatusBubbleGtk(); // StatusBubble implementation. @@ -38,14 +41,16 @@ class StatusBubbleGtk : public StatusBubble { // the download shelf, when it is visible. virtual void UpdateDownloadShelfVisibility(bool visible) { } + // Overridden from NotificationObserver: + void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + // Top of the widget hierarchy for a StatusBubble. This top level widget is // guarenteed to have its gtk_widget_name set to "status-bubble" for // identification. GtkWidget* widget() { return container_.get(); } - // Notification from the window that we should retheme ourself. - void UserChangedTheme(GtkThemeProperties* properties); - private: // Sets the text of the label widget and controls visibility. (As contrasted // with setting the current status or URL text, which may be ignored for now). @@ -61,6 +66,14 @@ class StatusBubbleGtk : public StatusBubble { // Builds the widgets, containers, etc. void InitWidgets(); + // Notification from the window that we should retheme ourself. + void UserChangedTheme(); + + NotificationRegistrar registrar_; + + // Provides colors. + GtkThemeProvider* theme_provider_; + // A GtkAlignment that is the child of |slide_widget_|. OwnedWidgetGtk container_; diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc index b7e549d..e86df4e 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc @@ -20,6 +20,8 @@ #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/gtk_util.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" #include "grit/app_resources.h" #include "grit/theme_resources.h" @@ -658,13 +660,12 @@ TabStripGtk::TabStripGtk(TabStripModel* model) available_width_for_tabs_(-1), resize_layout_scheduled_(false), model_(model), + theme_provider_(GtkThemeProvider::GetFrom(model->profile())), resize_layout_factory_(this), added_as_message_loop_observer_(false) { - ThemeProvider* theme_provider = model->profile()->GetThemeProvider(); - TabRendererGtk::SetSelectedTitleColor(theme_provider->GetColor( - BrowserThemeProvider::COLOR_TAB_TEXT)); - TabRendererGtk::SetUnselectedTitleColor(theme_provider->GetColor( - BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT)); + theme_provider_->InitThemesFor(this); + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); } TabStripGtk::~TabStripGtk() { @@ -854,14 +855,6 @@ gfx::Point TabStripGtk::GetTabStripOriginForWidget(GtkWidget* target) { return gfx::Point(x, y); } -void TabStripGtk::UserChangedTheme(GtkThemeProperties* properties) { - ThemeProvider* theme_provider = properties->provider; - TabRendererGtk::SetSelectedTitleColor(theme_provider->GetColor( - BrowserThemeProvider::COLOR_TAB_TEXT)); - TabRendererGtk::SetUnselectedTitleColor(theme_provider->GetColor( - BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT)); -} - //////////////////////////////////////////////////////////////////////////////// // TabStripGtk, TabStripModelObserver implementation: @@ -1113,6 +1106,17 @@ void TabStripGtk::DidProcessEvent(GdkEvent* event) { } } +void TabStripGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::BROWSER_THEME_CHANGED) { + TabRendererGtk::SetSelectedTitleColor(theme_provider_->GetColor( + BrowserThemeProvider::COLOR_TAB_TEXT)); + TabRendererGtk::SetUnselectedTitleColor(theme_provider_->GetColor( + BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT)); + } +} + //////////////////////////////////////////////////////////////////////////////// // TabStripGtk, private: diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h index 91b83f0..44bc870 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.h +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h @@ -14,15 +14,17 @@ #include "base/message_loop.h" #include "chrome/browser/gtk/tabs/tab_gtk.h" #include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/common/notification_observer.h" #include "chrome/common/owned_widget_gtk.h" class CustomDrawButton; class DraggedTabControllerGtk; -class GtkThemeProperties; +class GtkThemeProvider; class TabStripGtk : public TabStripModelObserver, public TabGtk::TabDelegate, - public MessageLoopForUI::Observer { + public MessageLoopForUI::Observer, + public NotificationObserver { public: class TabAnimation; @@ -84,9 +86,6 @@ class TabStripGtk : public TabStripModelObserver, // allocated. gfx::Point GetTabStripOriginForWidget(GtkWidget* widget); - // Alerts us that the theme changed, and we might need to change theme images. - void UserChangedTheme(GtkThemeProperties* properties); - protected: // TabStripModelObserver implementation: virtual void TabInsertedAt(TabContents* contents, @@ -127,6 +126,11 @@ class TabStripGtk : public TabStripModelObserver, virtual void WillProcessEvent(GdkEvent* event); virtual void DidProcessEvent(GdkEvent* event); + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + private: friend class DraggedTabControllerGtk; friend class InsertTabAnimation; @@ -364,6 +368,8 @@ class TabStripGtk : public TabStripModelObserver, TabStripGtk* tabstrip); #endif + NotificationRegistrar registrar_; + // The Tabs we contain, and their last generated "good" bounds. std::vector<TabData> tab_data_; @@ -397,6 +403,9 @@ class TabStripGtk : public TabStripModelObserver, // Our model. TabStripModel* model_; + // Theme resources. + GtkThemeProvider* theme_provider_; + // The currently running animation. scoped_ptr<TabAnimation> active_animation_; diff --git a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc index 2692df7..0fd1045 100644 --- a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc +++ b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc @@ -8,6 +8,7 @@ #include "base/gfx/rect.h" #include "chrome/browser/gtk/bookmark_bubble_gtk.h" #include "chrome/browser/gtk/browser_toolbar_gtk.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/profile.h" #include "grit/theme_resources.h" @@ -15,10 +16,10 @@ ToolbarStarToggleGtk::ToolbarStarToggleGtk(BrowserToolbarGtk* host) : host_(host), widget_(gtk_button_new()), is_starred_(false), - unstarred_(host->profile()->GetThemeProvider(), IDR_STAR, IDR_STAR_P, - IDR_STAR_H, IDR_STAR_D), - starred_(host->profile()->GetThemeProvider(), IDR_STARRED, IDR_STARRED_P, - IDR_STARRED_H, 0) { + 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) { gtk_widget_set_size_request(widget_.get(), gdk_pixbuf_get_width(unstarred_.pixbufs(0)), gdk_pixbuf_get_height(unstarred_.pixbufs(0))); diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index 4b829fa..52c0bfe 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -357,8 +357,6 @@ TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) gtk_widget_show(floating_.get()); registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, Source<TabContents>(tab_contents)); - registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources()); } TabContentsViewGtk::~TabContentsViewGtk() { @@ -579,11 +577,6 @@ void TabContentsViewGtk::Observe(NotificationType type, sad_tab_.reset(); break; } - case NotificationType::BROWSER_THEME_CHANGED: { - GtkThemeProperties properties(tab_contents()->profile()); - UserChangedTheme(&properties); - break; - } default: NOTREACHED() << "Got a notification we didn't register for."; break; @@ -701,15 +694,6 @@ void TabContentsViewGtk::OnDragEnd(GtkWidget* widget, // ----------------------------------------------------------------------------- -void TabContentsViewGtk::UserChangedTheme(GtkThemeProperties* properties) { - if (popup_view_) - popup_view_->UserChangedTheme(properties); - - // TODO(erg): Plumb the selected text color, etc from here all the way to - // RenderThemeChromiumLinux.cpp in WebKit through our associated - // RenderViewHost. -} - void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) { gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0); } diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h index aa440d9..552724e 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.h +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h @@ -86,9 +86,6 @@ class TabContentsViewGtk : public TabContentsView, // Tell webkit the drag is over. void DragEnded(); - // Called when the theme is changed. - void UserChangedTheme(GtkThemeProperties* properties); - // We keep track of the timestamp of the latest mousedown event. static gboolean OnMouseDown(GtkWidget* widget, GdkEventButton* event, TabContentsViewGtk* view); |