| 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 =
|
|
|