Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / libgtk2ui / native_theme_gtk2.cc
blob957cc3708bc6be70c178898d99127f97be7c1936
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);
22 // Tree
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);
28 // Table
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);
35 } // namespace
38 namespace libgtk2ui {
40 // static
41 NativeThemeGtk2* NativeThemeGtk2::instance() {
42 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk2, s_native_theme, ());
43 return &s_native_theme;
46 NativeThemeGtk2::NativeThemeGtk2()
47 : fake_window_(NULL),
48 fake_menu_item_(NULL) {
51 NativeThemeGtk2::~NativeThemeGtk2() {
52 if (fake_window_)
53 gtk_widget_destroy(fake_window_);
54 fake_entry_.Destroy();
55 fake_label_.Destroy();
56 fake_button_.Destroy();
57 fake_menu_.Destroy();
60 SkColor NativeThemeGtk2::GetSystemColor(ColorId color_id) const {
61 switch (color_id) {
62 // TODO(erg): Still need to fish the colors out of trees and tables.
64 // Tree
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;
78 // Table
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;
92 default:
93 // Fall through.
94 break;
97 return GdkColorToSkColor(GetSystemGdkColor(color_id));
100 void NativeThemeGtk2::PaintMenuPopupBackground(
101 SkCanvas* canvas,
102 const gfx::Size& size,
103 const MenuBackgroundExtraParams& menu_background) const {
104 if (menu_background.corner_radius > 0) {
105 SkPaint paint;
106 paint.setStyle(SkPaint::kFill_Style);
107 paint.setFlags(SkPaint::kAntiAlias_Flag);
108 paint.setColor(GetSystemColor(kColorId_MenuBackgroundColor));
110 gfx::Path path;
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);
119 } else {
120 canvas->drawColor(GetSystemColor(kColorId_MenuBackgroundColor),
121 SkXfermode::kSrc_Mode);
125 void NativeThemeGtk2::PaintMenuItemBackground(
126 SkCanvas* canvas,
127 State state,
128 const gfx::Rect& rect,
129 const MenuListExtraParams& menu_list) const {
130 SkColor color;
131 SkPaint paint;
132 switch (state) {
133 case NativeTheme::kNormal:
134 case NativeTheme::kDisabled:
135 color = GetSystemColor(NativeTheme::kColorId_MenuBackgroundColor);
136 paint.setColor(color);
137 break;
138 case NativeTheme::kHovered:
139 color = GetSystemColor(
140 NativeTheme::kColorId_FocusedMenuItemBackgroundColor);
141 paint.setColor(color);
142 break;
143 default:
144 NOTREACHED() << "Invalid state " << state;
145 break;
147 canvas->drawRect(gfx::RectToSkRect(rect), paint);
150 GdkColor NativeThemeGtk2::GetSystemGdkColor(ColorId color_id) const {
151 switch (color_id) {
152 // Windows
153 case kColorId_WindowBackground:
154 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
156 // Dialogs
157 case kColorId_DialogBackground:
158 return GetWindowStyle()->bg[GTK_STATE_NORMAL];
160 // FocusableBorder
161 case kColorId_FocusedBorderColor:
162 return GetEntryStyle()->bg[GTK_STATE_SELECTED];
163 case kColorId_UnfocusedBorderColor:
164 return GetEntryStyle()->text_aa[GTK_STATE_NORMAL];
166 // MenuItem
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];
189 // Label
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];
197 // Button
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];
209 // Textfield
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];
223 // Tree
224 // Table
226 default:
227 // Fall through
228 break;
231 return SkColorToGdkColor(kInvalidColorIdColor);
234 GtkWidget* NativeThemeGtk2::GetRealizedWindow() const {
235 if (!fake_window_) {
236 fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
237 gtk_widget_realize(fake_window_);
240 return 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