[gtk+] win32: Add support for -gtk-win32-part-width/height to CSS
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] win32: Add support for -gtk-win32-part-width/height to CSS
- Date: Mon, 15 Feb 2016 03:45:33 +0000 (UTC)
commit f425b5549c49146ba3b751672e79f70d5e5572d7
Author: Benjamin Otte <otte gnome org>
Date: Mon Feb 15 00:49:29 2016 +0100
win32: Add support for -gtk-win32-part-width/height to CSS
It's unused by now, but I want it for min-width of checks/radios.
gtk/gtkcssnumbervalue.c | 8 ++-
gtk/gtkcsswin32sizevalue.c | 214 +++++++++++++++++++++++++++++++++++++-------
gtk/gtkwin32theme.c | 53 ++++++++++-
gtk/gtkwin32themeprivate.h | 6 ++
4 files changed, 245 insertions(+), 36 deletions(-)
---
diff --git a/gtk/gtkcssnumbervalue.c b/gtk/gtkcssnumbervalue.c
index cca1e85..e8256c0 100644
--- a/gtk/gtkcssnumbervalue.c
+++ b/gtk/gtkcssnumbervalue.c
@@ -131,7 +131,9 @@ gtk_css_number_value_can_parse (GtkCssParser *parser)
{
return _gtk_css_parser_has_number (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-size")
+ || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-width")
+ || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height");
}
GtkCssValue *
@@ -140,7 +142,9 @@ _gtk_css_number_value_parse (GtkCssParser *parser,
{
if (_gtk_css_parser_has_prefix (parser, "calc"))
return gtk_css_calc_value_parse (parser, flags);
- if (_gtk_css_parser_has_prefix (parser, "-gtk-win32-size"))
+ 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"))
return gtk_css_win32_size_value_parse (parser, flags);
return gtk_css_dimension_value_parse (parser, flags);
diff --git a/gtk/gtkcsswin32sizevalue.c b/gtk/gtkcsswin32sizevalue.c
index 9856a20..7c35d37 100644
--- a/gtk/gtkcsswin32sizevalue.c
+++ b/gtk/gtkcsswin32sizevalue.c
@@ -21,16 +21,37 @@
#include "gtkwin32themeprivate.h"
+typedef enum {
+ GTK_WIN32_SIZE,
+ GTK_WIN32_PART_WIDTH,
+ GTK_WIN32_PART_HEIGHT
+} GtkWin32SizeType;
+
+static const char *css_value_names[] = {
+ "-gtk-win32-size(",
+ "-gtk-win32-part-width(",
+ "-gtk-win32-part-height("
+};
+
struct _GtkCssValue {
GTK_CSS_VALUE_BASE
- double scale; /* needed for calc() math */
- GtkWin32Theme *theme;
- gint id;
+ double scale; /* needed for calc() math */
+ GtkWin32Theme *theme;
+ GtkWin32SizeType type;
+ union {
+ struct {
+ gint id;
+ } size;
+ struct {
+ gint part;
+ gint state;
+ } part;
+ } val;
};
-static GtkCssValue * gtk_css_win32_size_value_new (double scale,
- GtkWin32Theme *theme,
- int id);
+static GtkCssValue * gtk_css_win32_size_value_new (double scale,
+ GtkWin32Theme *theme,
+ GtkWin32SizeType type);
static void
gtk_css_value_win32_size_free (GtkCssValue *value)
@@ -39,6 +60,32 @@ gtk_css_value_win32_size_free (GtkCssValue *value)
g_slice_free (GtkCssValue, value);
}
+static int
+gtk_css_value_win32_compute_size (const GtkCssValue *value)
+{
+ int size;
+
+ switch (value->type)
+ {
+ case GTK_WIN32_SIZE:
+ size = gtk_win32_theme_get_size (value->theme, value->val.size.id);
+
+ case GTK_WIN32_PART_WIDTH:
+ gtk_win32_theme_get_part_size (value->theme, value->val.part.part, value->val.part.state, &size, NULL);
+ break;
+
+ case GTK_WIN32_PART_HEIGHT:
+ gtk_win32_theme_get_part_size (value->theme, value->val.part.part, value->val.part.state, NULL, &size);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ return 0;
+ }
+
+ return size;
+}
+
static GtkCssValue *
gtk_css_value_win32_size_compute (GtkCssValue *value,
guint property_id,
@@ -46,15 +93,31 @@ gtk_css_value_win32_size_compute (GtkCssValue *value,
GtkCssStyle *style,
GtkCssStyle *parent_style)
{
- return _gtk_css_number_value_new (value->scale * gtk_win32_theme_get_size (value->theme, value->id),
GTK_CSS_PX);
+ return _gtk_css_number_value_new (value->scale * gtk_css_value_win32_compute_size (value), GTK_CSS_PX);
}
static gboolean
gtk_css_value_win32_size_equal (const GtkCssValue *value1,
const GtkCssValue *value2)
{
- return gtk_win32_theme_equal (value1->theme, value2->theme) &&
- value1->id == value2->id;
+ if (value1->type != value2->type ||
+ !gtk_win32_theme_equal (value1->theme, value2->theme) )
+ return FALSE;
+
+ switch (value1->type)
+ {
+ case GTK_WIN32_SIZE:
+ return value1->val.size.id == value2->val.size.id;
+
+ case GTK_WIN32_PART_WIDTH:
+ case GTK_WIN32_PART_HEIGHT:
+ return value1->val.part.part == value2->val.part.part
+ && value1->val.part.state == value2->val.part.state;
+
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
}
static void
@@ -65,16 +128,33 @@ gtk_css_value_win32_size_print (const GtkCssValue *value,
{
g_string_append_printf (string, "%g * ", value->scale);
}
- g_string_append (string, "-gtk-win32-size(");
+ g_string_append (string, css_value_names[value->type]);
gtk_win32_theme_print (value->theme, string);
- g_string_append_printf (string, ", %d)", value->id);
+
+ switch (value->type)
+ {
+ case GTK_WIN32_SIZE:
+ g_string_append_printf (string, ", %d", value->val.size.id);
+ break;
+
+ case GTK_WIN32_PART_WIDTH:
+ case GTK_WIN32_PART_HEIGHT:
+ g_string_append_printf (string, ", %d, %d", value->val.part.part, value->val.part.state);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ g_string_append (string, ")");
}
static double
gtk_css_value_win32_size_get (const GtkCssValue *value,
double one_hundred_percent)
{
- return value->scale * gtk_win32_theme_get_size (value->theme, value->id);
+ return value->scale * gtk_css_value_win32_compute_size (value);
}
static GtkCssDimension
@@ -93,23 +173,33 @@ static GtkCssValue *
gtk_css_value_win32_size_multiply (const GtkCssValue *value,
double factor)
{
- return gtk_css_win32_size_value_new (value->scale * factor, value->theme, value->id);
+ GtkCssValue *result;
+
+ result = gtk_css_win32_size_value_new (value->scale * factor, value->theme, value->type);
+ result->val = value->val;
+
+ return result;
}
static GtkCssValue *
gtk_css_value_win32_size_try_add (const GtkCssValue *value1,
const GtkCssValue *value2)
{
+ GtkCssValue *result;
+
if (!gtk_css_value_win32_size_equal (value1, value2))
return NULL;
- return gtk_css_win32_size_value_new (value1->scale + value2->scale, value1->theme, value1->id);
+ result = gtk_css_win32_size_value_new (value1->scale + value2->scale, value1->theme, value1->type);
+ result->val = value1->val;
+
+ return result;
}
static gint
gtk_css_value_win32_size_get_calc_term_order (const GtkCssValue *value)
{
- return 2000;
+ return 2000 + 100 * value->type;
}
static const GtkCssNumberValueClass GTK_CSS_VALUE_WIN32_SIZE = {
@@ -129,31 +219,79 @@ static const GtkCssNumberValueClass GTK_CSS_VALUE_WIN32_SIZE = {
};
static GtkCssValue *
-gtk_css_win32_size_value_new (double scale,
- GtkWin32Theme *theme,
- int id)
+gtk_css_win32_size_value_new (double scale,
+ GtkWin32Theme *theme,
+ GtkWin32SizeType type)
{
GtkCssValue *result;
result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_WIN32_SIZE.value_class);
result->scale = scale;
result->theme = gtk_win32_theme_ref (theme);
- result->id = id;
+ result->type = type;
return result;
}
+static GtkCssValue *
+gtk_css_win32_size_value_parse_size (GtkCssValue *value,
+ GtkCssParser *parser)
+{
+ if (!_gtk_css_parser_try_int (parser, &value->val.size.id))
+ {
+ _gtk_css_value_unref (value);
+ _gtk_css_parser_error (parser, "Expected an integer ID");
+ return NULL;
+ }
+
+ return value;
+}
+
+static GtkCssValue *
+gtk_css_win32_size_value_parse_part_size (GtkCssValue *value,
+ GtkCssParser *parser)
+{
+ if (!_gtk_css_parser_try_int (parser, &value->val.part.part))
+ {
+ _gtk_css_value_unref (value);
+ _gtk_css_parser_error (parser, "Expected an integer part ID");
+ return NULL;
+ }
+
+ if (! _gtk_css_parser_try (parser, ",", TRUE))
+ {
+ _gtk_css_value_unref (value);
+ _gtk_css_parser_error (parser, "Expected ','");
+ return NULL;
+ }
+
+ if (!_gtk_css_parser_try_int (parser, &value->val.part.state))
+ {
+ _gtk_css_value_unref (value);
+ _gtk_css_parser_error (parser, "Expected an integer state ID");
+ return NULL;
+ }
+
+ return value;
+}
+
GtkCssValue *
gtk_css_win32_size_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags)
{
GtkWin32Theme *theme;
GtkCssValue *result;
- int id;
+ guint type;
- if (!_gtk_css_parser_try (parser, "-gtk-win32-size(", TRUE))
+ for (type = 0; type < G_N_ELEMENTS(css_value_names); type++)
{
- _gtk_css_parser_error (parser, "Expected '-gtk-win32-size('");
+ if (_gtk_css_parser_try (parser, css_value_names[type], TRUE))
+ break;
+ }
+
+ if (type >= G_N_ELEMENTS(css_value_names))
+ {
+ _gtk_css_parser_error (parser, "Not a win32 size value");
return NULL;
}
@@ -161,29 +299,43 @@ gtk_css_win32_size_value_parse (GtkCssParser *parser,
if (theme == NULL)
return NULL;
+ result = gtk_css_win32_size_value_new (1.0, theme, type);
+ gtk_win32_theme_unref (theme);
+
if (! _gtk_css_parser_try (parser, ",", TRUE))
{
- gtk_win32_theme_unref (theme);
+ _gtk_css_value_unref (result);
_gtk_css_parser_error (parser, "Expected ','");
return NULL;
}
- if (!_gtk_css_parser_try_int (parser, &id))
+ switch (result->type)
{
- gtk_win32_theme_unref (theme);
- _gtk_css_parser_error (parser, "Expected an integer ID");
- return 0;
+ case GTK_WIN32_SIZE:
+ result = gtk_css_win32_size_value_parse_size (result, parser);
+ break;
+
+ case GTK_WIN32_PART_WIDTH:
+ case GTK_WIN32_PART_HEIGHT:
+ result = gtk_css_win32_size_value_parse_part_size (result, parser);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ _gtk_css_value_unref (result);
+ result = NULL;
+ break;
}
+ if (result == NULL)
+ return NULL;
+
if (!_gtk_css_parser_try (parser, ")", TRUE))
{
- gtk_win32_theme_unref (theme);
+ _gtk_css_value_unref (result);
_gtk_css_parser_error (parser, "Expected ')'");
return NULL;
}
- result = gtk_css_win32_size_value_new (1.0, theme, id);
- gtk_win32_theme_unref (theme);
-
return result;
}
diff --git a/gtk/gtkwin32theme.c b/gtk/gtkwin32theme.c
index e1de2c9..d2fb6f0 100644
--- a/gtk/gtkwin32theme.c
+++ b/gtk/gtkwin32theme.c
@@ -74,7 +74,7 @@ static IsThemeActiveFunc is_theme_active = NULL;
static IsAppThemedFunc is_app_themed = NULL;
static IsThemeBackgroundPartiallyTransparentFunc is_theme_partially_transparent = NULL;
static DrawThemeParentBackgroundFunc draw_theme_parent_background = NULL;
-static GetThemePartSizeFunc get_theme_part_size = NULL;
+static GetThemePartSizeFunc GetThemePartSize = NULL;
#endif
@@ -209,7 +209,7 @@ gtk_win32_theme_init (void)
get_theme_sys_metric = (GetThemeSysSizeFunc) GetProcAddress (uxtheme_dll, "GetThemeSysSize");
is_theme_partially_transparent = (IsThemeBackgroundPartiallyTransparentFunc) GetProcAddress
(uxtheme_dll, "IsThemeBackgroundPartiallyTransparent");
draw_theme_parent_background = (DrawThemeParentBackgroundFunc) GetProcAddress (uxtheme_dll,
"DrawThemeParentBackground");
- get_theme_part_size = (GetThemePartSizeFunc) GetProcAddress (uxtheme_dll, "GetThemePartSize");
+ GetThemePartSize = (GetThemePartSizeFunc) GetProcAddress (uxtheme_dll, "GetThemePartSize");
}
if (is_app_themed && is_theme_active)
@@ -337,7 +337,7 @@ gtk_win32_theme_create_surface (GtkWin32Theme *theme,
rect.bottom = height;
hdc = GetDC (NULL);
- res = get_theme_part_size (htheme, hdc, xp_part, state, &rect, 2, &size);
+ res = GetThemePartSize (htheme, hdc, xp_part, state, &rect, 2 /*TS_DRAW*/, &size);
ReleaseDC (NULL, hdc);
if (res == S_OK)
@@ -389,6 +389,53 @@ gtk_win32_theme_create_surface (GtkWin32Theme *theme,
return surface;
}
+void
+gtk_win32_theme_get_part_size (GtkWin32Theme *theme,
+ int part,
+ int state,
+ int *width,
+ int *height)
+{
+#if 0
+ /* Known fallback sizes copied from Wine */
+ struct {
+ int part;
+ int width;
+ int height;
+ } fallback_sizes[] = {
+ { BP_RADIOBUTTON, 13, 13 },
+ { BP_CHECKBOX, 13, 13 },
+ };
+#endif
+#ifdef G_OS_WIN32
+ HTHEME htheme = gtk_win32_theme_get_htheme (theme);
+ SIZE size;
+ HDC hdc;
+ HRESULT res;
+
+ if (use_xp_theme && GetThemePartSize != NULL && htheme != NULL)
+ {
+ hdc = GetDC (NULL);
+ res = GetThemePartSize (htheme, hdc, part, state, NULL, 2 /*TS_DRAW*/, &size);
+ ReleaseDC (NULL, hdc);
+
+ if (SUCCEEDED (res))
+ {
+ if (width)
+ *width = size.cx;
+ if (height)
+ *height = size.cy;
+ return;
+ }
+ }
+#endif
+
+ if (width)
+ *width = 1;
+ if (height)
+ *height = 1;
+}
+
int
gtk_win32_theme_get_size (GtkWin32Theme *theme,
int id)
diff --git a/gtk/gtkwin32themeprivate.h b/gtk/gtkwin32themeprivate.h
index c05311d..b03bea8 100644
--- a/gtk/gtkwin32themeprivate.h
+++ b/gtk/gtkwin32themeprivate.h
@@ -48,6 +48,12 @@ cairo_surface_t * gtk_win32_theme_create_surface (GtkWin32Theme *theme,
int height,
int *x_offs_out,
int *y_offs_out);
+
+void gtk_win32_theme_get_part_size (GtkWin32Theme *theme,
+ int part,
+ int state,
+ int *width,
+ int *height);
int gtk_win32_theme_get_size (GtkWin32Theme *theme,
int id);
void gtk_win32_theme_get_color (GtkWin32Theme *theme,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]