Index: chrome/browser/gtk/gtk_theme_provider.cc |
diff --git a/chrome/browser/gtk/gtk_theme_provider.cc b/chrome/browser/gtk/gtk_theme_provider.cc |
index 4f3511021fb384baa336576a0b295020bed1a5ee..9330f303cca946007128c1bee7ba85db85f59b17 100644 |
--- a/chrome/browser/gtk/gtk_theme_provider.cc |
+++ b/chrome/browser/gtk/gtk_theme_provider.cc |
@@ -8,6 +8,8 @@ |
#include "app/gfx/color_utils.h" |
#include "app/gfx/gtk_util.h" |
+#include "app/gfx/skbitmap_operations.h" |
+#include "base/stl_util-inl.h" |
#include "chrome/browser/metrics/user_metrics.h" |
#include "chrome/browser/profile.h" |
#include "chrome/browser/gtk/cairo_cached_surface.h" |
@@ -57,6 +59,26 @@ SkColor GdkToSkColor(GdkColor* color) { |
color->blue >> 8); |
} |
+// A list of images that we provide while in gtk mode. |
+const int kThemeImages[] = { |
+ IDR_THEME_TOOLBAR, |
+ IDR_THEME_TAB_BACKGROUND, |
+ IDR_THEME_TAB_BACKGROUND_INCOGNITO, |
+ IDR_THEME_FRAME, |
+ IDR_THEME_FRAME_INACTIVE, |
+ IDR_THEME_FRAME_INCOGNITO, |
+ IDR_THEME_FRAME_INCOGNITO_INACTIVE, |
+}; |
+ |
+bool IsOverridableImage(int id) { |
+ for (size_t i = 0; i < arraysize(kThemeImages); ++i) { |
+ if (kThemeImages[i] == id) |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
} // namespace |
GtkWidget* GtkThemeProvider::icon_widget_ = NULL; |
@@ -84,9 +106,9 @@ GtkThemeProvider::~GtkThemeProvider() { |
gtk_widget_destroy(fake_window_); |
fake_label_.Destroy(); |
- // We have to call this because ClearCaches in ~BrowserThemeProvider doesn't |
- // call the right virutal FreePlatformCaches. |
- FreePerDisplaySurfaces(); |
+ // We have to call this because FreePlatformCached() in ~BrowserThemeProvider |
+ // doesn't call the right virutal FreePlatformCaches. |
+ FreePlatformCaches(); |
// Disconnect from the destroy signal of any redisual widgets in |
// |chrome_buttons_|. |
@@ -103,6 +125,39 @@ void GtkThemeProvider::Init(Profile* profile) { |
BrowserThemeProvider::Init(profile); |
} |
+SkBitmap* GtkThemeProvider::GetBitmapNamed(int id) const { |
+ if (use_gtk_ && IsOverridableImage(id)) { |
+ // Try to get our cached version: |
+ ImageCache::const_iterator it = gtk_images_.find(id); |
+ if (it != gtk_images_.end()) |
+ return it->second; |
+ |
+ // We haven't built this image yet: |
+ SkBitmap* bitmap = GenerateGtkThemeBitmap(id); |
+ gtk_images_[id] = bitmap; |
+ return bitmap; |
+ } |
+ |
+ return BrowserThemeProvider::GetBitmapNamed(id); |
+} |
+ |
+SkColor GtkThemeProvider::GetColor(int id) const { |
+ if (use_gtk_) { |
+ ColorMap::const_iterator it = colors_.find(id); |
+ if (it != colors_.end()) |
+ return it->second; |
+ } |
+ |
+ return BrowserThemeProvider::GetColor(id); |
+} |
+ |
+bool GtkThemeProvider::HasCustomImage(int id) const { |
+ if (use_gtk_) |
+ return IsOverridableImage(id); |
+ |
+ return BrowserThemeProvider::HasCustomImage(id); |
+} |
+ |
void GtkThemeProvider::InitThemesFor(NotificationObserver* observer) { |
observer->Observe(NotificationType::BROWSER_THEME_CHANGED, |
Source<ThemeProvider>(this), |
@@ -345,40 +400,10 @@ void GtkThemeProvider::NotifyThemeChanged() { |
} |
} |
-SkBitmap* GtkThemeProvider::LoadThemeBitmap(int id) const { |
- if (use_gtk_) { |
- if (id == IDR_THEME_TOOLBAR) { |
- GtkStyle* style = gtk_rc_get_style(fake_window_); |
- GdkColor* color = &style->bg[GTK_STATE_NORMAL]; |
- SkBitmap* bitmap = new SkBitmap; |
- bitmap->setConfig(SkBitmap::kARGB_8888_Config, |
- kToolbarImageWidth, kToolbarImageHeight); |
- bitmap->allocPixels(); |
- bitmap->eraseRGB(color->red >> 8, color->green >> 8, color->blue >> 8); |
- return bitmap; |
- } |
- if ((id == IDR_THEME_TAB_BACKGROUND) || |
- (id == IDR_THEME_TAB_BACKGROUND_INCOGNITO)) |
- return GenerateTabBackgroundBitmapImpl(id); |
- } |
- |
- return BrowserThemeProvider::LoadThemeBitmap(id); |
-} |
- |
-void GtkThemeProvider::SaveThemeBitmap(const std::string resource_name, |
- int id) const { |
- if (!use_gtk_) { |
- // Prevent us from writing out our mostly unused resources in gtk theme |
- // mode. Simply preventing us from writing this data out in gtk mode isn't |
- // the best design, but this would probably be a very invasive change on |
- // all three platforms otherwise. |
- BrowserThemeProvider::SaveThemeBitmap(resource_name, id); |
- } |
-} |
- |
void GtkThemeProvider::FreePlatformCaches() { |
BrowserThemeProvider::FreePlatformCaches(); |
FreePerDisplaySurfaces(); |
+ STLDeleteValues(>k_images_); |
} |
// static |
@@ -475,34 +500,35 @@ void GtkThemeProvider::LoadGtkValues() { |
} |
} |
- SetThemeColorFromGtk(kColorFrame, &frame_color); |
+ SetThemeTintFromGtk(BrowserThemeProvider::TINT_BUTTONS, &button_color); |
+ SetThemeTintFromGtk(BrowserThemeProvider::TINT_FRAME, &frame_color); |
+ SetThemeTintFromGtk(BrowserThemeProvider::TINT_FRAME_INCOGNITO, &frame_color); |
+ SetThemeTintFromGtk(BrowserThemeProvider::TINT_BACKGROUND_TAB, &frame_color); |
+ |
+ SetThemeColorFromGtk(BrowserThemeProvider::COLOR_FRAME, &frame_color); |
+ BuildTintedFrameColor(BrowserThemeProvider::COLOR_FRAME_INACTIVE, |
+ BrowserThemeProvider::TINT_FRAME_INACTIVE); |
+ BuildTintedFrameColor(BrowserThemeProvider::COLOR_FRAME_INCOGNITO, |
+ BrowserThemeProvider::TINT_FRAME_INCOGNITO); |
+ BuildTintedFrameColor(BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE, |
+ BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); |
+ |
// Skip COLOR_FRAME_INACTIVE and the incognito colors, as they will be |
- // autogenerated from tints. |
- SetThemeColorFromGtk(kColorToolbar, &toolbar_color); |
- SetThemeColorFromGtk(kColorTabText, &label_color); |
- SetThemeColorFromGtk(kColorBookmarkText, &label_color); |
- SetThemeColorFromGtk(kColorControlBackground, |
+ // autogenerated from tints. TODO(erg): Still true? |
+ SetThemeColorFromGtk(BrowserThemeProvider::COLOR_TOOLBAR, &toolbar_color); |
+ SetThemeColorFromGtk(BrowserThemeProvider::COLOR_TAB_TEXT, &label_color); |
+ SetThemeColorFromGtk(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, &label_color); |
+ SetThemeColorFromGtk(BrowserThemeProvider::COLOR_CONTROL_BACKGROUND, |
&window_style->bg[GTK_STATE_NORMAL]); |
- SetThemeColorFromGtk(kColorButtonBackground, |
+ SetThemeColorFromGtk(BrowserThemeProvider::COLOR_BUTTON_BACKGROUND, |
&window_style->bg[GTK_STATE_NORMAL]); |
- SetThemeTintFromGtk(kTintButtons, &button_color, |
- kDefaultTintButtons); |
- SetThemeTintFromGtk(kTintFrame, &frame_color, |
- kDefaultTintFrame); |
- SetThemeTintFromGtk(kTintFrameIncognito, |
- &frame_color, |
- kDefaultTintFrameIncognito); |
- SetThemeTintFromGtk(kTintBackgroundTab, |
- &frame_color, |
- kDefaultTintBackgroundTab); |
- |
// The inactive frame color never occurs naturally in the theme, as it is a |
// tinted version of |frame_color|. We generate another color based on the |
// background tab color, with the lightness and saturation moved in the |
// opposite direction. (We don't touch the hue, since there should be subtle |
// hints of the color in the text.) |
- color_utils::HSL inactive_tab_text_hsl = GetTint(TINT_BACKGROUND_TAB); |
+ color_utils::HSL inactive_tab_text_hsl = tints_[TINT_BACKGROUND_TAB]; |
if (inactive_tab_text_hsl.l < 0.5) |
inactive_tab_text_hsl.l = kDarkInactiveLuminance; |
else |
@@ -513,32 +539,26 @@ void GtkThemeProvider::LoadGtkValues() { |
else |
inactive_tab_text_hsl.s = kLightInactiveSaturation; |
- SetColor(kColorBackgroundTabText, |
- color_utils::HSLToSkColor(inactive_tab_text_hsl, 255)); |
+ colors_[BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT] = |
+ color_utils::HSLToSkColor(inactive_tab_text_hsl, 255); |
// The inactive color/tint is special: We *must* use the exact insensitive |
// color for all inactive windows, otherwise we end up neon pink half the |
// time. |
- SetThemeColorFromGtk(kColorFrameInactive, &inactive_frame_color); |
- SetThemeTintFromGtk(kTintFrameInactive, &inactive_frame_color, |
- kExactColor); |
- SetThemeTintFromGtk(kTintFrameIncognitoInactive, &inactive_frame_color, |
- kExactColor); |
- |
- force_process_images(); |
- GenerateFrameColors(); |
- AutoLock lock(themed_image_cache_lock_); |
- GenerateFrameImages(); |
+ SetThemeColorFromGtk(BrowserThemeProvider::COLOR_FRAME_INACTIVE, |
+ &inactive_frame_color); |
+ SetTintToExactColor(BrowserThemeProvider::TINT_FRAME_INACTIVE, |
+ &inactive_frame_color); |
+ SetTintToExactColor(BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE, |
+ &inactive_frame_color); |
} |
-void GtkThemeProvider::SetThemeColorFromGtk(const char* id, GdkColor* color) { |
- SetColor(id, GdkToSkColor(color)); |
+void GtkThemeProvider::SetThemeColorFromGtk(int id, GdkColor* color) { |
+ colors_[id] = GdkToSkColor(color); |
} |
-void GtkThemeProvider::SetThemeTintFromGtk( |
- const char* id, |
- GdkColor* color, |
- const color_utils::HSL& default_tint) { |
+void GtkThemeProvider::SetThemeTintFromGtk(int id, GdkColor* color) { |
+ color_utils::HSL default_tint = GetDefaultTint(id); |
color_utils::HSL hsl; |
color_utils::SkColorToHSL(GdkToSkColor(color), &hsl); |
@@ -547,7 +567,19 @@ void GtkThemeProvider::SetThemeTintFromGtk( |
if (default_tint.l != -1) |
hsl.l = default_tint.l; |
- SetTint(id, hsl); |
+ |
+ tints_[id] = hsl; |
+} |
+ |
+void GtkThemeProvider::BuildTintedFrameColor(int color_id, int tint_id) { |
+ colors_[color_id] = HSLShift(colors_[BrowserThemeProvider::COLOR_FRAME], |
+ tints_[tint_id]); |
+} |
+ |
+void GtkThemeProvider::SetTintToExactColor(int id, GdkColor* color) { |
+ color_utils::HSL hsl; |
+ color_utils::SkColorToHSL(GdkToSkColor(color), &hsl); |
+ tints_[id] = hsl; |
} |
void GtkThemeProvider::FreePerDisplaySurfaces() { |
@@ -561,6 +593,55 @@ void GtkThemeProvider::FreePerDisplaySurfaces() { |
per_display_surfaces_.clear(); |
} |
+SkBitmap* GtkThemeProvider::GenerateGtkThemeBitmap(int id) const { |
+ switch (id) { |
+ case IDR_THEME_TOOLBAR: { |
+ GtkStyle* style = gtk_rc_get_style(fake_window_); |
+ GdkColor* color = &style->bg[GTK_STATE_NORMAL]; |
+ SkBitmap* bitmap = new SkBitmap; |
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config, |
+ kToolbarImageWidth, kToolbarImageHeight); |
+ bitmap->allocPixels(); |
+ bitmap->eraseRGB(color->red >> 8, color->green >> 8, color->blue >> 8); |
+ return bitmap; |
+ } |
+ case IDR_THEME_TAB_BACKGROUND: |
+ return GenerateTabImage(IDR_THEME_FRAME); |
+ case IDR_THEME_TAB_BACKGROUND_INCOGNITO: |
+ return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO); |
+ case IDR_THEME_FRAME: |
+ return GenerateFrameImage(BrowserThemeProvider::TINT_FRAME); |
+ case IDR_THEME_FRAME_INACTIVE: |
+ return GenerateFrameImage(BrowserThemeProvider::TINT_FRAME_INACTIVE); |
+ case IDR_THEME_FRAME_INCOGNITO: |
+ return GenerateFrameImage(BrowserThemeProvider::TINT_FRAME_INCOGNITO); |
+ case IDR_THEME_FRAME_INCOGNITO_INACTIVE: { |
+ return GenerateFrameImage( |
+ BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); |
+ } |
+ } |
+ |
+ NOTREACHED() << "Invalid bitmap request " << id; |
+ return NULL; |
+} |
+ |
+SkBitmap* GtkThemeProvider::GenerateFrameImage(int tint_id) const { |
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
+ scoped_ptr<SkBitmap> frame(new SkBitmap(*rb.GetBitmapNamed(IDR_THEME_FRAME))); |
+ TintMap::const_iterator it = tints_.find(tint_id); |
+ DCHECK(it != tints_.end()); |
+ return new SkBitmap(SkBitmapOperations::CreateHSLShiftedBitmap(*frame, |
+ it->second)); |
+} |
+ |
+SkBitmap* GtkThemeProvider::GenerateTabImage(int base_id) const { |
+ SkBitmap* base_image = GetBitmapNamed(base_id); |
+ SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( |
+ *base_image, GetTint(BrowserThemeProvider::TINT_BACKGROUND_TAB)); |
+ return new SkBitmap(SkBitmapOperations::CreateTiledBitmap( |
+ bg_tint, 0, 0, bg_tint.width(), bg_tint.height())); |
+} |
+ |
void GtkThemeProvider::OnDestroyChromeButton(GtkWidget* button, |
GtkThemeProvider* provider) { |
std::vector<GtkWidget*>::iterator it = |