Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / ui / libgtk2ui / native_theme_gtk2.cc
blob2088824222adb91b0a4f1cb0ecdc77eef36e258c
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h"
7 #include <gtk/gtk.h>
9 #include "chrome/browser/ui/libgtk2ui/chrome_gtk_menu_subclasses.h"
10 #include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
11 #include "ui/gfx/color_utils.h"
12 #include "ui/gfx/path.h"
13 #include "ui/gfx/rect.h"
14 #include "ui/gfx/size.h"
15 #include "ui/gfx/skia_util.h"
16 #include "ui/native_theme/common_theme.h"
18 namespace {
20 // Theme colors returned by GetSystemColor().
21 const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128);
23 const GdkColor kURLTextColor = GDK_COLOR_RGB(0x00, 0x88, 0x00);
25 GdkColor GdkAlphaBlend(GdkColor foreground,
26 GdkColor background,
27 SkAlpha alpha) {
28 return libgtk2ui::SkColorToGdkColor(
29 color_utils::AlphaBlend(libgtk2ui::GdkColorToSkColor(foreground),
30 libgtk2ui::GdkColorToSkColor(background), alpha));
33 // Generates the normal URL color, a green color used in unhighlighted URL
34 // text. It is a mix of |kURLTextColor| and the current text color. Unlike the
35 // selected text color, it is more important to match the qualities of the
36 // foreground typeface color instead of taking the background into account.
37 GdkColor NormalURLColor(GdkColor foreground) {
38 color_utils::HSL fg_hsl;
39 color_utils::SkColorToHSL(libgtk2ui::GdkColorToSkColor(foreground), &fg_hsl);
41 color_utils::HSL hue_hsl;
42 color_utils::SkColorToHSL(libgtk2ui::GdkColorToSkColor(kURLTextColor),
43 &hue_hsl);
45 // Only allow colors that have a fair amount of saturation in them (color vs
46 // white). This means that our output color will always be fairly green.
47 double s = std::max(0.5, fg_hsl.s);
49 // Make sure the luminance is at least as bright as the |kURLTextColor| green
50 // would be if we were to use that.
51 double l;
52 if (fg_hsl.l < hue_hsl.l)
53 l = hue_hsl.l;
54 else
55 l = (fg_hsl.l + hue_hsl.l) / 2;
57 color_utils::HSL output = { hue_hsl.h, s, l };
58 return libgtk2ui::SkColorToGdkColor(color_utils::HSLToSkColor(output, 255));
61 // Generates the selected URL color, a green color used on URL text in the
62 // currently highlighted entry in the autocomplete popup. It's a mix of
63 // |kURLTextColor|, the current text color, and the background color (the
64 // select highlight). It is more important to contrast with the background
65 // saturation than to look exactly like the foreground color.
66 GdkColor SelectedURLColor(GdkColor foreground, GdkColor background) {
67 color_utils::HSL fg_hsl;
68 color_utils::SkColorToHSL(libgtk2ui::GdkColorToSkColor(foreground),
69 &fg_hsl);
71 color_utils::HSL bg_hsl;
72 color_utils::SkColorToHSL(libgtk2ui::GdkColorToSkColor(background),
73 &bg_hsl);
75 color_utils::HSL hue_hsl;
76 color_utils::SkColorToHSL(libgtk2ui::GdkColorToSkColor(kURLTextColor),
77 &hue_hsl);
79 // The saturation of the text should be opposite of the background, clamped
80 // to 0.2-0.8. We make sure it's greater than 0.2 so there's some color, but
81 // less than 0.8 so it's not the oversaturated neon-color.
82 double opposite_s = 1 - bg_hsl.s;
83 double s = std::max(0.2, std::min(0.8, opposite_s));
85 // The luminance should match the luminance of the foreground text. Again,
86 // we clamp so as to have at some amount of color (green) in the text.
87 double opposite_l = fg_hsl.l;
88 double l = std::max(0.1, std::min(0.9, opposite_l));
90 color_utils::HSL output = { hue_hsl.h, s, l };
91 return libgtk2ui::SkColorToGdkColor(color_utils::HSLToSkColor(output, 255));
94 } // namespace
97 namespace libgtk2ui {
99 // static
100 NativeThemeGtk2* NativeThemeGtk2::instance() {
101 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk2, s_native_theme, ());
102 return &s_native_theme;
105 NativeThemeGtk2::NativeThemeGtk2()
106 : fake_window_(NULL),
107 fake_menu_item_(NULL) {
110 NativeThemeGtk2::~NativeThemeGtk2() {
111 if (fake_window_)
112 gtk_widget_destroy(fake_window_);
113 fake_entry_.Destroy();
114 fake_label_.Destroy();
115 fake_button_.Destroy();
116 fake_tree_.Destroy();
117 fake_menu_.Destroy();
120 SkColor NativeThemeGtk2::GetSystemColor(ColorId color_id) const {
121 return GdkColorToSkColor(GetSystemGdkColor(color_id));
124 void NativeThemeGtk2::PaintMenuPopupBackground(
125 SkCanvas* canvas,
126 const gfx::Size& size,
127 const MenuBackgroundExtraParams& menu_background) const {
128 if (menu_background.corner_radius > 0) {
129 SkPaint paint;
130 paint.setStyle(SkPaint::kFill_Style);
131 paint.setFlags(SkPaint::kAntiAlias_Flag);
132 paint.setColor(GetSystemColor(kColorId_MenuBackgroundColor));
134 gfx::Path path;
135 SkRect rect = SkRect::MakeWH(SkIntToScalar(size.width()),
136 SkIntToScalar(size.height()));
137 SkScalar radius = SkIntToScalar(menu_background.corner_radius);
138 SkScalar radii[8] = {radius, radius, radius, radius,
139 radius, radius, radius, radius};
140 path.addRoundRect(rect, radii);
142 canvas->drawPath(path, paint);
143 } else {
144 canvas->drawColor(GetSystemColor(kColorId_MenuBackgroundColor),
145 SkXfermode::kSrc_Mode);
149 void NativeThemeGtk2::PaintMenuItemBackground(
150 SkCanvas* canvas,
151 State state,
152 const gfx::Rect& rect,
153 const MenuListExtraParams& menu_list) const {
154 SkColor color;
155 SkPaint paint;
156 switch (state) {
157 case NativeTheme::kNormal:
158 case NativeTheme::kDisabled:
159 color = GetSystemColor(NativeTheme::kColorId_MenuBackgroundColor);
160 paint.setColor(color);
161 break;
162 case NativeTheme::kHovered:
163 color = GetSystemColor(
164 NativeTheme::kColorId_FocusedMenuItemBackgroundColor);
165 paint.setColor(color);
166 break;
167 default:
168 NOTREACHED() << "Invalid state " << state;
169 break;
171 canvas->drawRect(gfx::RectToSkRect(rect), paint);
174 void NativeThemeGtk2::NotifyNativeThemeObservers() {
175 NotifyObservers();
178 GdkColor NativeThemeGtk2::GetSystemGdkColor(ColorId color_id) const {
179 switch (color_id) {
180 // Windows
181 case kColorId_WindowBackground:
182 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
184 // Dialogs
185 case kColorId_DialogBackground:
186 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
188 // FocusableBorder
189 case kColorId_FocusedBorderColor:
190 return GetEntryStyle()->bg[GTK_STATE_SELECTED];
191 case kColorId_UnfocusedBorderColor:
192 return GetEntryStyle()->text_aa[GTK_STATE_NORMAL];
194 // MenuItem
195 case kColorId_EnabledMenuItemForegroundColor:
196 case kColorId_DisabledEmphasizedMenuItemForegroundColor:
197 return GetMenuItemStyle()->text[GTK_STATE_NORMAL];
198 case kColorId_DisabledMenuItemForegroundColor:
199 return GetMenuItemStyle()->text[GTK_STATE_INSENSITIVE];
200 case kColorId_SelectedMenuItemForegroundColor:
201 return GetMenuItemStyle()->text[GTK_STATE_SELECTED];
202 case kColorId_FocusedMenuItemBackgroundColor:
203 return GetMenuItemStyle()->bg[GTK_STATE_SELECTED];
204 case kColorId_HoverMenuItemBackgroundColor:
205 return GetMenuItemStyle()->bg[GTK_STATE_PRELIGHT];
206 case kColorId_FocusedMenuButtonBorderColor:
207 return GetEntryStyle()->bg[GTK_STATE_NORMAL];
208 case kColorId_HoverMenuButtonBorderColor:
209 return GetEntryStyle()->text_aa[GTK_STATE_PRELIGHT];
210 case kColorId_MenuBorderColor:
211 case kColorId_EnabledMenuButtonBorderColor:
212 case kColorId_MenuSeparatorColor: {
213 return GetMenuItemStyle()->text[GTK_STATE_INSENSITIVE];
215 case kColorId_MenuBackgroundColor:
216 return GetMenuStyle()->bg[GTK_STATE_NORMAL];
218 // Label
219 case kColorId_LabelEnabledColor:
220 return GetLabelStyle()->text[GTK_STATE_NORMAL];
221 case kColorId_LabelDisabledColor:
222 return GetLabelStyle()->text[GTK_STATE_INSENSITIVE];
223 case kColorId_LabelBackgroundColor:
224 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
226 // Button
227 case kColorId_ButtonBackgroundColor:
228 return GetButtonStyle()->bg[GTK_STATE_NORMAL];
229 case kColorId_ButtonEnabledColor:
230 return GetButtonStyle()->text[GTK_STATE_NORMAL];
231 case kColorId_ButtonDisabledColor:
232 return GetButtonStyle()->text[GTK_STATE_INSENSITIVE];
233 case kColorId_ButtonHighlightColor:
234 return GetButtonStyle()->base[GTK_STATE_SELECTED];
235 case kColorId_ButtonHoverColor:
236 return GetButtonStyle()->text[GTK_STATE_PRELIGHT];
237 case kColorId_ButtonHoverBackgroundColor:
238 return GetButtonStyle()->bg[GTK_STATE_PRELIGHT];
240 // Textfield
241 case kColorId_TextfieldDefaultColor:
242 return GetEntryStyle()->text[GTK_STATE_NORMAL];
243 case kColorId_TextfieldDefaultBackground:
244 return GetEntryStyle()->base[GTK_STATE_NORMAL];
245 case kColorId_TextfieldReadOnlyColor:
246 return GetEntryStyle()->text[GTK_STATE_INSENSITIVE];
247 case kColorId_TextfieldReadOnlyBackground:
248 return GetEntryStyle()->base[GTK_STATE_INSENSITIVE];
249 case kColorId_TextfieldSelectionColor:
250 return GetEntryStyle()->text[GTK_STATE_SELECTED];
251 case kColorId_TextfieldSelectionBackgroundFocused:
252 return GetEntryStyle()->base[GTK_STATE_SELECTED];
254 // Tooltips
255 case kColorId_TooltipBackground:
256 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
258 // Trees and Tables (implemented on GTK using the same class)
259 case kColorId_TableBackground:
260 case kColorId_TreeBackground:
261 return GetTreeStyle()->bg[GTK_STATE_NORMAL];
262 case kColorId_TableText:
263 case kColorId_TreeText:
264 return GetTreeStyle()->text[GTK_STATE_NORMAL];
265 case kColorId_TableSelectedText:
266 case kColorId_TableSelectedTextUnfocused:
267 case kColorId_TreeSelectedText:
268 case kColorId_TreeSelectedTextUnfocused:
269 return GetTreeStyle()->text[GTK_STATE_SELECTED];
270 case kColorId_TableSelectionBackgroundFocused:
271 case kColorId_TableSelectionBackgroundUnfocused:
272 case kColorId_TreeSelectionBackgroundFocused:
273 case kColorId_TreeSelectionBackgroundUnfocused:
274 return GetTreeStyle()->bg[GTK_STATE_SELECTED];
275 case kColorId_TreeArrow:
276 return GetTreeStyle()->fg[GTK_STATE_NORMAL];
277 case kColorId_TableGroupingIndicatorColor:
278 return GetTreeStyle()->text_aa[GTK_STATE_NORMAL];
280 // Results Table
281 case kColorId_ResultsTableNormalBackground:
282 return GetEntryStyle()->base[GTK_STATE_NORMAL];
283 case kColorId_ResultsTableHoveredBackground: {
284 GtkStyle* entry_style = GetEntryStyle();
285 return GdkAlphaBlend(
286 entry_style->base[GTK_STATE_NORMAL],
287 entry_style->base[GTK_STATE_SELECTED], 0x80);
289 case kColorId_ResultsTableSelectedBackground:
290 return GetEntryStyle()->base[GTK_STATE_SELECTED];
291 case kColorId_ResultsTableNormalText:
292 case kColorId_ResultsTableHoveredText:
293 return GetEntryStyle()->text[GTK_STATE_NORMAL];
294 case kColorId_ResultsTableSelectedText:
295 return GetEntryStyle()->text[GTK_STATE_SELECTED];
296 case kColorId_ResultsTableNormalDimmedText:
297 case kColorId_ResultsTableHoveredDimmedText: {
298 GtkStyle* entry_style = GetEntryStyle();
299 return GdkAlphaBlend(
300 entry_style->text[GTK_STATE_NORMAL],
301 entry_style->base[GTK_STATE_NORMAL], 0x80);
303 case kColorId_ResultsTableSelectedDimmedText: {
304 GtkStyle* entry_style = GetEntryStyle();
305 return GdkAlphaBlend(
306 entry_style->text[GTK_STATE_SELECTED],
307 entry_style->base[GTK_STATE_NORMAL], 0x80);
309 case kColorId_ResultsTableNormalUrl:
310 case kColorId_ResultsTableHoveredUrl: {
311 return NormalURLColor(GetEntryStyle()->text[GTK_STATE_NORMAL]);
313 case kColorId_ResultsTableSelectedUrl: {
314 GtkStyle* entry_style = GetEntryStyle();
315 return SelectedURLColor(entry_style->text[GTK_STATE_SELECTED],
316 entry_style->base[GTK_STATE_SELECTED]);
318 case kColorId_ResultsTableNormalDivider: {
319 GtkStyle* win_style = GetWindowStyle();
320 return GdkAlphaBlend(win_style->text[GTK_STATE_NORMAL],
321 win_style->bg[GTK_STATE_NORMAL], 0x34);
323 case kColorId_ResultsTableHoveredDivider: {
324 GtkStyle* win_style = GetWindowStyle();
325 return GdkAlphaBlend(win_style->text[GTK_STATE_PRELIGHT],
326 win_style->bg[GTK_STATE_PRELIGHT], 0x34);
328 case kColorId_ResultsTableSelectedDivider: {
329 GtkStyle* win_style = GetWindowStyle();
330 return GdkAlphaBlend(win_style->text[GTK_STATE_SELECTED],
331 win_style->bg[GTK_STATE_SELECTED], 0x34);
335 return SkColorToGdkColor(kInvalidColorIdColor);
338 GtkWidget* NativeThemeGtk2::GetRealizedWindow() const {
339 if (!fake_window_) {
340 fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
341 gtk_widget_realize(fake_window_);
344 return fake_window_;
347 GtkStyle* NativeThemeGtk2::GetWindowStyle() const {
348 return gtk_rc_get_style(GetRealizedWindow());
351 GtkStyle* NativeThemeGtk2::GetEntryStyle() const {
352 if (!fake_entry_.get()) {
353 fake_entry_.Own(gtk_entry_new());
355 // The fake entry needs to be in the window so it can be realized sow e can
356 // use the computed parts of the style.
357 gtk_container_add(GTK_CONTAINER(GetRealizedWindow()), fake_entry_.get());
358 gtk_widget_realize(fake_entry_.get());
360 return gtk_rc_get_style(fake_entry_.get());
363 GtkStyle* NativeThemeGtk2::GetLabelStyle() const {
364 if (!fake_label_.get())
365 fake_label_.Own(gtk_label_new(""));
367 return gtk_rc_get_style(fake_label_.get());
370 GtkStyle* NativeThemeGtk2::GetButtonStyle() const {
371 if (!fake_button_.get())
372 fake_button_.Own(gtk_button_new());
374 return gtk_rc_get_style(fake_button_.get());
377 GtkStyle* NativeThemeGtk2::GetTreeStyle() const {
378 if (!fake_tree_.get())
379 fake_tree_.Own(gtk_tree_view_new());
381 return gtk_rc_get_style(fake_tree_.get());
384 GtkStyle* NativeThemeGtk2::GetMenuStyle() const {
385 if (!fake_menu_.get())
386 fake_menu_.Own(gtk_menu_new());
387 return gtk_rc_get_style(fake_menu_.get());
390 GtkStyle* NativeThemeGtk2::GetMenuItemStyle() const {
391 if (!fake_menu_item_) {
392 if (!fake_menu_.get())
393 fake_menu_.Own(gtk_custom_menu_new());
395 fake_menu_item_ = gtk_custom_menu_item_new();
396 gtk_menu_shell_append(GTK_MENU_SHELL(fake_menu_.get()), fake_menu_item_);
399 return gtk_rc_get_style(fake_menu_item_);
402 } // namespace libgtk2ui