OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/libgtk2ui/gtk2_ui.h" | 5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include <pango/pango.h> | 10 #include <pango/pango.h> |
11 | 11 |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/debug/leak_annotations.h" | 13 #include "base/debug/leak_annotations.h" |
14 #include "base/environment.h" | 14 #include "base/environment.h" |
15 #include "base/i18n/rtl.h" | 15 #include "base/i18n/rtl.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/nix/mime_util_xdg.h" | 17 #include "base/nix/mime_util_xdg.h" |
18 #include "base/nix/xdg_util.h" | 18 #include "base/nix/xdg_util.h" |
19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
20 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
22 #include "chrome/browser/themes/theme_properties.h" | 22 #include "chrome/browser/themes/theme_properties.h" |
23 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" | 23 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" |
24 #include "chrome/browser/ui/libgtk2ui/chrome_gtk_frame.h" | |
25 #include "chrome/browser/ui/libgtk2ui/gtk2_border.h" | 24 #include "chrome/browser/ui/libgtk2ui/gtk2_border.h" |
26 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" | 25 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" |
27 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h" | 26 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h" |
28 #include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h" | 27 #include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h" |
29 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" | 28 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" |
30 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" | 29 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" |
31 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h" | 30 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h" |
32 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h" | 31 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h" |
33 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h" | 32 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h" |
34 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" | 33 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" |
(...skipping 10 matching lines...) Expand all Loading... | |
45 #include "ui/base/resource/resource_bundle.h" | 44 #include "ui/base/resource/resource_bundle.h" |
46 #include "ui/gfx/canvas.h" | 45 #include "ui/gfx/canvas.h" |
47 #include "ui/gfx/display.h" | 46 #include "ui/gfx/display.h" |
48 #include "ui/gfx/geometry/rect.h" | 47 #include "ui/gfx/geometry/rect.h" |
49 #include "ui/gfx/geometry/size.h" | 48 #include "ui/gfx/geometry/size.h" |
50 #include "ui/gfx/image/image.h" | 49 #include "ui/gfx/image/image.h" |
51 #include "ui/gfx/skbitmap_operations.h" | 50 #include "ui/gfx/skbitmap_operations.h" |
52 #include "ui/gfx/skia_util.h" | 51 #include "ui/gfx/skia_util.h" |
53 #include "ui/native_theme/native_theme.h" | 52 #include "ui/native_theme/native_theme.h" |
54 #include "ui/resources/grit/ui_resources.h" | 53 #include "ui/resources/grit/ui_resources.h" |
54 #include "ui/views/controls/button/blue_button.h" | |
55 #include "ui/views/controls/button/label_button.h" | 55 #include "ui/views/controls/button/label_button.h" |
56 #include "ui/views/controls/button/label_button_border.h" | 56 #include "ui/views/controls/button/label_button_border.h" |
57 #include "ui/views/linux_ui/window_button_order_observer.h" | 57 #include "ui/views/linux_ui/window_button_order_observer.h" |
58 #include "ui/views/resources/grit/views_resources.h" | 58 #include "ui/views/resources/grit/views_resources.h" |
59 | 59 |
60 #if defined(USE_GCONF) | 60 #if defined(USE_GCONF) |
61 #include "chrome/browser/ui/libgtk2ui/gconf_listener.h" | 61 #include "chrome/browser/ui/libgtk2ui/gconf_listener.h" |
62 #endif | 62 #endif |
63 | 63 |
64 // A minimized port of GtkThemeService into something that can provide colors | 64 // A minimized port of GtkThemeService into something that can provide colors |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 // Number of app indicators used (used as part of app-indicator id). | 100 // Number of app indicators used (used as part of app-indicator id). |
101 int indicators_count; | 101 int indicators_count; |
102 | 102 |
103 // The unknown content type. | 103 // The unknown content type. |
104 const char* kUnknownContentType = "application/octet-stream"; | 104 const char* kUnknownContentType = "application/octet-stream"; |
105 | 105 |
106 // The size of the rendered toolbar image. | 106 // The size of the rendered toolbar image. |
107 const int kToolbarImageWidth = 64; | 107 const int kToolbarImageWidth = 64; |
108 const int kToolbarImageHeight = 128; | 108 const int kToolbarImageHeight = 128; |
109 | 109 |
110 // How much to tint the GTK+ color lighter at the top of the window. | |
111 const color_utils::HSL kGtkFrameShift = { -1, -1, 0.58 }; | |
112 | |
113 // How much to tint the GTK+ color when an explicit frame color hasn't been | |
114 // specified. | |
115 const color_utils::HSL kDefaultFrameShift = { -1, -1, 0.4 }; | |
116 | |
117 // Values used as the new luminance and saturation values in the inactive tab | 110 // Values used as the new luminance and saturation values in the inactive tab |
118 // text color. | 111 // text color. |
119 const double kDarkInactiveLuminance = 0.85; | 112 const double kDarkInactiveLuminance = 0.85; |
120 const double kLightInactiveLuminance = 0.15; | 113 const double kLightInactiveLuminance = 0.15; |
121 const double kHeavyInactiveSaturation = 0.7; | 114 const double kHeavyInactiveSaturation = 0.7; |
122 const double kLightInactiveSaturation = 0.3; | 115 const double kLightInactiveSaturation = 0.3; |
123 | 116 |
124 // Default color for links on the NTP when the GTK+ theme doesn't define a | |
125 // link color. Constant taken from gtklinkbutton.c. | |
126 const GdkColor kDefaultLinkColor = { 0, 0, 0, 0xeeee }; | |
127 | |
128 const int kSkiaToGDKMultiplier = 257; | |
129 | |
130 // TODO(erg): ThemeService has a whole interface just for reading default | 117 // TODO(erg): ThemeService has a whole interface just for reading default |
131 // constants. Figure out what to do with that more long term; for now, just | 118 // constants. Figure out what to do with that more long term; for now, just |
132 // copy the constants themselves here. | 119 // copy the constants themselves here. |
133 // | 120 // |
134 // Default tints. | 121 // Default tints. |
135 const color_utils::HSL kDefaultTintButtons = { -1, -1, -1 }; | 122 const color_utils::HSL kDefaultTintButtons = { -1, -1, -1 }; |
136 const color_utils::HSL kDefaultTintFrame = { -1, -1, -1 }; | 123 const color_utils::HSL kDefaultTintFrame = { -1, -1, -1 }; |
137 const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f }; | 124 const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f }; |
138 const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; | 125 const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; |
139 const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; | 126 const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 IDR_OMNIBOX_STAR, | 161 IDR_OMNIBOX_STAR, |
175 IDR_OMNIBOX_STAR_DARK, | 162 IDR_OMNIBOX_STAR_DARK, |
176 IDR_OMNIBOX_TTS, | 163 IDR_OMNIBOX_TTS, |
177 IDR_OMNIBOX_TTS_DARK, | 164 IDR_OMNIBOX_TTS_DARK, |
178 }; | 165 }; |
179 | 166 |
180 // This table converts button ids into a pair of gtk-stock id and state. | 167 // This table converts button ids into a pair of gtk-stock id and state. |
181 struct IDRGtkMapping { | 168 struct IDRGtkMapping { |
182 int idr; | 169 int idr; |
183 const char* stock_id; | 170 const char* stock_id; |
184 GtkStateType gtk_state; | 171 bool enabled; |
185 } const kGtkIcons[] = { | 172 } const kGtkIcons[] = { |
186 { IDR_BACK, GTK_STOCK_GO_BACK, GTK_STATE_NORMAL }, | 173 { IDR_BACK, "go-previous", true }, |
187 { IDR_BACK_D, GTK_STOCK_GO_BACK, GTK_STATE_INSENSITIVE }, | 174 { IDR_BACK_D, "go-previous", false }, |
188 | 175 |
189 { IDR_FORWARD, GTK_STOCK_GO_FORWARD, GTK_STATE_NORMAL }, | 176 { IDR_FORWARD, "go-next", true }, |
190 { IDR_FORWARD_D, GTK_STOCK_GO_FORWARD, GTK_STATE_INSENSITIVE }, | 177 { IDR_FORWARD_D, "go-next", false }, |
191 | 178 |
192 { IDR_HOME, GTK_STOCK_HOME, GTK_STATE_NORMAL }, | 179 { IDR_HOME, "go-home", true }, |
193 | 180 |
194 { IDR_RELOAD, GTK_STOCK_REFRESH, GTK_STATE_NORMAL }, | 181 { IDR_RELOAD, "view-refresh", true }, |
195 { IDR_RELOAD_D, GTK_STOCK_REFRESH, GTK_STATE_INSENSITIVE }, | 182 { IDR_RELOAD_D, "view-refresh", false }, |
196 | 183 |
197 { IDR_STOP, GTK_STOCK_STOP, GTK_STATE_NORMAL }, | 184 { IDR_STOP, "process-stop", true }, |
198 { IDR_STOP_D, GTK_STOCK_STOP, GTK_STATE_INSENSITIVE }, | 185 { IDR_STOP_D, "process-stop", false }, |
199 }; | 186 }; |
200 | 187 |
201 // The image resources that will be tinted by the 'button' tint value. | 188 // The image resources that will be tinted by the 'button' tint value. |
202 const int kOtherToolbarButtonIDs[] = { | 189 const int kOtherToolbarButtonIDs[] = { |
203 IDR_TOOLBAR_BEZEL_HOVER, | 190 IDR_TOOLBAR_BEZEL_HOVER, |
204 IDR_TOOLBAR_BEZEL_PRESSED, | 191 IDR_TOOLBAR_BEZEL_PRESSED, |
205 IDR_BROWSER_ACTIONS_OVERFLOW, | 192 IDR_BROWSER_ACTIONS_OVERFLOW, |
206 | 193 |
207 // TODO(erg): The dropdown arrow should be tinted because we're injecting | 194 // TODO(erg): The dropdown arrow should be tinted because we're injecting |
208 // various background GTK colors, but the code that accesses them needs to be | 195 // various background GTK colors, but the code that accesses them needs to be |
(...skipping 13 matching lines...) Expand all Loading... | |
222 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) | 209 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) |
223 images.insert(kGtkIcons[i].idr); | 210 images.insert(kGtkIcons[i].idr); |
224 | 211 |
225 images.insert(kOtherToolbarButtonIDs, | 212 images.insert(kOtherToolbarButtonIDs, |
226 kOtherToolbarButtonIDs + arraysize(kOtherToolbarButtonIDs)); | 213 kOtherToolbarButtonIDs + arraysize(kOtherToolbarButtonIDs)); |
227 } | 214 } |
228 | 215 |
229 return images.count(id) > 0; | 216 return images.count(id) > 0; |
230 } | 217 } |
231 | 218 |
219 // Get ChromeGtkFrame theme colors. No-op in GTK3. | |
220 void GetChromeStyleColor(const char* style_property, SkColor* ret_color) { | |
221 #if GTK_MAJOR_VERSION == 2 | |
222 GdkColor* style_color = NULL; | |
223 | |
224 gtk_widget_style_get(NativeThemeGtk2::instance()->GetWindow(), | |
225 style_property, &style_color, | |
226 NULL); | |
227 | |
228 if (style_color) { | |
229 *ret_color = GdkColorToSkColor(*style_color); | |
230 gdk_color_free(style_color); | |
231 } | |
232 #endif | |
233 } | |
234 | |
232 // Picks a button tint from a set of background colors. While | 235 // Picks a button tint from a set of background colors. While |
233 // |accent_gdk_color| will usually be the same color through a theme, this | 236 // |accent_color| will usually be the same color through a theme, this |
234 // function will get called with the normal GtkLabel |text_color|/GtkWindow | 237 // function will get called with the normal GtkLabel |text_color|/GtkWindow |
235 // |background_color| pair and the GtkEntry |text_color|/|background_color| | 238 // |background_color| pair and the GtkEntry |text_color|/|background_color| |
236 // pair. While 3/4 of the time the resulting tint will be the same, themes that | 239 // pair. While 3/4 of the time the resulting tint will be the same, themes that |
237 // have a dark window background (with light text) and a light text entry (with | 240 // have a dark window background (with light text) and a light text entry (with |
238 // dark text) will get better icons with this separated out. | 241 // dark text) will get better icons with this separated out. |
239 void PickButtonTintFromColors(const GdkColor& accent_gdk_color, | 242 void PickButtonTintFromColors(SkColor accent_color, |
240 const GdkColor& text_color, | 243 SkColor text_color, |
241 const GdkColor& background_color, | 244 SkColor background_color, |
242 color_utils::HSL* tint) { | 245 color_utils::HSL* tint) { |
243 SkColor accent_color = GdkColorToSkColor(accent_gdk_color); | 246 color_utils::HSL accent_tint, text_tint, background_tint; |
244 color_utils::HSL accent_tint; | |
245 color_utils::SkColorToHSL(accent_color, &accent_tint); | 247 color_utils::SkColorToHSL(accent_color, &accent_tint); |
246 | 248 color_utils::SkColorToHSL(text_color, &text_tint); |
247 color_utils::HSL text_tint; | 249 color_utils::SkColorToHSL(background_color, &background_tint); |
248 color_utils::SkColorToHSL(GdkColorToSkColor(text_color), | |
249 &text_tint); | |
250 | |
251 color_utils::HSL background_tint; | |
252 color_utils::SkColorToHSL(GdkColorToSkColor(background_color), | |
253 &background_tint); | |
254 | 250 |
255 // If the accent color is gray, then our normal HSL tomfoolery will bring out | 251 // If the accent color is gray, then our normal HSL tomfoolery will bring out |
256 // whatever color is oddly dominant (for example, in rgb space [125, 128, | 252 // whatever color is oddly dominant (for example, in rgb space [125, 128, |
257 // 125] will tint green instead of gray). Slight differences (+/-10 (4%) to | 253 // 125] will tint green instead of gray). Slight differences (+/-10 (4%) to |
258 // all color components) should be interpreted as this color being gray and | 254 // all color components) should be interpreted as this color being gray and |
259 // we should switch into a special grayscale mode. | 255 // we should switch into a special grayscale mode. |
260 int rb_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - | 256 int rb_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - |
261 static_cast<int>(SkColorGetB(accent_color))); | 257 static_cast<int>(SkColorGetB(accent_color))); |
262 int rg_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - | 258 int rg_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - |
263 static_cast<int>(SkColorGetG(accent_color))); | 259 static_cast<int>(SkColorGetG(accent_color))); |
(...skipping 26 matching lines...) Expand all Loading... | |
290 // white. | 286 // white. |
291 if (text_tint.l < 0.5) | 287 if (text_tint.l < 0.5) |
292 tint->l = -1; | 288 tint->l = -1; |
293 else if (text_tint.l <= 0.9) | 289 else if (text_tint.l <= 0.9) |
294 tint->l = text_tint.l; | 290 tint->l = text_tint.l; |
295 else | 291 else |
296 tint->l = 0.9; | 292 tint->l = 0.9; |
297 } | 293 } |
298 } | 294 } |
299 | 295 |
300 // Applies an HSL shift to a GdkColor (instead of an SkColor) | |
301 void GdkColorHSLShift(const color_utils::HSL& shift, GdkColor* frame_color) { | |
302 SkColor shifted = color_utils::HSLShift( | |
303 GdkColorToSkColor(*frame_color), shift); | |
304 | |
305 frame_color->pixel = 0; | |
306 frame_color->red = SkColorGetR(shifted) * kSkiaToGDKMultiplier; | |
307 frame_color->green = SkColorGetG(shifted) * kSkiaToGDKMultiplier; | |
308 frame_color->blue = SkColorGetB(shifted) * kSkiaToGDKMultiplier; | |
309 } | |
310 | |
311 // Copied Default blah sections from ThemeService. | 296 // Copied Default blah sections from ThemeService. |
312 color_utils::HSL GetDefaultTint(int id) { | 297 color_utils::HSL GetDefaultTint(int id) { |
313 switch (id) { | 298 switch (id) { |
314 case ThemeProperties::TINT_FRAME: | 299 case ThemeProperties::TINT_FRAME: |
315 return kDefaultTintFrame; | 300 return kDefaultTintFrame; |
316 case ThemeProperties::TINT_FRAME_INACTIVE: | 301 case ThemeProperties::TINT_FRAME_INACTIVE: |
317 return kDefaultTintFrameInactive; | 302 return kDefaultTintFrameInactive; |
318 case ThemeProperties::TINT_FRAME_INCOGNITO: | 303 case ThemeProperties::TINT_FRAME_INCOGNITO: |
319 return kDefaultTintFrameIncognito; | 304 return kDefaultTintFrameIncognito; |
320 case ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE: | 305 case ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE: |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 } // namespace | 406 } // namespace |
422 | 407 |
423 Gtk2UI::Gtk2UI() | 408 Gtk2UI::Gtk2UI() |
424 : default_font_size_pixels_(0), | 409 : default_font_size_pixels_(0), |
425 default_font_style_(gfx::Font::NORMAL), | 410 default_font_style_(gfx::Font::NORMAL), |
426 middle_click_action_(GetDefaultMiddleClickAction()), | 411 middle_click_action_(GetDefaultMiddleClickAction()), |
427 device_scale_factor_(1.0) { | 412 device_scale_factor_(1.0) { |
428 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); | 413 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); |
429 } | 414 } |
430 | 415 |
416 | |
417 | |
418 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { | |
419 gtkui->ResetStyle(); | |
420 } | |
421 | |
431 void Gtk2UI::Initialize() { | 422 void Gtk2UI::Initialize() { |
432 signals_.reset(new Gtk2SignalRegistrar); | 423 GtkSettings* settings = gtk_settings_get_default(); |
424 g_signal_connect_after(settings, | |
425 "notify::gtk-theme-name", | |
426 G_CALLBACK(OnThemeChanged), | |
427 this); | |
428 g_signal_connect_after(settings, | |
429 "notify::gtk-icon-theme-name", | |
430 G_CALLBACK(OnThemeChanged), | |
431 this); | |
433 | 432 |
434 // Create our fake widgets. | |
435 fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
436 fake_frame_ = chrome_gtk_frame_new(); | |
437 fake_label_.Own(gtk_label_new("")); | |
438 fake_entry_.Own(gtk_entry_new()); | |
439 | |
440 // Only realized widgets receive style-set notifications, which we need to | |
441 // broadcast new theme images and colors. Only realized widgets have style | |
442 // properties, too, which we query for some colors. | |
443 gtk_widget_realize(fake_frame_); | |
444 gtk_widget_realize(fake_window_); | |
445 | |
446 signals_->Connect(fake_frame_, "style-set", | |
447 G_CALLBACK(&OnStyleSetThunk), this); | |
448 | 433 |
449 LoadGtkValues(); | 434 LoadGtkValues(); |
450 | 435 |
451 printing::PrintingContextLinux::SetCreatePrintDialogFunction( | 436 printing::PrintingContextLinux::SetCreatePrintDialogFunction( |
452 &PrintDialogGtk2::CreatePrintDialog); | 437 &PrintDialogGtk2::CreatePrintDialog); |
453 printing::PrintingContextLinux::SetPdfPaperSizeFunction( | 438 printing::PrintingContextLinux::SetPdfPaperSizeFunction( |
454 &GetPdfPaperSizeDeviceUnitsGtk); | 439 &GetPdfPaperSizeDeviceUnitsGtk); |
455 | 440 |
456 #if defined(USE_GCONF) | 441 #if defined(USE_GCONF) |
457 // We must build this after GTK gets initialized. | 442 // We must build this after GTK gets initialized. |
458 gconf_listener_.reset(new GConfListener(this)); | 443 gconf_listener_.reset(new GConfListener(this)); |
459 #endif // defined(USE_GCONF) | 444 #endif // defined(USE_GCONF) |
460 | 445 |
461 indicators_count = 0; | 446 indicators_count = 0; |
462 | 447 |
463 // Instantiate the singleton instance of Gtk2EventLoop. | 448 // Instantiate the singleton instance of Gtk2EventLoop. |
464 Gtk2EventLoop::GetInstance(); | 449 Gtk2EventLoop::GetInstance(); |
465 } | 450 } |
466 | 451 |
467 Gtk2UI::~Gtk2UI() { | 452 Gtk2UI::~Gtk2UI() { |
468 gtk_widget_destroy(fake_window_); | |
469 gtk_widget_destroy(fake_frame_); | |
470 fake_label_.Destroy(); | |
471 fake_entry_.Destroy(); | |
472 | |
473 ClearAllThemeData(); | 453 ClearAllThemeData(); |
474 } | 454 } |
475 | 455 |
476 gfx::Image Gtk2UI::GetThemeImageNamed(int id) const { | 456 gfx::Image Gtk2UI::GetThemeImageNamed(int id) const { |
477 // Try to get our cached version: | 457 // Try to get our cached version: |
478 ImageCache::const_iterator it = gtk_images_.find(id); | 458 ImageCache::const_iterator it = gtk_images_.find(id); |
479 if (it != gtk_images_.end()) | 459 if (it != gtk_images_.end()) |
480 return it->second; | 460 return it->second; |
481 | 461 |
482 if (IsOverridableImage(id)) { | 462 if (IsOverridableImage(id)) { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
734 | 714 |
735 bool Gtk2UI::MatchEvent(const ui::Event& event, | 715 bool Gtk2UI::MatchEvent(const ui::Event& event, |
736 std::vector<ui::TextEditCommandAuraLinux>* commands) { | 716 std::vector<ui::TextEditCommandAuraLinux>* commands) { |
737 // Ensure that we have a keyboard handler. | 717 // Ensure that we have a keyboard handler. |
738 if (!key_bindings_handler_) | 718 if (!key_bindings_handler_) |
739 key_bindings_handler_.reset(new Gtk2KeyBindingsHandler); | 719 key_bindings_handler_.reset(new Gtk2KeyBindingsHandler); |
740 | 720 |
741 return key_bindings_handler_->MatchEvent(event, commands); | 721 return key_bindings_handler_->MatchEvent(event, commands); |
742 } | 722 } |
743 | 723 |
744 void Gtk2UI::GetScrollbarColors(GdkColor* thumb_active_color, | 724 void Gtk2UI::SetScrollbarColors() { |
745 GdkColor* thumb_inactive_color, | 725 thumb_active_color_ = SkColorSetRGB(244, 244, 244); |
746 GdkColor* track_color) { | 726 thumb_inactive_color_ = SkColorSetRGB(234, 234, 234); |
747 GdkColor* theme_thumb_active = NULL; | 727 track_color_ = SkColorSetRGB(211, 211, 211); |
748 GdkColor* theme_thumb_inactive = NULL; | |
749 GdkColor* theme_trough_color = NULL; | |
750 gtk_widget_style_get(GTK_WIDGET(fake_frame_), | |
751 "scrollbar-slider-prelight-color", &theme_thumb_active, | |
752 "scrollbar-slider-normal-color", &theme_thumb_inactive, | |
753 "scrollbar-trough-color", &theme_trough_color, | |
754 NULL); | |
755 | 728 |
756 // Ask the theme if the theme specifies all the scrollbar colors and short | 729 GetChromeStyleColor("scrollbar-slider-prelight-color", &thumb_active_color_); |
757 // circuit the expensive painting/compositing if we have all of them. | 730 GetChromeStyleColor("scrollbar-slider-normal-color", &thumb_inactive_color_); |
758 if (theme_thumb_active && theme_thumb_inactive && theme_trough_color) { | 731 GetChromeStyleColor("scrollbar-trough-color", &track_color_); |
759 *thumb_active_color = *theme_thumb_active; | |
760 *thumb_inactive_color = *theme_thumb_inactive; | |
761 *track_color = *theme_trough_color; | |
762 | |
763 gdk_color_free(theme_thumb_active); | |
764 gdk_color_free(theme_thumb_inactive); | |
765 gdk_color_free(theme_trough_color); | |
766 return; | |
767 } | |
768 | |
769 // Create window containing scrollbar elements | |
770 GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); | |
771 GtkWidget* fixed = gtk_fixed_new(); | |
772 GtkWidget* scrollbar = gtk_hscrollbar_new(NULL); | |
773 gtk_container_add(GTK_CONTAINER(window), fixed); | |
774 gtk_container_add(GTK_CONTAINER(fixed), scrollbar); | |
775 gtk_widget_realize(window); | |
776 gtk_widget_realize(scrollbar); | |
777 | |
778 // Draw scrollbar thumb part and track into offscreen image | |
779 const int kWidth = 100; | |
780 const int kHeight = 20; | |
781 GtkStyle* style = gtk_rc_get_style(scrollbar); | |
782 GdkWindow* gdk_window = gtk_widget_get_window(window); | |
783 GdkPixmap* pm = gdk_pixmap_new(gdk_window, kWidth, kHeight, -1); | |
784 GdkRectangle rect = { 0, 0, kWidth, kHeight }; | |
785 unsigned char data[3 * kWidth * kHeight]; | |
786 for (int i = 0; i < 3; ++i) { | |
787 if (i < 2) { | |
788 // Thumb part | |
789 gtk_paint_slider(style, pm, | |
790 i == 0 ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, | |
791 GTK_SHADOW_OUT, &rect, scrollbar, "slider", 0, 0, | |
792 kWidth, kHeight, GTK_ORIENTATION_HORIZONTAL); | |
793 } else { | |
794 // Track | |
795 gtk_paint_box(style, pm, GTK_STATE_ACTIVE, GTK_SHADOW_IN, &rect, | |
796 scrollbar, "trough-upper", 0, 0, kWidth, kHeight); | |
797 } | |
798 GdkPixbuf* pb = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, | |
799 FALSE, 8, kWidth, kHeight, | |
800 3 * kWidth, 0, 0); | |
801 gdk_pixbuf_get_from_drawable(pb, pm, NULL, 0, 0, 0, 0, kWidth, kHeight); | |
802 | |
803 // Sample pixels | |
804 int components[3] = { 0 }; | |
805 for (int y = 2; y < kHeight - 2; ++y) { | |
806 for (int c = 0; c < 3; ++c) { | |
807 // Sample a vertical slice of pixels at about one-thirds from the | |
808 // left edge. This allows us to avoid any fixed graphics that might be | |
809 // located at the edges or in the center of the scrollbar. | |
810 // Each pixel is made up of a red, green, and blue component; taking up | |
811 // a total of three bytes. | |
812 components[c] += data[3 * (kWidth / 3 + y * kWidth) + c]; | |
813 } | |
814 } | |
815 GdkColor* color = i == 0 ? thumb_active_color : | |
816 i == 1 ? thumb_inactive_color : | |
817 track_color; | |
818 color->pixel = 0; | |
819 // We sampled pixels across the full height of the image, ignoring a two | |
820 // pixel border. In some themes, the border has a completely different | |
821 // color which we do not want to factor into our average color computation. | |
822 // | |
823 // We now need to scale the colors from the 0..255 range, to the wider | |
824 // 0..65535 range, and we need to actually compute the average color; so, | |
825 // we divide by the total number of pixels in the sample. | |
826 color->red = components[0] * 65535 / (255 * (kHeight - 4)); | |
827 color->green = components[1] * 65535 / (255 * (kHeight - 4)); | |
828 color->blue = components[2] * 65535 / (255 * (kHeight - 4)); | |
829 | |
830 g_object_unref(pb); | |
831 } | |
832 g_object_unref(pm); | |
833 | |
834 gtk_widget_destroy(window); | |
835 | |
836 // Override any of the default colors with ones that were specified by the | |
837 // theme. | |
838 if (theme_thumb_active) { | |
839 *thumb_active_color = *theme_thumb_active; | |
840 gdk_color_free(theme_thumb_active); | |
841 } | |
842 | |
843 if (theme_thumb_inactive) { | |
844 *thumb_inactive_color = *theme_thumb_inactive; | |
845 gdk_color_free(theme_thumb_inactive); | |
846 } | |
847 | |
848 if (theme_trough_color) { | |
849 *track_color = *theme_trough_color; | |
850 gdk_color_free(theme_trough_color); | |
851 } | |
852 } | 732 } |
853 | 733 |
854 void Gtk2UI::LoadGtkValues() { | 734 void Gtk2UI::LoadGtkValues() { |
855 // TODO(erg): GtkThemeService had a comment here about having to muck with | 735 // TODO(erg): GtkThemeService had a comment here about having to muck with |
856 // the raw Prefs object to remove prefs::kCurrentThemeImages or else we'd | 736 // the raw Prefs object to remove prefs::kCurrentThemeImages or else we'd |
857 // regress startup time. Figure out how to do that when we can't access the | 737 // regress startup time. Figure out how to do that when we can't access the |
858 // prefs system from here. | 738 // prefs system from here. |
859 | 739 |
860 GtkStyle* frame_style = gtk_rc_get_style(fake_frame_); | 740 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
861 | 741 |
862 GtkStyle* window_style = gtk_rc_get_style(fake_window_); | 742 SkColor toolbar_color = |
863 SetThemeColorFromGtk(ThemeProperties::COLOR_CONTROL_BACKGROUND, | 743 theme->GetSystemColor(ui::NativeTheme::kColorId_WindowBackground); |
864 &window_style->bg[GTK_STATE_NORMAL]); | 744 SkColor button_color = |
745 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor); | |
746 SkColor label_color = | |
747 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelEnabledColor); | |
865 | 748 |
866 GdkColor toolbar_color = window_style->bg[GTK_STATE_NORMAL]; | 749 colors_[ThemeProperties::COLOR_CONTROL_BACKGROUND] = toolbar_color; |
867 SetThemeColorFromGtk(ThemeProperties::COLOR_TOOLBAR, &toolbar_color); | 750 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color; |
868 | 751 |
869 GdkColor button_color = window_style->bg[GTK_STATE_SELECTED]; | 752 SetThemeTint(ThemeProperties::TINT_BUTTONS, button_color); |
870 SetThemeTintFromGtk(ThemeProperties::TINT_BUTTONS, &button_color); | |
871 | 753 |
872 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); | 754 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; |
873 GdkColor label_color = label_style->fg[GTK_STATE_NORMAL]; | 755 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; |
874 SetThemeColorFromGtk(ThemeProperties::COLOR_TAB_TEXT, &label_color); | 756 colors_[ThemeProperties::COLOR_STATUS_BAR_TEXT] = label_color; |
875 SetThemeColorFromGtk(ThemeProperties::COLOR_BOOKMARK_TEXT, &label_color); | |
876 SetThemeColorFromGtk(ThemeProperties::COLOR_STATUS_BAR_TEXT, &label_color); | |
877 | 757 |
878 UpdateDefaultFont(label_style->font_desc); | 758 UpdateDefaultFont(); |
879 | 759 |
880 // Build the various icon tints. | 760 // Build the various icon tints. |
881 GetNormalButtonTintHSL(&button_tint_); | 761 GetNormalButtonTintHSL(&button_tint_); |
882 GetNormalEntryForegroundHSL(&entry_tint_); | 762 GetNormalEntryForegroundHSL(&entry_tint_); |
883 GetSelectedEntryForegroundHSL(&selected_entry_tint_); | 763 GetSelectedEntryForegroundHSL(&selected_entry_tint_); |
884 GdkColor frame_color = BuildFrameColors(frame_style); | 764 SkColor frame_color = BuildFrameColors(); |
885 | 765 |
886 // The inactive frame color never occurs naturally in the theme, as it is a | 766 // The inactive frame color never occurs naturally in the theme, as it is a |
887 // tinted version of |frame_color|. We generate another color based on the | 767 // tinted version of |frame_color|. We generate another color based on the |
888 // background tab color, with the lightness and saturation moved in the | 768 // background tab color, with the lightness and saturation moved in the |
889 // opposite direction. (We don't touch the hue, since there should be subtle | 769 // opposite direction. (We don't touch the hue, since there should be subtle |
890 // hints of the color in the text.) | 770 // hints of the color in the text.) |
891 color_utils::HSL inactive_tab_text_hsl = | 771 color_utils::HSL inactive_tab_text_hsl = |
892 tints_[ThemeProperties::TINT_BACKGROUND_TAB]; | 772 tints_[ThemeProperties::TINT_BACKGROUND_TAB]; |
893 if (inactive_tab_text_hsl.l < 0.5) | 773 if (inactive_tab_text_hsl.l < 0.5) |
894 inactive_tab_text_hsl.l = kDarkInactiveLuminance; | 774 inactive_tab_text_hsl.l = kDarkInactiveLuminance; |
895 else | 775 else |
896 inactive_tab_text_hsl.l = kLightInactiveLuminance; | 776 inactive_tab_text_hsl.l = kLightInactiveLuminance; |
897 | 777 |
898 if (inactive_tab_text_hsl.s < 0.5) | 778 if (inactive_tab_text_hsl.s < 0.5) |
899 inactive_tab_text_hsl.s = kHeavyInactiveSaturation; | 779 inactive_tab_text_hsl.s = kHeavyInactiveSaturation; |
900 else | 780 else |
901 inactive_tab_text_hsl.s = kLightInactiveSaturation; | 781 inactive_tab_text_hsl.s = kLightInactiveSaturation; |
902 | 782 |
903 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = | 783 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = |
904 color_utils::HSLToSkColor(inactive_tab_text_hsl, 255); | 784 color_utils::HSLToSkColor(inactive_tab_text_hsl, 255); |
905 | 785 |
906 // We pick the text and background colors for the NTP out of the colors for a | 786 // We pick the text and background colors for the NTP out of the colors for a |
907 // GtkEntry. We do this because GtkEntries background color is never the same | 787 // GtkEntry. We do this because GtkEntries background color is never the same |
908 // as |toolbar_color|, is usually a white, and when it isn't a white, | 788 // as |toolbar_color|, is usually a white, and when it isn't a white, |
909 // provides sufficient contrast to |toolbar_color|. Try this out with | 789 // provides sufficient contrast to |toolbar_color|. Try this out with |
910 // Darklooks, HighContrastInverse or ThinIce. | 790 // Darklooks, HighContrastInverse or ThinIce. |
911 GtkStyle* entry_style = gtk_rc_get_style(fake_entry_.get()); | 791 |
912 GdkColor ntp_background = entry_style->base[GTK_STATE_NORMAL]; | 792 SkColor ntp_background = |
913 GdkColor ntp_foreground = entry_style->text[GTK_STATE_NORMAL]; | 793 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultBackground ); |
914 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_BACKGROUND, | 794 SkColor ntp_foreground = |
915 &ntp_background); | 795 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultColor); |
916 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_TEXT, | 796 |
917 &ntp_foreground); | 797 colors_[ThemeProperties::COLOR_NTP_BACKGROUND] = ntp_background; |
798 colors_[ThemeProperties::COLOR_NTP_TEXT] = ntp_foreground; | |
918 | 799 |
919 // The NTP header is the color that surrounds the current active thumbnail on | 800 // The NTP header is the color that surrounds the current active thumbnail on |
920 // the NTP, and acts as the border of the "Recent Links" box. It would be | 801 // the NTP, and acts as the border of the "Recent Links" box. It would be |
921 // awesome if they were separated so we could use GetBorderColor() for the | 802 // awesome if they were separated so we could use GetBorderColor() for the |
922 // border around the "Recent Links" section, but matching the frame color is | 803 // border around the "Recent Links" section, but matching the frame color is |
923 // more important. | 804 // more important. |
924 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_HEADER, | |
925 &frame_color); | |
926 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION, | |
927 &toolbar_color); | |
928 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_TEXT, | |
929 &label_color); | |
930 | 805 |
931 // Override the link color if the theme provides it. | 806 colors_[ThemeProperties::COLOR_NTP_HEADER] = frame_color; |
932 const GdkColor* link_color = NULL; | 807 colors_[ThemeProperties::COLOR_NTP_SECTION] = toolbar_color; |
933 gtk_widget_style_get(GTK_WIDGET(fake_window_), | 808 colors_[ThemeProperties::COLOR_NTP_SECTION_TEXT] = label_color; |
934 "link-color", &link_color, NULL); | |
935 | 809 |
936 bool is_default_link_color = false; | 810 // Default link color, taken from gtklinkbutton.c. |
937 if (!link_color) { | 811 SkColor link_color = SkColorSetRGB(0, 0, 0xee); |
938 link_color = &kDefaultLinkColor; | 812 GetChromeStyleColor("link-color", &link_color); |
939 is_default_link_color = true; | |
940 } | |
941 | 813 |
942 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_LINK, | 814 colors_[ThemeProperties::COLOR_NTP_LINK] = link_color; |
943 link_color); | 815 colors_[ThemeProperties::COLOR_NTP_LINK_UNDERLINE] = link_color; |
944 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_LINK_UNDERLINE, | 816 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK] = link_color; |
945 link_color); | 817 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE] = link_color; |
946 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_LINK, | |
947 link_color); | |
948 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE, | |
949 link_color); | |
950 | |
951 if (!is_default_link_color) | |
952 gdk_color_free(const_cast<GdkColor*>(link_color)); | |
953 | 818 |
954 // Generate the colors that we pass to WebKit. | 819 // Generate the colors that we pass to WebKit. |
955 focus_ring_color_ = GdkColorToSkColor(frame_color); | 820 focus_ring_color_ = frame_color; |
956 | 821 |
957 GdkColor thumb_active_color, thumb_inactive_color, track_color; | 822 SetScrollbarColors(); |
958 Gtk2UI::GetScrollbarColors(&thumb_active_color, | |
959 &thumb_inactive_color, | |
960 &track_color); | |
961 thumb_active_color_ = GdkColorToSkColor(thumb_active_color); | |
962 thumb_inactive_color_ = GdkColorToSkColor(thumb_inactive_color); | |
963 track_color_ = GdkColorToSkColor(track_color); | |
964 | 823 |
965 // Some GTK themes only define the text selection colors on the GtkEntry | 824 // Some GTK themes only define the text selection colors on the GtkEntry |
966 // class, so we need to use that for getting selection colors. | 825 // class, so we need to use that for getting selection colors. |
967 active_selection_bg_color_ = | 826 active_selection_bg_color_ = |
968 GdkColorToSkColor(entry_style->base[GTK_STATE_SELECTED]); | 827 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldSelectionBackgrou ndFocused); |
969 active_selection_fg_color_ = | 828 active_selection_fg_color_ = |
970 GdkColorToSkColor(entry_style->text[GTK_STATE_SELECTED]); | 829 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldSelectionColor); |
971 inactive_selection_bg_color_ = | 830 inactive_selection_bg_color_ = |
972 GdkColorToSkColor(entry_style->base[GTK_STATE_ACTIVE]); | 831 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldReadOnlyBackgroun d); |
973 inactive_selection_fg_color_ = | 832 inactive_selection_fg_color_ = |
974 GdkColorToSkColor(entry_style->text[GTK_STATE_ACTIVE]); | 833 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldReadOnlyColor); |
975 | 834 |
976 colors_[ThemeProperties::COLOR_THROBBER_SPINNING] = | 835 colors_[ThemeProperties::COLOR_THROBBER_SPINNING] = |
977 NativeThemeGtk2::instance()->GetSystemColor( | 836 theme->GetSystemColor(ui::NativeTheme::kColorId_ThrobberSpinningColor); |
978 ui::NativeTheme::kColorId_ThrobberSpinningColor); | |
979 colors_[ThemeProperties::COLOR_THROBBER_WAITING] = | 837 colors_[ThemeProperties::COLOR_THROBBER_WAITING] = |
980 NativeThemeGtk2::instance()->GetSystemColor( | 838 theme->GetSystemColor(ui::NativeTheme::kColorId_ThrobberWaitingColor); |
981 ui::NativeTheme::kColorId_ThrobberWaitingColor); | |
982 } | 839 } |
983 | 840 |
984 GdkColor Gtk2UI::BuildFrameColors(GtkStyle* frame_style) { | 841 SkColor Gtk2UI::BuildFrameColors() { |
985 GdkColor* theme_frame = NULL; | 842 SkColor frame_color = |
986 GdkColor* theme_inactive_frame = NULL; | 843 NativeThemeGtk2::instance()->GetSystemColor( |
987 GdkColor* theme_incognito_frame = NULL; | 844 ui::NativeTheme::kColorId_WindowBackground); |
988 GdkColor* theme_incognito_inactive_frame = NULL; | 845 SkColor temp_color; |
989 gtk_widget_style_get(GTK_WIDGET(fake_frame_), | 846 SetThemeTint(ThemeProperties::TINT_BACKGROUND_TAB, frame_color); |
990 "frame-color", &theme_frame, | |
991 "inactive-frame-color", &theme_inactive_frame, | |
992 "incognito-frame-color", &theme_incognito_frame, | |
993 "incognito-inactive-frame-color", | |
994 &theme_incognito_inactive_frame, | |
995 NULL); | |
996 | 847 |
997 GdkColor frame_color = BuildAndSetFrameColor( | |
998 &frame_style->bg[GTK_STATE_SELECTED], | |
999 theme_frame, | |
1000 kDefaultFrameShift, | |
1001 ThemeProperties::COLOR_FRAME, | |
1002 ThemeProperties::TINT_FRAME); | |
1003 if (theme_frame) | |
1004 gdk_color_free(theme_frame); | |
1005 SetThemeTintFromGtk(ThemeProperties::TINT_BACKGROUND_TAB, &frame_color); | |
1006 | 848 |
1007 BuildAndSetFrameColor( | 849 temp_color = color_utils::HSLShift( |
1008 &frame_style->bg[GTK_STATE_INSENSITIVE], | 850 frame_color, |
1009 theme_inactive_frame, | 851 GetDefaultTint(ThemeProperties::TINT_FRAME)); |
1010 kDefaultFrameShift, | 852 GetChromeStyleColor("frame-color", &temp_color); |
1011 ThemeProperties::COLOR_FRAME_INACTIVE, | |
1012 ThemeProperties::TINT_FRAME_INACTIVE); | |
1013 if (theme_inactive_frame) | |
1014 gdk_color_free(theme_inactive_frame); | |
1015 | 853 |
1016 BuildAndSetFrameColor( | 854 colors_[ThemeProperties::COLOR_FRAME] = temp_color; |
1017 &frame_color, | 855 SetThemeTint(ThemeProperties::TINT_FRAME, temp_color); |
1018 theme_incognito_frame, | |
1019 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO), | |
1020 ThemeProperties::COLOR_FRAME_INCOGNITO, | |
1021 ThemeProperties::TINT_FRAME_INCOGNITO); | |
1022 if (theme_incognito_frame) | |
1023 gdk_color_free(theme_incognito_frame); | |
1024 | 856 |
1025 BuildAndSetFrameColor( | 857 |
1026 &frame_color, | 858 temp_color = color_utils::HSLShift( |
1027 theme_incognito_inactive_frame, | 859 frame_color, |
1028 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE), | 860 GetDefaultTint(ThemeProperties::TINT_FRAME_INACTIVE)); |
1029 ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE, | 861 GetChromeStyleColor("inactive-frame-color", &temp_color); |
1030 ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE); | 862 |
1031 if (theme_incognito_inactive_frame) | 863 colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = temp_color; |
1032 gdk_color_free(theme_incognito_inactive_frame); | 864 SetThemeTint(ThemeProperties::TINT_FRAME_INACTIVE, temp_color); |
865 | |
866 | |
867 temp_color = color_utils::HSLShift( | |
868 frame_color, | |
869 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO)); | |
870 GetChromeStyleColor("incognito-frame-color", &temp_color); | |
871 | |
872 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] = temp_color; | |
873 SetThemeTint(ThemeProperties::TINT_FRAME_INCOGNITO, temp_color); | |
874 | |
875 | |
876 temp_color = color_utils::HSLShift( | |
877 frame_color, | |
878 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE)); | |
879 GetChromeStyleColor("incognito-inactive-frame-color", &temp_color); | |
880 | |
881 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = temp_color; | |
882 SetThemeTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE, temp_color); | |
883 | |
1033 | 884 |
1034 return frame_color; | 885 return frame_color; |
1035 } | 886 } |
1036 | 887 |
1037 void Gtk2UI::SetThemeColorFromGtk(int id, const GdkColor* color) { | 888 void Gtk2UI::SetThemeTint(int id, SkColor color) { |
1038 colors_[id] = GdkColorToSkColor(*color); | |
1039 } | |
1040 | |
1041 void Gtk2UI::SetThemeTintFromGtk(int id, const GdkColor* color) { | |
1042 color_utils::HSL default_tint = GetDefaultTint(id); | 889 color_utils::HSL default_tint = GetDefaultTint(id); |
1043 color_utils::HSL hsl; | 890 color_utils::HSL hsl; |
1044 color_utils::SkColorToHSL(GdkColorToSkColor(*color), &hsl); | 891 color_utils::SkColorToHSL(color, &hsl); |
1045 | 892 |
1046 if (default_tint.s != -1) | 893 if (default_tint.s != -1) |
1047 hsl.s = default_tint.s; | 894 hsl.s = default_tint.s; |
1048 | 895 |
1049 if (default_tint.l != -1) | 896 if (default_tint.l != -1) |
1050 hsl.l = default_tint.l; | 897 hsl.l = default_tint.l; |
1051 | 898 |
1052 tints_[id] = hsl; | 899 tints_[id] = hsl; |
1053 } | 900 } |
1054 | 901 |
1055 GdkColor Gtk2UI::BuildAndSetFrameColor(const GdkColor* base, | |
1056 const GdkColor* gtk_base, | |
1057 const color_utils::HSL& tint, | |
1058 int color_id, | |
1059 int tint_id) { | |
1060 GdkColor out_color = *base; | |
1061 if (gtk_base) { | |
1062 // The theme author specified a color to use, use it without modification. | |
1063 out_color = *gtk_base; | |
1064 } else { | |
1065 // Tint the basic color since this is a heuristic color instead of one | |
1066 // specified by the theme author. | |
1067 GdkColorHSLShift(tint, &out_color); | |
1068 } | |
1069 SetThemeColorFromGtk(color_id, &out_color); | |
1070 SetThemeTintFromGtk(tint_id, &out_color); | |
1071 | |
1072 return out_color; | |
1073 } | |
1074 | |
1075 SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const { | 902 SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const { |
1076 switch (id) { | 903 switch (id) { |
1077 case IDR_THEME_TOOLBAR: { | 904 case IDR_THEME_TOOLBAR: { |
1078 GtkStyle* style = gtk_rc_get_style(fake_window_); | |
1079 GdkColor* color = &style->bg[GTK_STATE_NORMAL]; | |
1080 SkBitmap bitmap; | 905 SkBitmap bitmap; |
1081 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight); | 906 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight); |
1082 bitmap.eraseARGB(0xff, color->red >> 8, color->green >> 8, | 907 bitmap.eraseColor( |
1083 color->blue >> 8); | 908 NativeThemeGtk2::instance()->GetSystemColor( |
909 ui::NativeTheme::kColorId_WindowBackground)); | |
1084 return bitmap; | 910 return bitmap; |
1085 } | 911 } |
1086 case IDR_THEME_TAB_BACKGROUND: | 912 case IDR_THEME_TAB_BACKGROUND: |
1087 case IDR_THEME_TAB_BACKGROUND_DESKTOP: | 913 case IDR_THEME_TAB_BACKGROUND_DESKTOP: |
1088 return GenerateTabImage(IDR_THEME_FRAME); | 914 return GenerateTabImage(IDR_THEME_FRAME); |
1089 case IDR_THEME_TAB_BACKGROUND_INCOGNITO: | 915 case IDR_THEME_TAB_BACKGROUND_INCOGNITO: |
1090 case IDR_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP: | 916 case IDR_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP: |
1091 return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO); | 917 return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO); |
1092 case IDR_FRAME: | 918 case IDR_FRAME: |
1093 case IDR_THEME_FRAME: | 919 case IDR_THEME_FRAME: |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1136 case IDR_FORWARD: | 962 case IDR_FORWARD: |
1137 case IDR_FORWARD_D: | 963 case IDR_FORWARD_D: |
1138 case IDR_HOME: | 964 case IDR_HOME: |
1139 case IDR_RELOAD: | 965 case IDR_RELOAD: |
1140 case IDR_RELOAD_D: | 966 case IDR_RELOAD_D: |
1141 case IDR_STOP: | 967 case IDR_STOP: |
1142 case IDR_STOP_D: { | 968 case IDR_STOP_D: { |
1143 return GenerateGTKIcon(id); | 969 return GenerateGTKIcon(id); |
1144 } | 970 } |
1145 case IDR_TOOLBAR_BEZEL_HOVER: | 971 case IDR_TOOLBAR_BEZEL_HOVER: |
1146 return GenerateToolbarBezel(GTK_STATE_PRELIGHT, IDR_TOOLBAR_BEZEL_HOVER); | 972 return GenerateToolbarBezel(ui::NativeTheme::kHovered, IDR_TOOLBAR_BEZEL_H OVER); |
1147 case IDR_TOOLBAR_BEZEL_PRESSED: | 973 case IDR_TOOLBAR_BEZEL_PRESSED: |
1148 return GenerateToolbarBezel(GTK_STATE_ACTIVE, IDR_TOOLBAR_BEZEL_PRESSED); | 974 return GenerateToolbarBezel(ui::NativeTheme::kPressed, IDR_TOOLBAR_BEZEL_P RESSED); |
1149 default: { | 975 default: { |
1150 return GenerateTintedIcon(id, button_tint_); | 976 return GenerateTintedIcon(id, button_tint_); |
1151 } | 977 } |
1152 } | 978 } |
1153 | 979 |
1154 return SkBitmap(); | 980 return SkBitmap(); |
1155 } | 981 } |
1156 | 982 |
1157 SkBitmap Gtk2UI::GenerateFrameImage( | 983 SkBitmap Gtk2UI::GenerateFrameImage( |
1158 int color_id, | 984 int color_id, |
1159 const char* gradient_name) const { | 985 const char* gradient_name) const { |
1160 // We use two colors: the main color (passed in) and a lightened version of | |
1161 // that color (which is supposed to match the light gradient at the top of | |
1162 // several GTK+ themes, such as Ambiance, Clearlooks or Bluebird). | |
1163 ColorMap::const_iterator it = colors_.find(color_id); | 986 ColorMap::const_iterator it = colors_.find(color_id); |
1164 DCHECK(it != colors_.end()); | 987 DCHECK(it != colors_.end()); |
1165 SkColor base = it->second; | 988 SkColor base = it->second; |
1166 | 989 |
990 | |
991 #if GTK_MAJOR_VERSION == 2 | |
992 // We use two colors: the main color (passed in) and a lightened version of | |
993 // that color (which is supposed to match the light gradient at the top of | |
994 // several GTK+ themes, such as Ambiance, Clearlooks or Bluebird). | |
995 const color_utils::HSL kGtkFrameShift = { -1, -1, 0.8 }; | |
1167 gfx::Canvas canvas(gfx::Size(kToolbarImageWidth, kToolbarImageHeight), | 996 gfx::Canvas canvas(gfx::Size(kToolbarImageWidth, kToolbarImageHeight), |
1168 1.0f, true); | 997 1.0f, true); |
1169 | 998 |
999 SkColor gradient_top_color = color_utils::HSLShift(base, kGtkFrameShift); | |
1170 int gradient_size; | 1000 int gradient_size; |
1171 GdkColor* gradient_top_color = NULL; | 1001 |
1172 gtk_widget_style_get(GTK_WIDGET(fake_frame_), | 1002 GetChromeStyleColor(gradient_name, &gradient_top_color); |
1003 gtk_widget_style_get(NativeThemeGtk2::instance()->GetWindow(), | |
1173 "frame-gradient-size", &gradient_size, | 1004 "frame-gradient-size", &gradient_size, |
1174 gradient_name, &gradient_top_color, | |
1175 NULL); | 1005 NULL); |
1006 | |
1176 if (gradient_size) { | 1007 if (gradient_size) { |
1177 SkColor lighter = gradient_top_color ? | |
1178 GdkColorToSkColor(*gradient_top_color) : | |
1179 color_utils::HSLShift(base, kGtkFrameShift); | |
1180 skia::RefPtr<SkShader> shader = gfx::CreateGradientShader( | 1008 skia::RefPtr<SkShader> shader = gfx::CreateGradientShader( |
1181 0, gradient_size, lighter, base); | 1009 0, gradient_size, gradient_top_color, base); |
1182 SkPaint paint; | 1010 SkPaint paint; |
1183 paint.setStyle(SkPaint::kFill_Style); | 1011 paint.setStyle(SkPaint::kFill_Style); |
1184 paint.setAntiAlias(true); | 1012 paint.setAntiAlias(true); |
1185 paint.setShader(shader.get()); | 1013 paint.setShader(shader.get()); |
1186 | 1014 |
1187 canvas.DrawRect(gfx::Rect(0, 0, kToolbarImageWidth, gradient_size), paint); | 1015 canvas.DrawRect(gfx::Rect(0, 0, kToolbarImageWidth, gradient_size), paint); |
1188 } | 1016 } |
1189 | 1017 |
1190 if (gradient_top_color) | |
1191 gdk_color_free(gradient_top_color); | |
1192 | |
1193 canvas.FillRect(gfx::Rect(0, gradient_size, kToolbarImageWidth, | 1018 canvas.FillRect(gfx::Rect(0, gradient_size, kToolbarImageWidth, |
1194 kToolbarImageHeight - gradient_size), base); | 1019 kToolbarImageHeight - gradient_size), base); |
1195 return canvas.ExtractImageRep().sk_bitmap(); | 1020 return canvas.ExtractImageRep().sk_bitmap(); |
1021 | |
1022 #else | |
knthzh
2015/08/24 03:58:18
So, I ended up deciding that the best way to rende
Elliot Glaysher
2015/08/24 17:14:38
Probably not. You should still be able to do by re
knthzh
2015/08/24 20:04:18
Wait, huh?
Elliot Glaysher
2015/08/24 20:14:23
I should not be allowed to write anything before m
| |
1023 // Render a GtkHeaderBar as our title bar, cropping out any curved edges on | |
1024 // the left and right sides. Also remove the bottom border for good measure. | |
1025 SkBitmap bitmap; | |
1026 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight); | |
1027 bitmap.eraseColor(base); | |
1028 | |
1029 | |
1030 static GtkWidget* title = NULL; | |
1031 if (!title) { | |
1032 title = gtk_header_bar_new(); | |
1033 gtk_widget_set_size_request(title, kToolbarImageWidth * 2, 48); | |
1034 | |
1035 GtkWidget* window = gtk_offscreen_window_new(); | |
1036 gtk_container_add(GTK_CONTAINER(window), title); | |
1037 | |
1038 gtk_widget_show_all(window); | |
1039 } | |
1040 | |
1041 cairo_surface_t* surface = cairo_image_surface_create_for_data( | |
1042 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), | |
1043 CAIRO_FORMAT_ARGB32, | |
1044 kToolbarImageWidth, 40, | |
1045 kToolbarImageWidth * 4); | |
1046 cairo_t* cr = cairo_create(surface); | |
1047 cairo_translate(cr, kToolbarImageWidth / -2, 0); | |
1048 gtk_widget_draw(title, cr); | |
1049 cairo_destroy(cr); | |
1050 cairo_surface_destroy(surface); | |
1051 | |
1052 | |
1053 return bitmap; | |
1054 #endif | |
1196 } | 1055 } |
1197 | 1056 |
1198 SkBitmap Gtk2UI::GenerateTabImage(int base_id) const { | 1057 SkBitmap Gtk2UI::GenerateTabImage(int base_id) const { |
1199 const SkBitmap* base_image = GetThemeImageNamed(base_id).ToSkBitmap(); | 1058 const SkBitmap* base_image = GetThemeImageNamed(base_id).ToSkBitmap(); |
1200 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( | 1059 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( |
1201 *base_image, GetDefaultTint(ThemeProperties::TINT_BACKGROUND_TAB)); | 1060 *base_image, GetDefaultTint(ThemeProperties::TINT_BACKGROUND_TAB)); |
1202 return SkBitmapOperations::CreateTiledBitmap( | 1061 return SkBitmapOperations::CreateTiledBitmap( |
1203 bg_tint, 0, 0, bg_tint.width(), bg_tint.height()); | 1062 bg_tint, 0, 0, bg_tint.width(), bg_tint.height()); |
1204 } | 1063 } |
1205 | 1064 |
1206 SkBitmap Gtk2UI::GenerateTintedIcon( | 1065 SkBitmap Gtk2UI::GenerateTintedIcon( |
1207 int base_id, | 1066 int base_id, |
1208 const color_utils::HSL& tint) const { | 1067 const color_utils::HSL& tint) const { |
1209 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1068 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1210 return SkBitmapOperations::CreateHSLShiftedBitmap( | 1069 return SkBitmapOperations::CreateHSLShiftedBitmap( |
1211 rb.GetImageNamed(base_id).AsBitmap(), tint); | 1070 rb.GetImageNamed(base_id).AsBitmap(), tint); |
1212 } | 1071 } |
1213 | 1072 |
1214 SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const { | 1073 SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const { |
1215 const char* stock_id = NULL; | 1074 const char* stock_id = NULL; |
1216 GtkStateType gtk_state = GTK_STATE_NORMAL; | 1075 bool enabled = true; |
1217 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) { | 1076 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) { |
1218 if (kGtkIcons[i].idr == base_id) { | 1077 if (kGtkIcons[i].idr == base_id) { |
1219 stock_id = kGtkIcons[i].stock_id; | 1078 stock_id = kGtkIcons[i].stock_id; |
1220 gtk_state = kGtkIcons[i].gtk_state; | 1079 enabled = kGtkIcons[i].enabled; |
1221 break; | 1080 break; |
1222 } | 1081 } |
1223 } | 1082 } |
1224 DCHECK(stock_id); | 1083 DCHECK(stock_id); |
1225 | 1084 |
1226 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1085 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1227 SkBitmap default_bitmap = rb.GetImageNamed(base_id).AsBitmap(); | 1086 SkBitmap default_bitmap = rb.GetImageNamed(base_id).AsBitmap(); |
1228 | 1087 |
1229 gtk_widget_ensure_style(fake_frame_); | |
1230 GtkStyle* style = gtk_widget_get_style(fake_frame_); | |
1231 GtkIconSet* icon_set = gtk_style_lookup_icon_set(style, stock_id); | |
1232 if (!icon_set) | |
1233 return default_bitmap; | |
1234 | |
1235 // Ask GTK to render the icon to a buffer, which we will steal from. | 1088 // Ask GTK to render the icon to a buffer, which we will steal from. |
1236 GdkPixbuf* gdk_icon = gtk_icon_set_render_icon( | 1089 GtkIconTheme* icon_theme = gtk_icon_theme_get_default(); |
1237 icon_set, | 1090 GdkPixbuf* gdk_icon = gtk_icon_theme_load_icon( |
1238 style, | 1091 icon_theme, |
1239 base::i18n::IsRTL() ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR, | 1092 stock_id, |
1240 gtk_state, | 1093 16, |
1241 GTK_ICON_SIZE_SMALL_TOOLBAR, | 1094 (GtkIconLookupFlags)0, |
1242 fake_frame_, | |
1243 NULL); | 1095 NULL); |
1244 | 1096 |
1245 if (!gdk_icon) { | 1097 if (!gdk_icon) { |
1246 // This can theoretically happen if an icon theme doesn't provide a | 1098 // This can theoretically happen if an icon theme doesn't provide a |
1247 // specific image. This should realistically never happen, but I bet there | 1099 // specific image. This should realistically never happen, but I bet there |
1248 // are some theme authors who don't reliably provide all icons. | 1100 // are some theme authors who don't reliably provide all icons. |
1249 return default_bitmap; | 1101 return default_bitmap; |
1250 } | 1102 } |
1251 | 1103 |
1252 SkBitmap retval; | 1104 SkBitmap retval; |
1253 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); | 1105 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); |
1254 retval.eraseColor(0); | 1106 retval.eraseColor(0); |
1255 | 1107 |
1256 const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon); | 1108 const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon); |
1257 g_object_unref(gdk_icon); | 1109 g_object_unref(gdk_icon); |
1258 | 1110 |
1259 SkCanvas canvas(retval); | 1111 SkCanvas canvas(retval); |
1260 | 1112 |
1261 if (gtk_state == GTK_STATE_ACTIVE || gtk_state == GTK_STATE_PRELIGHT) { | 1113 SkPaint paint; |
1262 SkBitmap border = DrawGtkButtonBorder(gtk_state, | 1114 |
1263 false, | 1115 // GTK3 behavior |
1264 false, | 1116 if (!enabled) |
1265 default_bitmap.width(), | 1117 paint.setAlpha(128); |
1266 default_bitmap.height()); | |
1267 canvas.drawBitmap(border, 0, 0); | |
1268 } | |
1269 | 1118 |
1270 canvas.drawBitmap(icon, | 1119 canvas.drawBitmap(icon, |
1271 (default_bitmap.width() / 2) - (icon.width() / 2), | 1120 (default_bitmap.width() / 2) - (icon.width() / 2), |
1272 (default_bitmap.height() / 2) - (icon.height() / 2)); | 1121 (default_bitmap.height() / 2) - (icon.height() / 2), |
1122 &paint); | |
1273 | 1123 |
1274 return retval; | 1124 return retval; |
1275 } | 1125 } |
1276 | 1126 |
1277 SkBitmap Gtk2UI::GenerateToolbarBezel(int gtk_state, int sizing_idr) const { | 1127 SkBitmap Gtk2UI::GenerateToolbarBezel( |
1128 ui::NativeTheme::State state, | |
1129 int sizing_idr) const { | |
1278 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1130 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1279 SkBitmap default_bitmap = | 1131 SkBitmap default_bitmap = |
1280 rb.GetImageNamed(sizing_idr).AsBitmap(); | 1132 rb.GetImageNamed(sizing_idr).AsBitmap(); |
1281 | 1133 |
1282 SkBitmap retval; | 1134 return DrawGtkButtonBorder( |
1283 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); | 1135 NULL, |
1284 retval.eraseColor(0); | 1136 state, |
1285 | |
1286 SkCanvas canvas(retval); | |
1287 SkBitmap border = DrawGtkButtonBorder( | |
1288 gtk_state, | |
1289 false, | |
1290 false, | |
1291 default_bitmap.width(), | 1137 default_bitmap.width(), |
1292 default_bitmap.height()); | 1138 default_bitmap.height()); |
1293 canvas.drawBitmap(border, 0, 0); | |
1294 | |
1295 return retval; | |
1296 } | 1139 } |
1297 | 1140 |
1298 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { | 1141 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { |
1299 GtkStyle* window_style = gtk_rc_get_style(fake_window_); | 1142 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
1300 const GdkColor accent_gdk_color = window_style->bg[GTK_STATE_SELECTED]; | |
1301 const GdkColor base_color = window_style->base[GTK_STATE_NORMAL]; | |
1302 | 1143 |
1303 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); | 1144 SkColor accent_color = |
1304 const GdkColor text_color = label_style->fg[GTK_STATE_NORMAL]; | 1145 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor); |
1146 SkColor text_color = | |
1147 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelEnabledColor); | |
1148 SkColor base_color = | |
1149 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelBackgroundColor); | |
1305 | 1150 |
1306 PickButtonTintFromColors(accent_gdk_color, text_color, base_color, tint); | 1151 PickButtonTintFromColors(accent_color, text_color, base_color, tint); |
1307 } | 1152 } |
1308 | 1153 |
1309 void Gtk2UI::GetNormalEntryForegroundHSL(color_utils::HSL* tint) const { | 1154 void Gtk2UI::GetNormalEntryForegroundHSL(color_utils::HSL* tint) const { |
1310 GtkStyle* window_style = gtk_rc_get_style(fake_window_); | 1155 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
1311 const GdkColor accent_gdk_color = window_style->bg[GTK_STATE_SELECTED]; | |
1312 | 1156 |
1313 GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); | 1157 SkColor accent_color = |
1314 const GdkColor text_color = style->text[GTK_STATE_NORMAL]; | 1158 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor); |
1315 const GdkColor base_color = style->base[GTK_STATE_NORMAL]; | 1159 SkColor text_color = |
1160 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultColor); | |
1161 SkColor base_color = | |
1162 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultBackground ); | |
1316 | 1163 |
1317 PickButtonTintFromColors(accent_gdk_color, text_color, base_color, tint); | 1164 PickButtonTintFromColors(accent_color, text_color, base_color, tint); |
1318 } | 1165 } |
1319 | 1166 |
1320 void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const { | 1167 void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const { |
1321 // The simplest of all the tints. We just use the selected text in the entry | 1168 // The simplest of all the tints. We just use the selected text in the entry |
1322 // since the icons tinted this way will only be displayed against | 1169 // since the icons tinted this way will only be displayed against |
1323 // base[GTK_STATE_SELECTED]. | 1170 // base[GTK_STATE_SELECTED]. |
1324 GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); | 1171 SkColor color = |
1325 const GdkColor color = style->text[GTK_STATE_SELECTED]; | 1172 NativeThemeGtk2::instance()->GetSystemColor( |
1326 color_utils::SkColorToHSL(GdkColorToSkColor(color), tint); | 1173 ui::NativeTheme::kColorId_TextfieldSelectionColor); |
1174 | |
1175 color_utils::SkColorToHSL(color, tint); | |
1327 } | 1176 } |
1328 | 1177 |
1329 SkBitmap Gtk2UI::DrawGtkButtonBorder(int gtk_state, | 1178 SkBitmap Gtk2UI::DrawGtkButtonBorder(const char* class_name, |
1330 bool focused, | 1179 ui::NativeTheme::State state, |
1331 bool call_to_action, | |
1332 int width, | 1180 int width, |
1333 int height) const { | 1181 int height) const { |
1182 SkBitmap border; | |
1183 border.allocN32Pixels(width, height); | |
1184 border.eraseColor(0); | |
1185 | |
1334 // Create a temporary GTK button to snapshot | 1186 // Create a temporary GTK button to snapshot |
1335 GtkWidget* window = gtk_offscreen_window_new(); | 1187 GtkWidget* window = gtk_offscreen_window_new(); |
1336 GtkWidget* button = gtk_button_new(); | 1188 GtkWidget* button = gtk_toggle_button_new(); |
1189 | |
1190 if (state == ui::NativeTheme::kPressed) | |
1191 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), true); | |
1192 else if (state == ui::NativeTheme::kDisabled) | |
1193 gtk_widget_set_sensitive(button, false); | |
1194 | |
1337 gtk_widget_set_size_request(button, width, height); | 1195 gtk_widget_set_size_request(button, width, height); |
1338 gtk_container_add(GTK_CONTAINER(window), button); | 1196 gtk_container_add(GTK_CONTAINER(window), button); |
1339 gtk_widget_realize(window); | |
1340 gtk_widget_realize(button); | |
1341 gtk_widget_show(button); | |
1342 gtk_widget_show(window); | |
1343 | 1197 |
1344 if (call_to_action) | 1198 if (class_name == views::BlueButton::kViewClassName) { |
1345 GTK_WIDGET_SET_FLAGS(button, GTK_HAS_DEFAULT); | 1199 gtk_widget_set_can_default(button, true); |
1346 | 1200 gtk_widget_grab_default(button); |
1347 if (focused) { | |
1348 // We can't just use gtk_widget_grab_focus() here because that sets | |
1349 // gtk_widget_is_focus(), but not gtk_widget_has_focus(), which is what the | |
1350 // GtkButton's paint checks. | |
1351 GTK_WIDGET_SET_FLAGS(button, GTK_HAS_FOCUS); | |
1352 } | 1201 } |
1353 | 1202 |
1354 gtk_widget_set_state(button, static_cast<GtkStateType>(gtk_state)); | 1203 gtk_widget_show_all(window); |
1355 | 1204 |
1356 GdkPixmap* pixmap; | 1205 |
1357 { | 1206 cairo_surface_t* surface = cairo_image_surface_create_for_data( |
1358 // http://crbug.com/346740 | 1207 static_cast<unsigned char*>(border.getAddr(0, 0)), |
1359 ANNOTATE_SCOPED_MEMORY_LEAK; | 1208 CAIRO_FORMAT_ARGB32, |
1360 pixmap = gtk_widget_get_snapshot(button, NULL); | 1209 width, height, |
1361 } | 1210 width * 4); |
1211 cairo_t* cr = cairo_create(surface); | |
1212 | |
1213 #if GTK_MAJOR_VERSION == 2 | |
1362 int w, h; | 1214 int w, h; |
1215 GdkPixmap* pixmap = gtk_widget_get_snapshot(button, NULL); | |
1363 gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h); | 1216 gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h); |
1364 DCHECK_EQ(w, width); | |
1365 DCHECK_EQ(h, height); | |
1366 | |
1367 // We render the Pixmap to a Pixbuf. This can be slow, as we're scrapping | |
1368 // bits from X. | |
1369 GdkColormap* colormap = gdk_drawable_get_colormap(pixmap); | 1217 GdkColormap* colormap = gdk_drawable_get_colormap(pixmap); |
1370 GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(NULL, | 1218 GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(NULL, |
1371 GDK_DRAWABLE(pixmap), | 1219 GDK_DRAWABLE(pixmap), |
1372 colormap, | 1220 colormap, |
1373 0, 0, 0, 0, w, h); | 1221 0, 0, 0, 0, w, h); |
1374 | 1222 |
1375 // Finally, we convert our pixbuf into a type we can use. | 1223 gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); |
1376 SkBitmap border = GdkPixbufToImageSkia(pixbuf); | 1224 cairo_paint(cr); |
1225 | |
1377 g_object_unref(pixbuf); | 1226 g_object_unref(pixbuf); |
1378 g_object_unref(pixmap); | 1227 g_object_unref(pixmap); |
1228 #else | |
1229 gtk_widget_draw(button, cr); | |
1230 #endif | |
1231 | |
1232 cairo_destroy(cr); | |
1233 cairo_surface_destroy(surface); | |
1234 | |
1235 | |
1379 gtk_widget_destroy(window); | 1236 gtk_widget_destroy(window); |
1380 | 1237 |
1381 return border; | 1238 return border; |
1382 } | 1239 } |
1383 | 1240 |
1384 void Gtk2UI::ClearAllThemeData() { | 1241 void Gtk2UI::ClearAllThemeData() { |
1385 gtk_images_.clear(); | 1242 gtk_images_.clear(); |
1386 } | 1243 } |
1387 | 1244 |
1388 void Gtk2UI::UpdateDefaultFont(const PangoFontDescription* desc) { | 1245 void Gtk2UI::UpdateDefaultFont() { |
1246 GtkStyle* style = gtk_rc_get_style(NativeThemeGtk2::instance()->GetLabel()); | |
1247 const PangoFontDescription* desc = style->font_desc; | |
1248 | |
1389 // Use gfx::FontRenderParams to select a family and determine the rendering | 1249 // Use gfx::FontRenderParams to select a family and determine the rendering |
1390 // settings. | 1250 // settings. |
1391 gfx::FontRenderParamsQuery query; | 1251 gfx::FontRenderParamsQuery query; |
1392 query.families = base::SplitString(pango_font_description_get_family(desc), | 1252 query.families = base::SplitString(pango_font_description_get_family(desc), |
1393 ",", base::TRIM_WHITESPACE, | 1253 ",", base::TRIM_WHITESPACE, |
1394 base::SPLIT_WANT_ALL); | 1254 base::SPLIT_WANT_ALL); |
1395 | 1255 |
1396 if (pango_font_description_get_size_is_absolute(desc)) { | 1256 if (pango_font_description_get_size_is_absolute(desc)) { |
1397 // If the size is absolute, it's specified in Pango units. There are | 1257 // If the size is absolute, it's specified in Pango units. There are |
1398 // PANGO_SCALE Pango units in a device unit (pixel). | 1258 // PANGO_SCALE Pango units in a device unit (pixel). |
(...skipping 16 matching lines...) Expand all Loading... | |
1415 query.style |= gfx::Font::BOLD; | 1275 query.style |= gfx::Font::BOLD; |
1416 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? | 1276 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? |
1417 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) | 1277 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) |
1418 query.style |= gfx::Font::ITALIC; | 1278 query.style |= gfx::Font::ITALIC; |
1419 | 1279 |
1420 default_font_render_params_ = | 1280 default_font_render_params_ = |
1421 gfx::GetFontRenderParams(query, &default_font_family_); | 1281 gfx::GetFontRenderParams(query, &default_font_family_); |
1422 default_font_style_ = query.style; | 1282 default_font_style_ = query.style; |
1423 } | 1283 } |
1424 | 1284 |
1425 void Gtk2UI::OnStyleSet(GtkWidget* widget, GtkStyle* previous_style) { | 1285 void Gtk2UI::ResetStyle() { |
1426 ClearAllThemeData(); | 1286 ClearAllThemeData(); |
1427 LoadGtkValues(); | 1287 LoadGtkValues(); |
1428 NativeThemeGtk2::instance()->NotifyObservers(); | 1288 NativeThemeGtk2::instance()->NotifyObservers(); |
1429 } | 1289 } |
1430 | 1290 |
1431 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { | 1291 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { |
1432 device_scale_factor_ = device_scale_factor; | 1292 device_scale_factor_ = device_scale_factor; |
1433 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); | 1293 UpdateDefaultFont(); |
1434 UpdateDefaultFont(label_style->font_desc); | |
1435 } | 1294 } |
1436 | 1295 |
1437 float Gtk2UI::GetDeviceScaleFactor() const { | 1296 float Gtk2UI::GetDeviceScaleFactor() const { |
1438 if (gfx::Display::HasForceDeviceScaleFactor()) | 1297 if (gfx::Display::HasForceDeviceScaleFactor()) |
1439 return gfx::Display::GetForcedDeviceScaleFactor(); | 1298 return gfx::Display::GetForcedDeviceScaleFactor(); |
1440 const int kCSSDefaultDPI = 96; | 1299 const int kCSSDefaultDPI = 96; |
1441 float scale = GetDPI() / kCSSDefaultDPI; | 1300 float scale = GetDPI() / kCSSDefaultDPI; |
1442 // Round to 1 decimal, e.g. to 1.4. | 1301 // Round to 1 decimal, e.g. to 1.4. |
1443 return roundf(scale * 10) / 10; | 1302 return roundf(scale * 10) / 10; |
1444 } | 1303 } |
1445 | 1304 |
1446 } // namespace libgtk2ui | 1305 } // namespace libgtk2ui |
1447 | 1306 |
1448 views::LinuxUI* BuildGtk2UI() { | 1307 views::LinuxUI* BuildGtk2UI() { |
1449 return new libgtk2ui::Gtk2UI; | 1308 return new libgtk2ui::Gtk2UI; |
1450 } | 1309 } |
OLD | NEW |