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 |