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/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"
20 // Theme colors returned by GetSystemColor().
21 const SkColor kInvalidColorIdColor
= SkColorSetRGB(255, 0, 128);
23 const SkColor kTreeBackground
= SK_ColorWHITE
;
24 const SkColor kTreeTextColor
= SK_ColorBLACK
;
25 const SkColor kTreeSelectedTextColor
= SK_ColorBLACK
;
26 const SkColor kTreeSelectionBackgroundColor
= SkColorSetRGB(0xEE, 0xEE, 0xEE);
27 const SkColor kTreeArrowColor
= SkColorSetRGB(0x7A, 0x7A, 0x7A);
29 const SkColor kTableBackground
= SK_ColorWHITE
;
30 const SkColor kTableTextColor
= SK_ColorBLACK
;
31 const SkColor kTableSelectedTextColor
= SK_ColorBLACK
;
32 const SkColor kTableSelectionBackgroundColor
= SkColorSetRGB(0xEE, 0xEE, 0xEE);
33 const SkColor kTableGroupingIndicatorColor
= SkColorSetRGB(0xCC, 0xCC, 0xCC);
41 NativeThemeGtk2
* NativeThemeGtk2::instance() {
42 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk2
, s_native_theme
, ());
43 return &s_native_theme
;
46 NativeThemeGtk2::NativeThemeGtk2()
48 fake_menu_item_(NULL
) {
51 NativeThemeGtk2::~NativeThemeGtk2() {
53 gtk_widget_destroy(fake_window_
);
54 fake_entry_
.Destroy();
55 fake_label_
.Destroy();
56 fake_button_
.Destroy();
60 SkColor
NativeThemeGtk2::GetSystemColor(ColorId color_id
) const {
62 // TODO(erg): Still need to fish the colors out of trees and tables.
65 case kColorId_TreeBackground
:
66 return kTreeBackground
;
67 case kColorId_TreeText
:
68 return kTreeTextColor
;
69 case kColorId_TreeSelectedText
:
70 case kColorId_TreeSelectedTextUnfocused
:
71 return kTreeSelectedTextColor
;
72 case kColorId_TreeSelectionBackgroundFocused
:
73 case kColorId_TreeSelectionBackgroundUnfocused
:
74 return kTreeSelectionBackgroundColor
;
75 case kColorId_TreeArrow
:
76 return kTreeArrowColor
;
79 case kColorId_TableBackground
:
80 return kTableBackground
;
81 case kColorId_TableText
:
82 return kTableTextColor
;
83 case kColorId_TableSelectedText
:
84 case kColorId_TableSelectedTextUnfocused
:
85 return kTableSelectedTextColor
;
86 case kColorId_TableSelectionBackgroundFocused
:
87 case kColorId_TableSelectionBackgroundUnfocused
:
88 return kTableSelectionBackgroundColor
;
89 case kColorId_TableGroupingIndicatorColor
:
90 return kTableGroupingIndicatorColor
;
97 return GdkColorToSkColor(GetSystemGdkColor(color_id
));
100 void NativeThemeGtk2::PaintMenuPopupBackground(
102 const gfx::Size
& size
,
103 const MenuBackgroundExtraParams
& menu_background
) const {
104 if (menu_background
.corner_radius
> 0) {
106 paint
.setStyle(SkPaint::kFill_Style
);
107 paint
.setFlags(SkPaint::kAntiAlias_Flag
);
108 paint
.setColor(GetSystemColor(kColorId_MenuBackgroundColor
));
111 SkRect rect
= SkRect::MakeWH(SkIntToScalar(size
.width()),
112 SkIntToScalar(size
.height()));
113 SkScalar radius
= SkIntToScalar(menu_background
.corner_radius
);
114 SkScalar radii
[8] = {radius
, radius
, radius
, radius
,
115 radius
, radius
, radius
, radius
};
116 path
.addRoundRect(rect
, radii
);
118 canvas
->drawPath(path
, paint
);
120 canvas
->drawColor(GetSystemColor(kColorId_MenuBackgroundColor
),
121 SkXfermode::kSrc_Mode
);
125 void NativeThemeGtk2::PaintMenuItemBackground(
128 const gfx::Rect
& rect
,
129 const MenuListExtraParams
& menu_list
) const {
133 case NativeTheme::kNormal
:
134 case NativeTheme::kDisabled
:
135 color
= GetSystemColor(NativeTheme::kColorId_MenuBackgroundColor
);
136 paint
.setColor(color
);
138 case NativeTheme::kHovered
:
139 color
= GetSystemColor(
140 NativeTheme::kColorId_FocusedMenuItemBackgroundColor
);
141 paint
.setColor(color
);
144 NOTREACHED() << "Invalid state " << state
;
147 canvas
->drawRect(gfx::RectToSkRect(rect
), paint
);
150 GdkColor
NativeThemeGtk2::GetSystemGdkColor(ColorId color_id
) const {
153 case kColorId_WindowBackground
:
154 return GetWindowStyle()->bg
[GTK_STATE_NORMAL
];
157 case kColorId_DialogBackground
:
158 return GetWindowStyle()->bg
[GTK_STATE_NORMAL
];
161 case kColorId_FocusedBorderColor
:
162 return GetEntryStyle()->bg
[GTK_STATE_SELECTED
];
163 case kColorId_UnfocusedBorderColor
:
164 return GetEntryStyle()->text_aa
[GTK_STATE_NORMAL
];
167 case kColorId_EnabledMenuItemForegroundColor
:
168 return GetMenuItemStyle()->text
[GTK_STATE_NORMAL
];
169 case kColorId_DisabledMenuItemForegroundColor
:
170 return GetMenuItemStyle()->text
[GTK_STATE_INSENSITIVE
];
171 case kColorId_SelectedMenuItemForegroundColor
:
172 return GetMenuItemStyle()->text
[GTK_STATE_SELECTED
];
173 case kColorId_FocusedMenuItemBackgroundColor
:
174 return GetMenuItemStyle()->bg
[GTK_STATE_SELECTED
];
175 case kColorId_HoverMenuItemBackgroundColor
:
176 return GetMenuItemStyle()->bg
[GTK_STATE_PRELIGHT
];
177 case kColorId_FocusedMenuButtonBorderColor
:
178 return GetEntryStyle()->bg
[GTK_STATE_NORMAL
];
179 case kColorId_HoverMenuButtonBorderColor
:
180 return GetEntryStyle()->text_aa
[GTK_STATE_PRELIGHT
];
181 case kColorId_MenuBorderColor
:
182 case kColorId_EnabledMenuButtonBorderColor
:
183 case kColorId_MenuSeparatorColor
: {
184 return GetMenuItemStyle()->text
[GTK_STATE_INSENSITIVE
];
186 case kColorId_MenuBackgroundColor
:
187 return GetMenuStyle()->bg
[GTK_STATE_NORMAL
];
190 case kColorId_LabelEnabledColor
:
191 return GetLabelStyle()->text
[GTK_STATE_NORMAL
];
192 case kColorId_LabelDisabledColor
:
193 return GetLabelStyle()->text
[GTK_STATE_INSENSITIVE
];
194 case kColorId_LabelBackgroundColor
:
195 return GetWindowStyle()->bg
[GTK_STATE_NORMAL
];
198 case kColorId_ButtonBackgroundColor
:
199 return GetButtonStyle()->bg
[GTK_STATE_NORMAL
];
200 case kColorId_ButtonEnabledColor
:
201 return GetButtonStyle()->text
[GTK_STATE_NORMAL
];
202 case kColorId_ButtonDisabledColor
:
203 return GetButtonStyle()->text
[GTK_STATE_INSENSITIVE
];
204 case kColorId_ButtonHighlightColor
:
205 return GetButtonStyle()->base
[GTK_STATE_SELECTED
];
206 case kColorId_ButtonHoverColor
:
207 return GetButtonStyle()->text
[GTK_STATE_PRELIGHT
];
210 case kColorId_TextfieldDefaultColor
:
211 return GetEntryStyle()->text
[GTK_STATE_NORMAL
];
212 case kColorId_TextfieldDefaultBackground
:
213 return GetEntryStyle()->base
[GTK_STATE_NORMAL
];
214 case kColorId_TextfieldReadOnlyColor
:
215 return GetEntryStyle()->text
[GTK_STATE_INSENSITIVE
];
216 case kColorId_TextfieldReadOnlyBackground
:
217 return GetEntryStyle()->base
[GTK_STATE_INSENSITIVE
];
218 case kColorId_TextfieldSelectionColor
:
219 return GetEntryStyle()->text
[GTK_STATE_SELECTED
];
220 case kColorId_TextfieldSelectionBackgroundFocused
:
221 return GetEntryStyle()->base
[GTK_STATE_SELECTED
];
231 return SkColorToGdkColor(kInvalidColorIdColor
);
234 GtkWidget
* NativeThemeGtk2::GetRealizedWindow() const {
236 fake_window_
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
237 gtk_widget_realize(fake_window_
);
243 GtkStyle
* NativeThemeGtk2::GetWindowStyle() const {
244 return gtk_rc_get_style(GetRealizedWindow());
247 GtkStyle
* NativeThemeGtk2::GetEntryStyle() const {
248 if (!fake_entry_
.get()) {
249 fake_entry_
.Own(gtk_entry_new());
251 // The fake entry needs to be in the window so it can be realized sow e can
252 // use the computed parts of the style.
253 gtk_container_add(GTK_CONTAINER(GetRealizedWindow()), fake_entry_
.get());
254 gtk_widget_realize(fake_entry_
.get());
256 return gtk_rc_get_style(fake_entry_
.get());
259 GtkStyle
* NativeThemeGtk2::GetLabelStyle() const {
260 if (!fake_label_
.get())
261 fake_label_
.Own(gtk_label_new(""));
263 return gtk_rc_get_style(fake_label_
.get());
266 GtkStyle
* NativeThemeGtk2::GetButtonStyle() const {
267 if (!fake_button_
.get())
268 fake_button_
.Own(gtk_button_new());
270 return gtk_rc_get_style(fake_button_
.get());
273 GtkStyle
* NativeThemeGtk2::GetMenuStyle() const {
274 if (!fake_menu_
.get())
275 fake_menu_
.Own(gtk_menu_new());
276 return gtk_rc_get_style(fake_menu_
.get());
279 GtkStyle
* NativeThemeGtk2::GetMenuItemStyle() const {
280 if (!fake_menu_item_
) {
281 if (!fake_menu_
.get())
282 fake_menu_
.Own(gtk_custom_menu_new());
284 fake_menu_item_
= gtk_custom_menu_item_new();
285 gtk_menu_shell_append(GTK_MENU_SHELL(fake_menu_
.get()), fake_menu_item_
);
288 return gtk_rc_get_style(fake_menu_item_
);
291 } // namespace libgtk2ui