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