| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/libgtkui/native_theme_gtk3.h" | 5 #include "chrome/browser/ui/libgtkui/native_theme_gtk3.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 | 8 |
| 9 #include "base/strings/string_split.h" |
| 10 #include "base/strings/string_util.h" |
| 9 #include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h" | 11 #include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h" |
| 10 #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" | 12 #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" |
| 11 #include "chrome/browser/ui/libgtkui/gtk_util.h" | 13 #include "chrome/browser/ui/libgtkui/gtk_util.h" |
| 12 #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" | 14 #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" |
| 13 #include "ui/gfx/color_utils.h" | 15 #include "ui/gfx/color_utils.h" |
| 16 #include "ui/gfx/geometry/rect.h" |
| 14 #include "ui/native_theme/native_theme_dark_aura.h" | 17 #include "ui/native_theme/native_theme_dark_aura.h" |
| 15 | 18 |
| 16 namespace libgtkui { | 19 namespace libgtkui { |
| 17 | 20 |
| 18 namespace { | 21 namespace { |
| 19 | 22 |
| 20 enum WidgetState { | 23 enum WidgetState { |
| 21 NORMAL = 0, | 24 NORMAL = 0, |
| 22 ACTIVE = 1, | 25 ACTIVE = 1, |
| 23 PRELIGHT = 2, | 26 PRELIGHT = 2, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 SkColor GetTextColor(GtkWidget* widget, WidgetState state) { | 59 SkColor GetTextColor(GtkWidget* widget, WidgetState state) { |
| 57 return GetFGColor(widget, state); | 60 return GetFGColor(widget, state); |
| 58 } | 61 } |
| 59 SkColor GetTextAAColor(GtkWidget* widget, WidgetState state) { | 62 SkColor GetTextAAColor(GtkWidget* widget, WidgetState state) { |
| 60 return GetFGColor(widget, state); | 63 return GetFGColor(widget, state); |
| 61 } | 64 } |
| 62 SkColor GetBaseColor(GtkWidget* widget, WidgetState state) { | 65 SkColor GetBaseColor(GtkWidget* widget, WidgetState state) { |
| 63 return GetBGColor(widget, state); | 66 return GetBGColor(widget, state); |
| 64 } | 67 } |
| 65 | 68 |
| 69 void PaintWidget(SkCanvas* canvas, |
| 70 const gfx::Rect& rect, |
| 71 const char* css_selector, |
| 72 GtkStateFlags state) { |
| 73 SkBitmap bitmap; |
| 74 bitmap.allocN32Pixels(rect.width(), rect.height()); |
| 75 bitmap.eraseColor(0); |
| 76 |
| 77 cairo_surface_t* surface = cairo_image_surface_create_for_data( |
| 78 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), CAIRO_FORMAT_ARGB32, |
| 79 rect.width(), rect.height(), |
| 80 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, rect.width())); |
| 81 cairo_t* cr = cairo_create(surface); |
| 82 |
| 83 GtkWidgetPath* path = gtk_widget_path_new(); |
| 84 for (const auto& widget_type : |
| 85 base::SplitString(css_selector, base::kWhitespaceASCII, |
| 86 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { |
| 87 gtk_widget_path_append_type(path, G_TYPE_NONE); |
| 88 for (const auto& widget_class : |
| 89 base::SplitString(widget_type, ".", base::TRIM_WHITESPACE, |
| 90 base::SPLIT_WANT_NONEMPTY)) { |
| 91 gtk_widget_path_iter_add_class(path, -1, widget_class.c_str()); |
| 92 } |
| 93 } |
| 94 |
| 95 GtkStyleContext* context = gtk_style_context_new(); |
| 96 gtk_style_context_set_path(context, path); |
| 97 gtk_style_context_set_state(context, state); |
| 98 |
| 99 gtk_render_background(context, cr, 0, 0, rect.width(), rect.height()); |
| 100 gtk_render_frame(context, cr, 0, 0, rect.width(), rect.height()); |
| 101 cairo_destroy(cr); |
| 102 cairo_surface_destroy(surface); |
| 103 canvas->drawBitmap(bitmap, rect.x(), rect.y()); |
| 104 |
| 105 g_object_unref(context); |
| 106 gtk_widget_path_unref(path); |
| 107 } |
| 108 |
| 109 GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) { |
| 110 switch (state) { |
| 111 case NativeThemeGtk3::kDisabled: |
| 112 return GTK_STATE_FLAG_INSENSITIVE; |
| 113 case NativeThemeGtk3::kHovered: |
| 114 return GTK_STATE_FLAG_PRELIGHT; |
| 115 case NativeThemeGtk3::kNormal: |
| 116 return GTK_STATE_FLAG_NORMAL; |
| 117 case NativeThemeGtk3::kPressed: |
| 118 return static_cast<GtkStateFlags>(GTK_STATE_FLAG_PRELIGHT | |
| 119 GTK_STATE_FLAG_ACTIVE); |
| 120 default: |
| 121 NOTREACHED(); |
| 122 return GTK_STATE_FLAG_NORMAL; |
| 123 } |
| 124 } |
| 125 |
| 66 } // namespace | 126 } // namespace |
| 67 | 127 |
| 68 // static | 128 // static |
| 69 NativeThemeGtk3* NativeThemeGtk3::instance() { | 129 NativeThemeGtk3* NativeThemeGtk3::instance() { |
| 70 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ()); | 130 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ()); |
| 71 return &s_native_theme; | 131 return &s_native_theme; |
| 72 } | 132 } |
| 73 | 133 |
| 74 // Constructors automatically called | 134 // Constructors automatically called |
| 75 NativeThemeGtk3::NativeThemeGtk3() {} | 135 NativeThemeGtk3::NativeThemeGtk3() {} |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 } | 354 } |
| 295 | 355 |
| 296 case kColorId_NumColors: | 356 case kColorId_NumColors: |
| 297 NOTREACHED(); | 357 NOTREACHED(); |
| 298 break; | 358 break; |
| 299 } | 359 } |
| 300 | 360 |
| 301 return kInvalidColorIdColor; | 361 return kInvalidColorIdColor; |
| 302 } | 362 } |
| 303 | 363 |
| 364 void NativeThemeGtk3::PaintMenuPopupBackground( |
| 365 SkCanvas* canvas, |
| 366 const gfx::Size& size, |
| 367 const MenuBackgroundExtraParams& menu_background) const { |
| 368 PaintWidget(canvas, gfx::Rect(size), "menu", GTK_STATE_FLAG_NORMAL); |
| 369 } |
| 370 |
| 371 void NativeThemeGtk3::PaintMenuItemBackground( |
| 372 SkCanvas* canvas, |
| 373 State state, |
| 374 const gfx::Rect& rect, |
| 375 const MenuItemExtraParams& menu_item) const { |
| 376 PaintWidget(canvas, rect, "menu menuitem", StateToStateFlags(state)); |
| 377 } |
| 378 |
| 304 GtkWidget* NativeThemeGtk3::GetWindow() const { | 379 GtkWidget* NativeThemeGtk3::GetWindow() const { |
| 305 static GtkWidget* fake_window = NULL; | 380 static GtkWidget* fake_window = NULL; |
| 306 | 381 |
| 307 if (!fake_window) { | 382 if (!fake_window) { |
| 308 fake_window = chrome_gtk_frame_new(); | 383 fake_window = chrome_gtk_frame_new(); |
| 309 gtk_widget_realize(fake_window); | 384 gtk_widget_realize(fake_window); |
| 310 } | 385 } |
| 311 | 386 |
| 312 return fake_window; | 387 return fake_window; |
| 313 } | 388 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 466 |
| 392 if (!fake_menu_item) { | 467 if (!fake_menu_item) { |
| 393 fake_menu_item = gtk_custom_menu_item_new(); | 468 fake_menu_item = gtk_custom_menu_item_new(); |
| 394 gtk_menu_shell_append(GTK_MENU_SHELL(GetMenu()), fake_menu_item); | 469 gtk_menu_shell_append(GTK_MENU_SHELL(GetMenu()), fake_menu_item); |
| 395 } | 470 } |
| 396 | 471 |
| 397 return fake_menu_item; | 472 return fake_menu_item; |
| 398 } | 473 } |
| 399 | 474 |
| 400 } // namespace libgtkui | 475 } // namespace libgtkui |
| OLD | NEW |