win32 theme: Add a way to query border of theme parts

This commit is contained in:
Benjamin Otte 2016-02-15 06:50:22 +01:00 committed by Benjamin Otte
parent a3998bce9d
commit 67b893c5f8
6 changed files with 128 additions and 7 deletions

View File

@ -133,7 +133,11 @@ gtk_css_number_value_can_parse (GtkCssParser *parser)
|| _gtk_css_parser_has_prefix (parser, "calc")
|| _gtk_css_parser_has_prefix (parser, "-gtk-win32-size")
|| _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-width")
|| _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height");
|| _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height")
|| _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-top")
|| _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-left")
|| _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-bottom")
|| _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-right");
}
GtkCssValue *
@ -144,7 +148,11 @@ _gtk_css_number_value_parse (GtkCssParser *parser,
return gtk_css_calc_value_parse (parser, flags);
if (_gtk_css_parser_has_prefix (parser, "-gtk-win32-size") ||
_gtk_css_parser_has_prefix (parser, "-gtk-win32-part-width") ||
_gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height"))
_gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height") ||
_gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-top") ||
_gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-left") ||
_gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-bottom") ||
_gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-right"))
return gtk_css_win32_size_value_parse (parser, flags);
return gtk_css_dimension_value_parse (parser, flags);

View File

@ -24,13 +24,21 @@
typedef enum {
GTK_WIN32_SIZE,
GTK_WIN32_PART_WIDTH,
GTK_WIN32_PART_HEIGHT
GTK_WIN32_PART_HEIGHT,
GTK_WIN32_PART_BORDER_TOP,
GTK_WIN32_PART_BORDER_RIGHT,
GTK_WIN32_PART_BORDER_BOTTOM,
GTK_WIN32_PART_BORDER_LEFT
} GtkWin32SizeType;
static const char *css_value_names[] = {
"-gtk-win32-size(",
"-gtk-win32-part-width(",
"-gtk-win32-part-height("
"-gtk-win32-part-height(",
"-gtk-win32-part-border-top(",
"-gtk-win32-part-border-right(",
"-gtk-win32-part-border-bottom(",
"-gtk-win32-part-border-left("
};
struct _GtkCssValue {
@ -63,6 +71,7 @@ gtk_css_value_win32_size_free (GtkCssValue *value)
static int
gtk_css_value_win32_compute_size (const GtkCssValue *value)
{
GtkBorder border;
int size;
switch (value->type)
@ -78,6 +87,26 @@ gtk_css_value_win32_compute_size (const GtkCssValue *value)
gtk_win32_theme_get_part_size (value->theme, value->val.part.part, value->val.part.state, NULL, &size);
break;
case GTK_WIN32_PART_BORDER_TOP:
gtk_win32_theme_get_part_border (value->theme, value->val.part.part, value->val.part.state, &border);
size = border.top;
break;
case GTK_WIN32_PART_BORDER_RIGHT:
gtk_win32_theme_get_part_border (value->theme, value->val.part.part, value->val.part.state, &border);
size = border.right;
break;
case GTK_WIN32_PART_BORDER_BOTTOM:
gtk_win32_theme_get_part_border (value->theme, value->val.part.part, value->val.part.state, &border);
size = border.bottom;
break;
case GTK_WIN32_PART_BORDER_LEFT:
gtk_win32_theme_get_part_border (value->theme, value->val.part.part, value->val.part.state, &border);
size = border.left;
break;
default:
g_assert_not_reached ();
return 0;
@ -139,6 +168,10 @@ gtk_css_value_win32_size_print (const GtkCssValue *value,
case GTK_WIN32_PART_WIDTH:
case GTK_WIN32_PART_HEIGHT:
case GTK_WIN32_PART_BORDER_TOP:
case GTK_WIN32_PART_BORDER_RIGHT:
case GTK_WIN32_PART_BORDER_BOTTOM:
case GTK_WIN32_PART_BORDER_LEFT:
g_string_append_printf (string, ", %d, %d", value->val.part.part, value->val.part.state);
break;
@ -317,6 +350,10 @@ gtk_css_win32_size_value_parse (GtkCssParser *parser,
case GTK_WIN32_PART_WIDTH:
case GTK_WIN32_PART_HEIGHT:
case GTK_WIN32_PART_BORDER_TOP:
case GTK_WIN32_PART_BORDER_RIGHT:
case GTK_WIN32_PART_BORDER_BOTTOM:
case GTK_WIN32_PART_BORDER_LEFT:
result = gtk_css_win32_size_value_parse_part_size (result, parser);
break;

View File

@ -86,6 +86,7 @@ struct _GtkWin32ThemePart {
const char *class_name;
gint part;
gint size;
GtkBorder margins;
void (* draw_func) (cairo_t *cr,
int part,
int state,
@ -94,9 +95,9 @@ struct _GtkWin32ThemePart {
};
static GtkWin32ThemePart theme_parts[] = {
{ "button", 1, 0, draw_button },
{ "button", 2, 13, draw_radio },
{ "button", 3, 13, draw_check }
{ "button", 1, 0, { 3, 3, 3, 3 }, draw_button },
{ "button", 2, 13, { 0, 0, 0, 0 }, draw_radio },
{ "button", 3, 13, { 0, 0, 0, 0 }, draw_check }
};
static const GtkWin32ThemePart *
@ -158,6 +159,26 @@ gtk_win32_get_theme_part_size (const char *class_name,
}
}
void
gtk_win32_get_theme_margins (const char *class_name,
int part,
int state,
GtkBorder *out_margins)
{
const GtkWin32ThemePart *theme_part;
theme_part = get_theme_part (class_name, part);
if (theme_part)
{
*out_margins = theme_part->margins;
}
else
{
out_margins->top = out_margins->bottom = out_margins->left = out_margins->right = 0;
}
}
struct {
const char *name;
GdkRGBA rgba;

View File

@ -21,6 +21,8 @@
#include <gdk/gdk.h>
#include <cairo.h>
#include <gtk/gtkborder.h>
G_BEGIN_DECLS
enum {
@ -68,6 +70,10 @@ void gtk_win32_get_theme_part_size (const char
int state,
int *width,
int *height);
void gtk_win32_get_theme_margins (const char *class_name,
int part,
int state,
GtkBorder *out_margins);
void gtk_win32_get_sys_color (gint id,
GdkRGBA *color);

View File

@ -64,6 +64,12 @@ typedef HRESULT (FAR PASCAL *GetThemePartSizeFunc) (HTHEME hTheme,
RECT *prc,
int eSize,
SIZE *psz);
typedef HRESULT (FAR PASCAL *GetThemeBackgroundExtentFunc) (HTHEME hTheme,
HDC hdc,
int iPartId,
int iStateId,
const RECT *pContentRect,
RECT *pExtentRect);
static GetThemeSysFontFunc get_theme_sys_font = NULL;
static GetThemeSysColorFunc GetThemeSysColor = NULL;
@ -77,6 +83,7 @@ static IsAppThemedFunc is_app_themed = NULL;
static IsThemeBackgroundPartiallyTransparentFunc is_theme_partially_transparent = NULL;
static DrawThemeParentBackgroundFunc draw_theme_parent_background = NULL;
static GetThemePartSizeFunc GetThemePartSize = NULL;
static GetThemeBackgroundExtentFunc GetThemeBackgroundExtent = NULL;
#endif
@ -212,6 +219,7 @@ gtk_win32_theme_init (void)
is_theme_partially_transparent = (IsThemeBackgroundPartiallyTransparentFunc) GetProcAddress (uxtheme_dll, "IsThemeBackgroundPartiallyTransparent");
draw_theme_parent_background = (DrawThemeParentBackgroundFunc) GetProcAddress (uxtheme_dll, "DrawThemeParentBackground");
GetThemePartSize = (GetThemePartSizeFunc) GetProcAddress (uxtheme_dll, "GetThemePartSize");
GetThemeBackgroundExtent = (GetThemeBackgroundExtentFunc) GetProcAddress (uxtheme_dll, "GetThemeBackgroundExtent");
}
if (is_app_themed && is_theme_active)
@ -387,6 +395,43 @@ gtk_win32_theme_create_surface (GtkWin32Theme *theme,
return surface;
}
void
gtk_win32_theme_get_part_border (GtkWin32Theme *theme,
int part,
int state,
GtkBorder *out_border)
{
#ifdef G_OS_WIN32
HTHEME htheme = gtk_win32_theme_get_htheme (theme);
RECT content, extent;
HDC hdc;
HRESULT res;
if (use_xp_theme && GetThemeBackgroundExtent != NULL && htheme != NULL)
{
/* According to Wine source code, these values don't matter
* because uxtheme.dll deals with margins internally. */
content.left = content.top = 0;
content.right = content.bottom = 100;
hdc = GetDC (NULL);
res = GetThemeBackgroundExtent (htheme, hdc, part, state, &content, &extent);
ReleaseDC (NULL, hdc);
if (SUCCEEDED (res))
{
out_border->top = content.top - extent.top;
out_border->left = content.left - extent.left;
out_border->bottom = extent.bottom - content.bottom;
out_border->right = extent.right - content.right;
return;
}
}
#endif
gtk_win32_get_theme_margins (theme->class_name, part, state, out_border);
}
void
gtk_win32_theme_get_part_size (GtkWin32Theme *theme,
int part,

View File

@ -49,6 +49,10 @@ cairo_surface_t * gtk_win32_theme_create_surface (GtkWin32Theme *theme,
int *x_offs_out,
int *y_offs_out);
void gtk_win32_theme_get_part_border (GtkWin32Theme *theme,
int part,
int state,
GtkBorder *out_border);
void gtk_win32_theme_get_part_size (GtkWin32Theme *theme,
int part,
int state,