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"
9 #include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
10 #include "ui/gfx/color_utils.h"
11 #include "ui/gfx/path.h"
12 #include "ui/gfx/rect.h"
13 #include "ui/gfx/size.h"
14 #include "ui/gfx/skia_util.h"
15 #include "ui/native_theme/common_theme.h"
19 // Theme colors returned by GetSystemColor().
20 const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128);
22 const SkColor kTreeBackground = SK_ColorWHITE;
23 const SkColor kTreeTextColor = SK_ColorBLACK;
24 const SkColor kTreeSelectedTextColor = SK_ColorBLACK;
25 const SkColor kTreeSelectionBackgroundColor = SkColorSetRGB(0xEE, 0xEE, 0xEE);
26 const SkColor kTreeArrowColor = SkColorSetRGB(0x7A, 0x7A, 0x7A);
28 const SkColor kTableBackground = SK_ColorWHITE;
29 const SkColor kTableTextColor = SK_ColorBLACK;
30 const SkColor kTableSelectedTextColor = SK_ColorBLACK;
31 const SkColor kTableSelectionBackgroundColor = SkColorSetRGB(0xEE, 0xEE, 0xEE);
32 const SkColor kTableGroupingIndicatorColor = SkColorSetRGB(0xCC, 0xCC, 0xCC);
40 NativeThemeGtk2* NativeThemeGtk2::instance() {
41 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk2, s_native_theme, ());
42 return &s_native_theme;
45 NativeThemeGtk2::NativeThemeGtk2()
47 fake_menu_item_(NULL) {
50 NativeThemeGtk2::~NativeThemeGtk2() {
52 gtk_widget_destroy(fake_window_);
53 fake_entry_.Destroy();
54 fake_label_.Destroy();
55 fake_button_.Destroy();
59 SkColor NativeThemeGtk2::GetSystemColor(ColorId color_id) const {
61 // TODO(erg): Still need to fish the colors out of trees and tables.
64 case kColorId_TreeBackground:
65 return kTreeBackground;
66 case kColorId_TreeText:
67 return kTreeTextColor;
68 case kColorId_TreeSelectedText:
69 case kColorId_TreeSelectedTextUnfocused:
70 return kTreeSelectedTextColor;
71 case kColorId_TreeSelectionBackgroundFocused:
72 case kColorId_TreeSelectionBackgroundUnfocused:
73 return kTreeSelectionBackgroundColor;
74 case kColorId_TreeArrow:
75 return kTreeArrowColor;
78 case kColorId_TableBackground:
79 return kTableBackground;
80 case kColorId_TableText:
81 return kTableTextColor;
82 case kColorId_TableSelectedText:
83 case kColorId_TableSelectedTextUnfocused:
84 return kTableSelectedTextColor;
85 case kColorId_TableSelectionBackgroundFocused:
86 case kColorId_TableSelectionBackgroundUnfocused:
87 return kTableSelectionBackgroundColor;
88 case kColorId_TableGroupingIndicatorColor:
89 return kTableGroupingIndicatorColor;
96 return GdkColorToSkColor(GetSystemGdkColor(color_id));
99 void NativeThemeGtk2::PaintMenuPopupBackground(
101 const gfx::Size& size,
102 const MenuBackgroundExtraParams& menu_background) const {
103 if (menu_background.corner_radius > 0) {
105 paint.setStyle(SkPaint::kFill_Style);
106 paint.setFlags(SkPaint::kAntiAlias_Flag);
107 paint.setColor(GetSystemColor(kColorId_MenuBackgroundColor));
110 SkRect rect = SkRect::MakeWH(SkIntToScalar(size.width()),
111 SkIntToScalar(size.height()));
112 SkScalar radius = SkIntToScalar(menu_background.corner_radius);
113 SkScalar radii[8] = {radius, radius, radius, radius,
114 radius, radius, radius, radius};
115 path.addRoundRect(rect, radii);
117 canvas->drawPath(path, paint);
119 canvas->drawColor(GetSystemColor(kColorId_MenuBackgroundColor),
120 SkXfermode::kSrc_Mode);
124 void NativeThemeGtk2::PaintMenuItemBackground(
127 const gfx::Rect& rect,
128 const MenuListExtraParams& menu_list) const {
132 case NativeTheme::kNormal:
133 case NativeTheme::kDisabled:
134 color = GetSystemColor(NativeTheme::kColorId_MenuBackgroundColor);
135 paint.setColor(color);
137 case NativeTheme::kHovered:
138 color = GetSystemColor(
139 NativeTheme::kColorId_FocusedMenuItemBackgroundColor);
140 paint.setColor(color);
143 NOTREACHED() << "Invalid state " << state;
146 canvas->drawRect(gfx::RectToSkRect(rect), paint);
149 GdkColor NativeThemeGtk2::GetSystemGdkColor(ColorId color_id) const {
152 case kColorId_WindowBackground:
153 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
156 case kColorId_DialogBackground:
157 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
160 case kColorId_FocusedBorderColor:
161 return GetEntryStyle()->bg[GTK_STATE_SELECTED];
162 case kColorId_UnfocusedBorderColor:
163 return GetEntryStyle()->text_aa[GTK_STATE_NORMAL];
166 case kColorId_EnabledMenuItemForegroundColor:
167 return GetMenuItemStyle()->text[GTK_STATE_NORMAL];
168 case kColorId_DisabledMenuItemForegroundColor:
169 return GetMenuItemStyle()->text[GTK_STATE_INSENSITIVE];
170 case kColorId_SelectedMenuItemForegroundColor:
171 return GetMenuItemStyle()->text[GTK_STATE_SELECTED];
172 case kColorId_FocusedMenuItemBackgroundColor:
173 return GetMenuItemStyle()->bg[GTK_STATE_SELECTED];
174 case kColorId_HoverMenuItemBackgroundColor:
175 return GetMenuItemStyle()->bg[GTK_STATE_PRELIGHT];
176 case kColorId_FocusedMenuButtonBorderColor:
177 return GetEntryStyle()->bg[GTK_STATE_NORMAL];
178 case kColorId_HoverMenuButtonBorderColor:
179 return GetEntryStyle()->text_aa[GTK_STATE_PRELIGHT];
180 case kColorId_MenuBorderColor:
181 case kColorId_EnabledMenuButtonBorderColor:
182 case kColorId_MenuSeparatorColor: {
183 return GetMenuItemStyle()->text[GTK_STATE_INSENSITIVE];
185 case kColorId_MenuBackgroundColor:
186 return GetMenuStyle()->bg[GTK_STATE_NORMAL];
189 case kColorId_LabelEnabledColor:
190 return GetLabelStyle()->text[GTK_STATE_NORMAL];
191 case kColorId_LabelDisabledColor:
192 return GetLabelStyle()->text[GTK_STATE_INSENSITIVE];
193 case kColorId_LabelBackgroundColor:
194 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
197 case kColorId_ButtonBackgroundColor:
198 return GetButtonStyle()->bg[GTK_STATE_NORMAL];
199 case kColorId_ButtonEnabledColor:
200 return GetButtonStyle()->text[GTK_STATE_NORMAL];
201 case kColorId_ButtonDisabledColor:
202 return GetButtonStyle()->text[GTK_STATE_INSENSITIVE];
203 case kColorId_ButtonHighlightColor:
204 return GetButtonStyle()->base[GTK_STATE_SELECTED];
205 case kColorId_ButtonHoverColor:
206 return GetButtonStyle()->text[GTK_STATE_PRELIGHT];
209 case kColorId_TextfieldDefaultColor:
210 return GetEntryStyle()->text[GTK_STATE_NORMAL];
211 case kColorId_TextfieldDefaultBackground:
212 return GetEntryStyle()->base[GTK_STATE_NORMAL];
213 case kColorId_TextfieldReadOnlyColor:
214 return GetEntryStyle()->text[GTK_STATE_INSENSITIVE];
215 case kColorId_TextfieldReadOnlyBackground:
216 return GetEntryStyle()->base[GTK_STATE_INSENSITIVE];
217 case kColorId_TextfieldSelectionColor:
218 return GetEntryStyle()->text[GTK_STATE_SELECTED];
219 case kColorId_TextfieldSelectionBackgroundFocused:
220 return GetEntryStyle()->base[GTK_STATE_SELECTED];
230 return SkColorToGdkColor(kInvalidColorIdColor);
233 GtkWidget* NativeThemeGtk2::GetRealizedWindow() const {
235 fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
236 gtk_widget_realize(fake_window_);
242 GtkStyle* NativeThemeGtk2::GetWindowStyle() const {
243 return gtk_rc_get_style(GetRealizedWindow());
246 GtkStyle* NativeThemeGtk2::GetEntryStyle() const {
247 if (!fake_entry_.get()) {
248 fake_entry_.Own(gtk_entry_new());
250 // The fake entry needs to be in the window so it can be realized sow e can
251 // use the computed parts of the style.
252 gtk_container_add(GTK_CONTAINER(GetRealizedWindow()), fake_entry_.get());
253 gtk_widget_realize(fake_entry_.get());
255 return gtk_rc_get_style(fake_entry_.get());
258 GtkStyle* NativeThemeGtk2::GetLabelStyle() const {
259 if (!fake_label_.get())
260 fake_label_.Own(gtk_label_new(""));
262 return gtk_rc_get_style(fake_label_.get());
265 GtkStyle* NativeThemeGtk2::GetButtonStyle() const {
266 if (!fake_button_.get())
267 fake_button_.Own(gtk_button_new());
269 return gtk_rc_get_style(fake_button_.get());
272 GtkStyle* NativeThemeGtk2::GetMenuStyle() const {
273 if (!fake_menu_.get())
274 fake_menu_.Own(gtk_menu_new());
275 return gtk_rc_get_style(fake_menu_.get());
278 GtkStyle* NativeThemeGtk2::GetMenuItemStyle() const {
279 if (!fake_menu_item_) {
280 if (!fake_menu_.get())
281 fake_menu_.Own(gtk_menu_new());
283 fake_menu_item_ = gtk_menu_item_new();
284 gtk_menu_shell_append(GTK_MENU_SHELL(fake_menu_.get()), fake_menu_item_);
287 return gtk_rc_get_style(fake_menu_item_);
290 } // namespace libgtk2ui