| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/gtk/gtk_theme_provider.h" | 5 #include "chrome/browser/gtk/gtk_theme_provider.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 GdkPixbuf* GtkThemeProvider::default_bookmark_icon_ = NULL; | 194 GdkPixbuf* GtkThemeProvider::default_bookmark_icon_ = NULL; |
| 195 | 195 |
| 196 // static | 196 // static |
| 197 GtkThemeProvider* GtkThemeProvider::GetFrom(Profile* profile) { | 197 GtkThemeProvider* GtkThemeProvider::GetFrom(Profile* profile) { |
| 198 return static_cast<GtkThemeProvider*>(profile->GetThemeProvider()); | 198 return static_cast<GtkThemeProvider*>(profile->GetThemeProvider()); |
| 199 } | 199 } |
| 200 | 200 |
| 201 GtkThemeProvider::GtkThemeProvider() | 201 GtkThemeProvider::GtkThemeProvider() |
| 202 : BrowserThemeProvider(), | 202 : BrowserThemeProvider(), |
| 203 fake_window_(gtk_window_new(GTK_WINDOW_TOPLEVEL)), | 203 fake_window_(gtk_window_new(GTK_WINDOW_TOPLEVEL)), |
| 204 fake_frame_(meta_frames_new()) { | 204 fake_frame_(meta_frames_new()), |
| 205 fullscreen_icon_set_(NULL) { |
| 205 fake_label_.Own(gtk_label_new("")); | 206 fake_label_.Own(gtk_label_new("")); |
| 206 fake_entry_.Own(gtk_entry_new()); | 207 fake_entry_.Own(gtk_entry_new()); |
| 208 fake_menu_item_.Own(gtk_menu_item_new()); |
| 207 | 209 |
| 208 // Only realized widgets receive style-set notifications, which we need to | 210 // Only realized widgets receive style-set notifications, which we need to |
| 209 // broadcast new theme images and colors. Only realized widgets have style | 211 // broadcast new theme images and colors. Only realized widgets have style |
| 210 // properties, too, which we query for some colors. | 212 // properties, too, which we query for some colors. |
| 211 gtk_widget_realize(fake_frame_); | 213 gtk_widget_realize(fake_frame_); |
| 212 gtk_widget_realize(fake_window_); | 214 gtk_widget_realize(fake_window_); |
| 213 signals_.Connect(fake_frame_, "style-set", | 215 signals_.Connect(fake_frame_, "style-set", |
| 214 G_CALLBACK(&OnStyleSetThunk), this); | 216 G_CALLBACK(&OnStyleSetThunk), this); |
| 215 } | 217 } |
| 216 | 218 |
| 217 GtkThemeProvider::~GtkThemeProvider() { | 219 GtkThemeProvider::~GtkThemeProvider() { |
| 218 profile()->GetPrefs()->RemovePrefObserver(prefs::kUsesSystemTheme, this); | 220 profile()->GetPrefs()->RemovePrefObserver(prefs::kUsesSystemTheme, this); |
| 219 gtk_widget_destroy(fake_window_); | 221 gtk_widget_destroy(fake_window_); |
| 220 gtk_widget_destroy(fake_frame_); | 222 gtk_widget_destroy(fake_frame_); |
| 221 fake_label_.Destroy(); | 223 fake_label_.Destroy(); |
| 222 fake_entry_.Destroy(); | 224 fake_entry_.Destroy(); |
| 225 fake_menu_item_.Destroy(); |
| 226 |
| 227 FreeIconSets(); |
| 223 | 228 |
| 224 // We have to call this because FreePlatformCached() in ~BrowserThemeProvider | 229 // We have to call this because FreePlatformCached() in ~BrowserThemeProvider |
| 225 // doesn't call the right virutal FreePlatformCaches. | 230 // doesn't call the right virutal FreePlatformCaches. |
| 226 FreePlatformCaches(); | 231 FreePlatformCaches(); |
| 227 } | 232 } |
| 228 | 233 |
| 229 void GtkThemeProvider::Init(Profile* profile) { | 234 void GtkThemeProvider::Init(Profile* profile) { |
| 230 profile->GetPrefs()->AddPrefObserver(prefs::kUsesSystemTheme, this); | 235 profile->GetPrefs()->AddPrefObserver(prefs::kUsesSystemTheme, this); |
| 231 use_gtk_ = profile->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme); | 236 use_gtk_ = profile->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme); |
| 232 | 237 |
| 233 BrowserThemeProvider::Init(profile); | 238 BrowserThemeProvider::Init(profile); |
| 234 } | 239 } |
| 235 | 240 |
| 236 SkBitmap* GtkThemeProvider::GetBitmapNamed(int id) const { | 241 SkBitmap* GtkThemeProvider::GetBitmapNamed(int id) const { |
| 242 // Try to get our cached version: |
| 243 ImageCache::const_iterator it = gtk_images_.find(id); |
| 244 if (it != gtk_images_.end()) |
| 245 return it->second; |
| 246 |
| 237 if (use_gtk_ && IsOverridableImage(id)) { | 247 if (use_gtk_ && IsOverridableImage(id)) { |
| 238 // Try to get our cached version: | |
| 239 ImageCache::const_iterator it = gtk_images_.find(id); | |
| 240 if (it != gtk_images_.end()) | |
| 241 return it->second; | |
| 242 | |
| 243 // We haven't built this image yet: | 248 // We haven't built this image yet: |
| 244 SkBitmap* bitmap = GenerateGtkThemeBitmap(id); | 249 SkBitmap* bitmap = GenerateGtkThemeBitmap(id); |
| 245 gtk_images_[id] = bitmap; | 250 gtk_images_[id] = bitmap; |
| 246 return bitmap; | 251 return bitmap; |
| 247 } | 252 } |
| 248 | 253 |
| 249 return BrowserThemeProvider::GetBitmapNamed(id); | 254 return BrowserThemeProvider::GetBitmapNamed(id); |
| 250 } | 255 } |
| 251 | 256 |
| 252 SkColor GtkThemeProvider::GetColor(int id) const { | 257 SkColor GtkThemeProvider::GetColor(int id) const { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 // the base color counts more than once. | 355 // the base color counts more than once. |
| 351 GdkColor color; | 356 GdkColor color; |
| 352 color.pixel = 0; | 357 color.pixel = 0; |
| 353 color.red = (text.red + (bg.red * kBgWeight)) / (1 + kBgWeight); | 358 color.red = (text.red + (bg.red * kBgWeight)) / (1 + kBgWeight); |
| 354 color.green = (text.green + (bg.green * kBgWeight)) / (1 + kBgWeight); | 359 color.green = (text.green + (bg.green * kBgWeight)) / (1 + kBgWeight); |
| 355 color.blue = (text.blue + (bg.blue * kBgWeight)) / (1 + kBgWeight); | 360 color.blue = (text.blue + (bg.blue * kBgWeight)) / (1 + kBgWeight); |
| 356 | 361 |
| 357 return color; | 362 return color; |
| 358 } | 363 } |
| 359 | 364 |
| 365 GtkIconSet* GtkThemeProvider::GetIconSetForId(int id) const { |
| 366 if (id == IDR_FULLSCREEN_MENU_BUTTON) |
| 367 return fullscreen_icon_set_; |
| 368 |
| 369 return NULL; |
| 370 } |
| 371 |
| 360 void GtkThemeProvider::GetScrollbarColors(GdkColor* thumb_active_color, | 372 void GtkThemeProvider::GetScrollbarColors(GdkColor* thumb_active_color, |
| 361 GdkColor* thumb_inactive_color, | 373 GdkColor* thumb_inactive_color, |
| 362 GdkColor* track_color) { | 374 GdkColor* track_color) { |
| 363 // Create window containing scrollbar elements | 375 // Create window containing scrollbar elements |
| 364 GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); | 376 GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); |
| 365 GtkWidget* fixed = gtk_fixed_new(); | 377 GtkWidget* fixed = gtk_fixed_new(); |
| 366 GtkWidget* scrollbar = gtk_hscrollbar_new(NULL); | 378 GtkWidget* scrollbar = gtk_hscrollbar_new(NULL); |
| 367 gtk_container_add(GTK_CONTAINER(window), fixed); | 379 gtk_container_add(GTK_CONTAINER(window), fixed); |
| 368 gtk_container_add(GTK_CONTAINER(fixed), scrollbar); | 380 gtk_container_add(GTK_CONTAINER(fixed), scrollbar); |
| 369 gtk_widget_realize(window); | 381 gtk_widget_realize(window); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 BrowserThemeProvider::ClearAllThemeData(); | 540 BrowserThemeProvider::ClearAllThemeData(); |
| 529 } | 541 } |
| 530 | 542 |
| 531 void GtkThemeProvider::LoadThemePrefs() { | 543 void GtkThemeProvider::LoadThemePrefs() { |
| 532 if (use_gtk_) { | 544 if (use_gtk_) { |
| 533 LoadGtkValues(); | 545 LoadGtkValues(); |
| 534 } else { | 546 } else { |
| 535 LoadDefaultValues(); | 547 LoadDefaultValues(); |
| 536 BrowserThemeProvider::LoadThemePrefs(); | 548 BrowserThemeProvider::LoadThemePrefs(); |
| 537 } | 549 } |
| 550 |
| 551 RebuildMenuIconSets(); |
| 538 } | 552 } |
| 539 | 553 |
| 540 void GtkThemeProvider::NotifyThemeChanged(Extension* extension) { | 554 void GtkThemeProvider::NotifyThemeChanged(Extension* extension) { |
| 541 BrowserThemeProvider::NotifyThemeChanged(extension); | 555 BrowserThemeProvider::NotifyThemeChanged(extension); |
| 542 | 556 |
| 543 // Notify all GtkChromeButtons of their new rendering mode: | 557 // Notify all GtkChromeButtons of their new rendering mode: |
| 544 for (std::vector<GtkWidget*>::iterator it = chrome_buttons_.begin(); | 558 for (std::vector<GtkWidget*>::iterator it = chrome_buttons_.begin(); |
| 545 it != chrome_buttons_.end(); ++it) { | 559 it != chrome_buttons_.end(); ++it) { |
| 546 gtk_chrome_button_set_use_gtk_rendering( | 560 gtk_chrome_button_set_use_gtk_rendering( |
| 547 GTK_CHROME_BUTTON(*it), use_gtk_); | 561 GTK_CHROME_BUTTON(*it), use_gtk_); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 561 GdkPixbuf* default_bookmark_icon = default_bookmark_icon_; | 575 GdkPixbuf* default_bookmark_icon = default_bookmark_icon_; |
| 562 default_folder_icon_ = NULL; | 576 default_folder_icon_ = NULL; |
| 563 default_bookmark_icon_ = NULL; | 577 default_bookmark_icon_ = NULL; |
| 564 | 578 |
| 565 if (profile()->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme)) { | 579 if (profile()->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme)) { |
| 566 ClearAllThemeData(); | 580 ClearAllThemeData(); |
| 567 LoadGtkValues(); | 581 LoadGtkValues(); |
| 568 NotifyThemeChanged(NULL); | 582 NotifyThemeChanged(NULL); |
| 569 } | 583 } |
| 570 | 584 |
| 585 RebuildMenuIconSets(); |
| 586 |
| 571 // Free the old icons only after the theme change notification has gone | 587 // Free the old icons only after the theme change notification has gone |
| 572 // through. | 588 // through. |
| 573 if (default_folder_icon) | 589 if (default_folder_icon) |
| 574 g_object_unref(default_folder_icon); | 590 g_object_unref(default_folder_icon); |
| 575 if (default_bookmark_icon) | 591 if (default_bookmark_icon) |
| 576 g_object_unref(default_bookmark_icon); | 592 g_object_unref(default_bookmark_icon); |
| 577 } | 593 } |
| 578 | 594 |
| 579 void GtkThemeProvider::LoadGtkValues() { | 595 void GtkThemeProvider::LoadGtkValues() { |
| 580 // Before we start setting images and values, we have to clear out old, stale | 596 // Before we start setting images and values, we have to clear out old, stale |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 thumb_active_color_ = SkColorSetRGB(244, 244, 244); | 770 thumb_active_color_ = SkColorSetRGB(244, 244, 244); |
| 755 thumb_inactive_color_ = SkColorSetRGB(234, 234, 234); | 771 thumb_inactive_color_ = SkColorSetRGB(234, 234, 234); |
| 756 track_color_ = SkColorSetRGB(211, 211, 211); | 772 track_color_ = SkColorSetRGB(211, 211, 211); |
| 757 | 773 |
| 758 active_selection_bg_color_ = SkColorSetRGB(30, 144, 255); | 774 active_selection_bg_color_ = SkColorSetRGB(30, 144, 255); |
| 759 active_selection_fg_color_ = SK_ColorWHITE; | 775 active_selection_fg_color_ = SK_ColorWHITE; |
| 760 inactive_selection_bg_color_ = SkColorSetRGB(200, 200, 200); | 776 inactive_selection_bg_color_ = SkColorSetRGB(200, 200, 200); |
| 761 inactive_selection_fg_color_ = SkColorSetRGB(50, 50, 50); | 777 inactive_selection_fg_color_ = SkColorSetRGB(50, 50, 50); |
| 762 } | 778 } |
| 763 | 779 |
| 780 void GtkThemeProvider::RebuildMenuIconSets() { |
| 781 FreeIconSets(); |
| 782 |
| 783 GtkStyle* style = gtk_rc_get_style(fake_menu_item_.get()); |
| 784 |
| 785 fullscreen_icon_set_ = gtk_icon_set_new(); |
| 786 BuildIconFromIDRWithColor(IDR_FULLSCREEN_MENU_BUTTON, |
| 787 style, |
| 788 GTK_STATE_PRELIGHT, |
| 789 fullscreen_icon_set_); |
| 790 BuildIconFromIDRWithColor(IDR_FULLSCREEN_MENU_BUTTON, |
| 791 style, |
| 792 GTK_STATE_NORMAL, |
| 793 fullscreen_icon_set_); |
| 794 } |
| 795 |
| 796 void GtkThemeProvider::BuildIconFromIDRWithColor(int id, |
| 797 GtkStyle* style, |
| 798 GtkStateType state, |
| 799 GtkIconSet* icon_set) { |
| 800 SkColor color = GdkToSkColor(&style->fg[state]); |
| 801 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 802 SkBitmap original = *rb.GetBitmapNamed(id); |
| 803 |
| 804 SkBitmap fill_color; |
| 805 fill_color.setConfig(SkBitmap::kARGB_8888_Config, |
| 806 original.width(), original.height(), 0); |
| 807 fill_color.allocPixels(); |
| 808 fill_color.eraseColor(color); |
| 809 SkBitmap masked = SkBitmapOperations::CreateMaskedBitmap( |
| 810 fill_color, original); |
| 811 |
| 812 GtkIconSource* icon = gtk_icon_source_new(); |
| 813 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&masked); |
| 814 gtk_icon_source_set_pixbuf(icon, pixbuf); |
| 815 g_object_unref(pixbuf); |
| 816 |
| 817 gtk_icon_source_set_direction_wildcarded(icon, TRUE); |
| 818 gtk_icon_source_set_size_wildcarded(icon, TRUE); |
| 819 |
| 820 gtk_icon_source_set_state(icon, state); |
| 821 // All fields default to wildcarding being on and setting a property doesn't |
| 822 // turn off wildcarding. You need to do this yourself. This is stated once in |
| 823 // the documentation in the gtk_icon_source_new() function, and no where else. |
| 824 gtk_icon_source_set_state_wildcarded( |
| 825 icon, state == GTK_STATE_NORMAL); |
| 826 |
| 827 gtk_icon_set_add_source(icon_set, icon); |
| 828 gtk_icon_source_free(icon); |
| 829 } |
| 830 |
| 764 void GtkThemeProvider::SetThemeColorFromGtk(int id, const GdkColor* color) { | 831 void GtkThemeProvider::SetThemeColorFromGtk(int id, const GdkColor* color) { |
| 765 colors_[id] = GdkToSkColor(color); | 832 colors_[id] = GdkToSkColor(color); |
| 766 } | 833 } |
| 767 | 834 |
| 768 void GtkThemeProvider::SetThemeTintFromGtk(int id, const GdkColor* color) { | 835 void GtkThemeProvider::SetThemeTintFromGtk(int id, const GdkColor* color) { |
| 769 color_utils::HSL default_tint = GetDefaultTint(id); | 836 color_utils::HSL default_tint = GetDefaultTint(id); |
| 770 color_utils::HSL hsl; | 837 color_utils::HSL hsl; |
| 771 color_utils::SkColorToHSL(GdkToSkColor(color), &hsl); | 838 color_utils::SkColorToHSL(GdkToSkColor(color), &hsl); |
| 772 | 839 |
| 773 if (default_tint.s != -1) | 840 if (default_tint.s != -1) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 795 for (PerDisplaySurfaceMap::iterator it = per_display_map->begin(); | 862 for (PerDisplaySurfaceMap::iterator it = per_display_map->begin(); |
| 796 it != per_display_map->end(); ++it) { | 863 it != per_display_map->end(); ++it) { |
| 797 for (CairoCachedSurfaceMap::iterator jt = it->second.begin(); | 864 for (CairoCachedSurfaceMap::iterator jt = it->second.begin(); |
| 798 jt != it->second.end(); ++jt) { | 865 jt != it->second.end(); ++jt) { |
| 799 delete jt->second; | 866 delete jt->second; |
| 800 } | 867 } |
| 801 } | 868 } |
| 802 per_display_map->clear(); | 869 per_display_map->clear(); |
| 803 } | 870 } |
| 804 | 871 |
| 872 void GtkThemeProvider::FreeIconSets() { |
| 873 if (fullscreen_icon_set_) { |
| 874 gtk_icon_set_unref(fullscreen_icon_set_); |
| 875 fullscreen_icon_set_ = NULL; |
| 876 } |
| 877 } |
| 878 |
| 805 SkBitmap* GtkThemeProvider::GenerateGtkThemeBitmap(int id) const { | 879 SkBitmap* GtkThemeProvider::GenerateGtkThemeBitmap(int id) const { |
| 806 switch (id) { | 880 switch (id) { |
| 807 case IDR_THEME_TOOLBAR: { | 881 case IDR_THEME_TOOLBAR: { |
| 808 GtkStyle* style = gtk_rc_get_style(fake_window_); | 882 GtkStyle* style = gtk_rc_get_style(fake_window_); |
| 809 GdkColor* color = &style->bg[GTK_STATE_NORMAL]; | 883 GdkColor* color = &style->bg[GTK_STATE_NORMAL]; |
| 810 SkBitmap* bitmap = new SkBitmap; | 884 SkBitmap* bitmap = new SkBitmap; |
| 811 bitmap->setConfig(SkBitmap::kARGB_8888_Config, | 885 bitmap->setConfig(SkBitmap::kARGB_8888_Config, |
| 812 kToolbarImageWidth, kToolbarImageHeight); | 886 kToolbarImageWidth, kToolbarImageHeight); |
| 813 bitmap->allocPixels(); | 887 bitmap->allocPixels(); |
| 814 bitmap->eraseRGB(color->red >> 8, color->green >> 8, color->blue >> 8); | 888 bitmap->eraseRGB(color->red >> 8, color->green >> 8, color->blue >> 8); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 cairo_set_line_width(cr, 1.0); | 1049 cairo_set_line_width(cr, 1.0); |
| 976 cairo_move_to(cr, start_x, widget->allocation.y); | 1050 cairo_move_to(cr, start_x, widget->allocation.y); |
| 977 cairo_line_to(cr, start_x, | 1051 cairo_line_to(cr, start_x, |
| 978 widget->allocation.y + widget->allocation.height); | 1052 widget->allocation.y + widget->allocation.height); |
| 979 cairo_stroke(cr); | 1053 cairo_stroke(cr); |
| 980 cairo_destroy(cr); | 1054 cairo_destroy(cr); |
| 981 cairo_pattern_destroy(pattern); | 1055 cairo_pattern_destroy(pattern); |
| 982 | 1056 |
| 983 return TRUE; | 1057 return TRUE; |
| 984 } | 1058 } |
| OLD | NEW |