Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: chrome/browser/ui/libgtkui/native_theme_gtk3.cc

Issue 2655553003: Native themes: Add menu separator part (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "chrome/browser/ui/libgtkui/chrome_gtk_frame.h" 9 #include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h"
10 #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" 10 #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h"
11 #include "chrome/browser/ui/libgtkui/gtk_util.h" 11 #include "chrome/browser/ui/libgtkui/gtk_util.h"
12 #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" 12 #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
13 #include "ui/gfx/color_palette.h" 13 #include "ui/gfx/color_palette.h"
14 #include "ui/gfx/color_utils.h" 14 #include "ui/gfx/color_utils.h"
15 #include "ui/gfx/geometry/rect.h" 15 #include "ui/gfx/geometry/rect.h"
16 #include "ui/gfx/skbitmap_operations.h" 16 #include "ui/gfx/skbitmap_operations.h"
17 #include "ui/native_theme/native_theme_dark_aura.h" 17 #include "ui/native_theme/native_theme_dark_aura.h"
18 18
19 namespace libgtkui { 19 namespace libgtkui {
20 20
21 namespace { 21 namespace {
22 22
23 enum BackgroundRenderMode {
24 BG_RENDER_NORMAL,
25 BG_RENDER_NONE,
26 BG_RENDER_RECURSIVE,
27 };
28
23 SkBitmap GetWidgetBitmap(const gfx::Size& size, 29 SkBitmap GetWidgetBitmap(const gfx::Size& size,
24 GtkStyleContext* context) { 30 GtkStyleContext* context,
31 BackgroundRenderMode bg_mode,
32 bool render_frame) {
33 DCHECK(bg_mode != BG_RENDER_NONE || render_frame);
25 SkBitmap bitmap; 34 SkBitmap bitmap;
26 bitmap.allocN32Pixels(size.width(), size.height()); 35 bitmap.allocN32Pixels(size.width(), size.height());
27 bitmap.eraseColor(0); 36 bitmap.eraseColor(0);
28 37
29 cairo_surface_t* surface = cairo_image_surface_create_for_data( 38 cairo_surface_t* surface = cairo_image_surface_create_for_data(
30 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), CAIRO_FORMAT_ARGB32, 39 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), CAIRO_FORMAT_ARGB32,
31 size.width(), size.height(), 40 size.width(), size.height(),
32 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, size.width())); 41 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, size.width()));
33 cairo_t* cr = cairo_create(surface); 42 cairo_t* cr = cairo_create(surface);
34 43
35 RenderBackground(size, cr, context); 44 switch (bg_mode) {
36 gtk_render_frame(context, cr, 0, 0, size.width(), size.height()); 45 case BG_RENDER_NORMAL:
46 gtk_render_background(context, cr, 0, 0, size.width(), size.height());
47 break;
48 case BG_RENDER_RECURSIVE:
49 RenderBackground(size, cr, context);
50 break;
51 case BG_RENDER_NONE:
52 break;
53 }
54 if (render_frame)
55 gtk_render_frame(context, cr, 0, 0, size.width(), size.height());
37 cairo_destroy(cr); 56 cairo_destroy(cr);
38 cairo_surface_destroy(surface); 57 cairo_surface_destroy(surface);
39 return bitmap; 58 return bitmap;
40 } 59 }
41 60
42 void PaintWidget(SkCanvas* canvas, 61 void PaintWidget(SkCanvas* canvas,
43 const gfx::Rect& rect, 62 const gfx::Rect& rect,
44 GtkStyleContext* context) { 63 GtkStyleContext* context,
45 canvas->drawBitmap(GetWidgetBitmap(rect.size(), context), rect.x(), rect.y()); 64 BackgroundRenderMode bg_mode,
65 bool render_frame) {
66 canvas->drawBitmap(
67 GetWidgetBitmap(rect.size(), context, bg_mode, render_frame), rect.x(),
68 rect.y());
46 } 69 }
47 70
48 GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) { 71 GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) {
49 switch (state) { 72 switch (state) {
50 case NativeThemeGtk3::kDisabled: 73 case NativeThemeGtk3::kDisabled:
51 return GTK_STATE_FLAG_INSENSITIVE; 74 return GTK_STATE_FLAG_INSENSITIVE;
52 case NativeThemeGtk3::kHovered: 75 case NativeThemeGtk3::kHovered:
53 return GTK_STATE_FLAG_PRELIGHT; 76 return GTK_STATE_FLAG_PRELIGHT;
54 case NativeThemeGtk3::kNormal: 77 case NativeThemeGtk3::kNormal:
55 return GTK_STATE_FLAG_NORMAL; 78 return GTK_STATE_FLAG_NORMAL;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 case ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor: 115 case ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor:
93 return GetFgColor( 116 return GetFgColor(
94 "GtkMenu#menu GtkMenuItem#menuitem:selected GtkLabel#label"); 117 "GtkMenu#menu GtkMenuItem#menuitem:selected GtkLabel#label");
95 case ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor: 118 case ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor:
96 return GetFgColor( 119 return GetFgColor(
97 "GtkMenu#menu GtkMenuItem#menuitem:disabled GtkLabel#label"); 120 "GtkMenu#menu GtkMenuItem#menuitem:disabled GtkLabel#label");
98 case ui::NativeTheme::kColorId_MenuItemSubtitleColor: 121 case ui::NativeTheme::kColorId_MenuItemSubtitleColor:
99 return GetFgColor( 122 return GetFgColor(
100 "GtkMenu#menu GtkMenuItem#menuitem GtkLabel#label.accelerator"); 123 "GtkMenu#menu GtkMenuItem#menuitem GtkLabel#label.accelerator");
101 case ui::NativeTheme::kColorId_MenuSeparatorColor: 124 case ui::NativeTheme::kColorId_MenuSeparatorColor:
102 // MenuButton borders are used the same way as menu separators in Chrome. 125 // MenuButton borders are used as vertical menu separators in Chrome.
103 case ui::NativeTheme::kColorId_EnabledMenuButtonBorderColor: 126 case ui::NativeTheme::kColorId_EnabledMenuButtonBorderColor:
104 case ui::NativeTheme::kColorId_FocusedMenuButtonBorderColor: 127 case ui::NativeTheme::kColorId_FocusedMenuButtonBorderColor:
105 case ui::NativeTheme::kColorId_HoverMenuButtonBorderColor: 128 case ui::NativeTheme::kColorId_HoverMenuButtonBorderColor:
Tom (Use chromium acct) 2017/01/25 02:44:40 erg: It's unclear if we want to do this for the ve
Elliot Glaysher 2017/01/25 18:42:09 I'm pretty sure that we want the vertical separato
Tom (Use chromium acct) 2017/01/25 22:25:44 Acknowledged.
106 if (GtkVersionCheck(3, 20)) 129 if (GtkVersionCheck(3, 20))
107 return GetBgColor("GtkMenu#menu GtkSeparator#separator"); 130 return GetBgColor("GtkMenu#menu GtkSeparator#separator");
108 else 131 else
109 return GetFgColor("GtkMenu#menu GtkMenuItem#menuitem.separator"); 132 return GetFgColor("GtkMenu#menu GtkMenuItem#menuitem.separator");
110 133
111 // Label 134 // Label
112 case ui::NativeTheme::kColorId_LabelEnabledColor: 135 case ui::NativeTheme::kColorId_LabelEnabledColor:
113 return GetFgColor("GtkLabel#label"); 136 return GetFgColor("GtkLabel#label");
114 case ui::NativeTheme::kColorId_LabelDisabledColor: 137 case ui::NativeTheme::kColorId_LabelDisabledColor:
115 return GetFgColor("GtkLabel#label:disabled"); 138 return GetFgColor("GtkLabel#label:disabled");
116 case ui::NativeTheme::kColorId_LabelTextSelectionColor: 139 case ui::NativeTheme::kColorId_LabelTextSelectionColor:
117 return GetFgColor("GtkLabel#label #selection:selected"); 140 return GetFgColor("GtkLabel#label #selection:selected");
118 case ui::NativeTheme::kColorId_LabelTextSelectionBackgroundFocused: 141 case ui::NativeTheme::kColorId_LabelTextSelectionBackgroundFocused:
119 return GetBgColor("GtkLabel#label #selection:selected"); 142 return GetBgColor("GtkLabel#label #selection:selected");
120 143
121 // Link 144 // Link
122 case ui::NativeTheme::kColorId_LinkDisabled: 145 case ui::NativeTheme::kColorId_LinkDisabled:
123 return SkColorSetA( 146 return SkColorSetA(
124 SkColorFromColorId(ui::NativeTheme::kColorId_LinkEnabled), 0xBB); 147 SkColorFromColorId(ui::NativeTheme::kColorId_LinkEnabled), 0xBB);
125 case ui::NativeTheme::kColorId_LinkPressed: 148 case ui::NativeTheme::kColorId_LinkPressed:
126 if (GtkVersionCheck(3, 12)) 149 if (GtkVersionCheck(3, 12))
127 return GetFgColor("GtkLabel#label.link:link:hover:active"); 150 return GetFgColor("GtkLabel#label.link:link:hover:active");
128 // fallthrough 151 // fallthrough
129 case ui::NativeTheme::kColorId_LinkEnabled: { 152 case ui::NativeTheme::kColorId_LinkEnabled: {
130 if (GtkVersionCheck(3, 12)) { 153 if (GtkVersionCheck(3, 12)) {
131 return GetFgColor("GtkLabel#label.link:link"); 154 return GetFgColor("GtkLabel#label.link:link");
132 } 155 }
133 auto link_context = GetStyleContextFromCss("GtkLabel#label.view"); 156 auto link_context = GetStyleContextFromCss("GtkLabel#label.view");
134 GdkColor* color; 157 GdkColor* color;
135 gtk_style_context_get_style(link_context, "link-color", &color, nullptr); 158 gtk_style_context_get_style(link_context, "link-color", &color, nullptr);
136 if (color) { 159 if (color) {
137 SkColor ret_color = SkColorSetRGB(color->red / 255, color->green / 255, 160 SkColor ret_color = SkColorSetRGB(color->red / 255, color->green / 255,
138 color->blue / 255); 161 color->blue / 255);
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 378
356 SkColor color = SkColorFromColorId(color_id); 379 SkColor color = SkColorFromColorId(color_id);
357 color_cache_[color_id] = color; 380 color_cache_[color_id] = color;
358 return color; 381 return color;
359 } 382 }
360 383
361 void NativeThemeGtk3::PaintMenuPopupBackground( 384 void NativeThemeGtk3::PaintMenuPopupBackground(
362 SkCanvas* canvas, 385 SkCanvas* canvas,
363 const gfx::Size& size, 386 const gfx::Size& size,
364 const MenuBackgroundExtraParams& menu_background) const { 387 const MenuBackgroundExtraParams& menu_background) const {
365 PaintWidget(canvas, gfx::Rect(size), GetStyleContextFromCss("GtkMenu#menu")); 388 PaintWidget(canvas, gfx::Rect(size), GetStyleContextFromCss("GtkMenu#menu"),
389 BG_RENDER_NORMAL, false);
366 } 390 }
367 391
368 void NativeThemeGtk3::PaintMenuItemBackground( 392 void NativeThemeGtk3::PaintMenuItemBackground(
369 SkCanvas* canvas, 393 SkCanvas* canvas,
370 State state, 394 State state,
371 const gfx::Rect& rect, 395 const gfx::Rect& rect,
372 const MenuItemExtraParams& menu_item) const { 396 const MenuItemExtraParams& menu_item) const {
373 auto context = GetStyleContextFromCss("GtkMenu#menu GtkMenuItem#menuitem"); 397 auto context = GetStyleContextFromCss("GtkMenu#menu GtkMenuItem#menuitem");
374 gtk_style_context_set_state(context, StateToStateFlags(state)); 398 gtk_style_context_set_state(context, StateToStateFlags(state));
375 PaintWidget(canvas, rect, context); 399 PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true);
400 }
401
402 void NativeThemeGtk3::PaintMenuSeparator(
Tom (Use chromium acct) 2017/01/25 02:44:39 erg: Just so you know, this lets gtk override chro
403 SkCanvas* canvas,
404 State state,
405 const gfx::Rect& rect,
406 const MenuSeparatorExtraParams& menu_separator) const {
407 auto separator_offset = [&](int separator_thickness) {
408 switch (menu_separator.type) {
409 case ui::LOWER_SEPARATOR:
410 return rect.height() - separator_thickness;
411 case ui::UPPER_SEPARATOR:
412 return 0;
413 default:
414 return rect.height() / 2;
415 }
416 };
417 if (GtkVersionCheck(3, 20)) {
418 auto context =
419 GetStyleContextFromCss("GtkMenu#menu GtkSeparator#separator");
420 GtkBorder margin, border, padding;
421 GtkStateFlags state = gtk_style_context_get_state(context);
422 gtk_style_context_get_margin(context, state, &margin);
423 gtk_style_context_get_border(context, state, &border);
424 gtk_style_context_get_padding(context, state, &padding);
425 int min_height = 0;
426 gtk_style_context_get(context, state, "min-height", &min_height, NULL);
427 int w = rect.width() - margin.left - margin.right;
428 int h =
429 min_height + padding.top + padding.bottom + border.top + border.bottom;
430 int x = margin.left;
431 int y = separator_offset(h);
432 PaintWidget(canvas, gfx::Rect(x, y, w, h), context, BG_RENDER_NORMAL, true);
433 } else {
434 auto context =
435 GetStyleContextFromCss("GtkMenu#menu GtkMenuItem#menuitem.separator");
436 gboolean wide_separators = false;
437 gint separator_height = 0;
438 gtk_style_context_get_style(context, "wide-separators", &wide_separators,
439 "separator-height", &separator_height, nullptr);
440 // This code was adapted from gtk/gtkmenuitem.c. For some reason,
441 // padding is used as the margin.
442 GtkBorder padding;
443 gtk_style_context_get_padding(context, gtk_style_context_get_state(context),
444 &padding);
445 int w = rect.width() - padding.left - padding.right;
446 int x = rect.x() + padding.left;
447 int h = wide_separators ? separator_height : 1;
448 int y = rect.y() + separator_offset(h);
449 if (wide_separators) {
450 PaintWidget(canvas, gfx::Rect(x, y, w, h), context, BG_RENDER_NONE, true);
451 } else {
452 SkPaint paint;
453 paint.setColor(SkColorFromStyleContext(context));
454 canvas->drawLine(x, y, x + w, y, paint);
455 }
456 }
376 } 457 }
377 458
378 void NativeThemeGtk3::PaintFrameTopArea( 459 void NativeThemeGtk3::PaintFrameTopArea(
379 SkCanvas* canvas, 460 SkCanvas* canvas,
380 State state, 461 State state,
381 const gfx::Rect& rect, 462 const gfx::Rect& rect,
382 const FrameTopAreaExtraParams& frame_top_area) const { 463 const FrameTopAreaExtraParams& frame_top_area) const {
383 auto context = GetStyleContextFromCss(frame_top_area.use_custom_frame 464 auto context = GetStyleContextFromCss(frame_top_area.use_custom_frame
384 ? "#headerbar.header-bar.titlebar" 465 ? "#headerbar.header-bar.titlebar"
385 : "GtkMenuBar#menubar"); 466 : "GtkMenuBar#menubar");
386 RemoveBorders(context); 467 RemoveBorders(context);
387 gtk_style_context_set_state(context, 468 gtk_style_context_set_state(context, frame_top_area.is_active
388 frame_top_area.is_active 469 ? GTK_STATE_FLAG_NORMAL
389 ? GTK_STATE_FLAG_NORMAL 470 : GTK_STATE_FLAG_BACKDROP);
390 : GTK_STATE_FLAG_BACKDROP);
391 471
392 SkBitmap bitmap = GetWidgetBitmap(rect.size(), context); 472 SkBitmap bitmap =
473 GetWidgetBitmap(rect.size(), context, BG_RENDER_RECURSIVE, false);
393 474
394 if (frame_top_area.incognito) { 475 if (frame_top_area.incognito) {
395 bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( 476 bitmap = SkBitmapOperations::CreateHSLShiftedBitmap(
396 bitmap, kDefaultTintFrameIncognito); 477 bitmap, kDefaultTintFrameIncognito);
397 } 478 }
398 479
399 canvas->drawBitmap(bitmap, rect.x(), rect.y()); 480 canvas->drawBitmap(bitmap, rect.x(), rect.y());
400 } 481 }
401 482
402 } // namespace libgtkui 483 } // namespace libgtkui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698