diff options
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkcssshorthandproperty.c | 36 | ||||
-rw-r--r-- | gtk/gtkcssstyleproperty.c | 223 | ||||
-rw-r--r-- | gtk/gtkstyleproperty.c | 279 | ||||
-rw-r--r-- | gtk/gtkstylepropertyprivate.h | 10 |
4 files changed, 303 insertions, 245 deletions
diff --git a/gtk/gtkcssshorthandproperty.c b/gtk/gtkcssshorthandproperty.c index 64c8633d03..6b85a98bc9 100644 --- a/gtk/gtkcssshorthandproperty.c +++ b/gtk/gtkcssshorthandproperty.c @@ -60,9 +60,42 @@ gtk_css_shorthand_property_set_property (GObject *object, } static void +_gtk_css_shorthand_property_assign (GtkStyleProperty *property, + GtkStyleProperties *props, + GtkStateFlags state, + const GValue *value) +{ + GParameter *parameters; + guint i, n_parameters; + + parameters = _gtk_style_property_unpack (property, value, &n_parameters); + + for (i = 0; i < n_parameters; i++) + { + _gtk_style_property_assign (_gtk_style_property_lookup (parameters[i].name), + props, + state, + ¶meters[i].value); + g_value_unset (¶meters[i].value); + } + g_free (parameters); +} + +static void +_gtk_css_shorthand_property_query (GtkStyleProperty *property, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context, + GValue *value) +{ + property->pack_func (value, props, state, context); +} + +static void _gtk_css_shorthand_property_class_init (GtkCssShorthandPropertyClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkStylePropertyClass *property_class = GTK_STYLE_PROPERTY_CLASS (klass); object_class->set_property = gtk_css_shorthand_property_set_property; @@ -73,6 +106,9 @@ _gtk_css_shorthand_property_class_init (GtkCssShorthandPropertyClass *klass) P_("The list of subproperties"), G_TYPE_STRV, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + property_class->assign = _gtk_css_shorthand_property_assign; + property_class->query = _gtk_css_shorthand_property_query; } static void diff --git a/gtk/gtkcssstyleproperty.c b/gtk/gtkcssstyleproperty.c index da90227814..f4fd07e02f 100644 --- a/gtk/gtkcssstyleproperty.c +++ b/gtk/gtkcssstyleproperty.c @@ -26,6 +26,14 @@ #include "gtkcsstypesprivate.h" #include "gtkintl.h" #include "gtkprivatetypebuiltins.h" +#include "gtkstylepropertiesprivate.h" + +/* for resolvage */ +#include <cairo-gobject.h> +#include "gtkgradient.h" +#include "gtkshadowprivate.h" +#include "gtkwin32themeprivate.h" + enum { PROP_0, @@ -100,9 +108,221 @@ gtk_css_style_property_get_property (GObject *object, } static void +_gtk_css_style_property_assign (GtkStyleProperty *property, + GtkStyleProperties *props, + GtkStateFlags state, + const GValue *value) +{ + _gtk_style_properties_set_property_by_property (props, + GTK_CSS_STYLE_PROPERTY (property), + state, + value); +} + +static void +_gtk_style_property_default_value (GtkStyleProperty *property, + GtkStyleProperties *properties, + GtkStateFlags state, + GValue *value) +{ + g_value_copy (_gtk_css_style_property_get_initial_value (GTK_CSS_STYLE_PROPERTY (property)), value); +} + +static gboolean +resolve_color (GtkStyleProperties *props, + GValue *value) +{ + GdkRGBA color; + + /* Resolve symbolic color to GdkRGBA */ + if (!gtk_symbolic_color_resolve (g_value_get_boxed (value), props, &color)) + return FALSE; + + /* Store it back, this is where GdkRGBA caching happens */ + g_value_unset (value); + g_value_init (value, GDK_TYPE_RGBA); + g_value_set_boxed (value, &color); + + return TRUE; +} + +static gboolean +resolve_color_rgb (GtkStyleProperties *props, + GValue *value) +{ + GdkColor color = { 0 }; + GdkRGBA rgba; + + if (!gtk_symbolic_color_resolve (g_value_get_boxed (value), props, &rgba)) + return FALSE; + + color.red = rgba.red * 65535. + 0.5; + color.green = rgba.green * 65535. + 0.5; + color.blue = rgba.blue * 65535. + 0.5; + + g_value_unset (value); + g_value_init (value, GDK_TYPE_COLOR); + g_value_set_boxed (value, &color); + + return TRUE; +} + +static gboolean +resolve_win32_theme_part (GtkStyleProperties *props, + GValue *value, + GValue *value_out, + GtkStylePropertyContext *context) +{ + GtkWin32ThemePart *part; + cairo_pattern_t *pattern; + + part = g_value_get_boxed (value); + if (part == NULL) + return FALSE; + + pattern = _gtk_win32_theme_part_render (part, context->width, context->height); + + g_value_take_boxed (value_out, pattern); + + return TRUE; +} + + +static gboolean +resolve_gradient (GtkStyleProperties *props, + GValue *value) +{ + cairo_pattern_t *gradient; + + if (!gtk_gradient_resolve (g_value_get_boxed (value), props, &gradient)) + return FALSE; + + /* Store it back, this is where cairo_pattern_t caching happens */ + g_value_unset (value); + g_value_init (value, CAIRO_GOBJECT_TYPE_PATTERN); + g_value_take_boxed (value, gradient); + + return TRUE; +} + +static gboolean +resolve_shadow (GtkStyleProperties *props, + GValue *value) +{ + GtkShadow *resolved, *base; + + base = g_value_get_boxed (value); + + if (base == NULL) + return TRUE; + + if (_gtk_shadow_get_resolved (base)) + return TRUE; + + resolved = _gtk_shadow_resolve (base, props); + if (resolved == NULL) + return FALSE; + + g_value_take_boxed (value, resolved); + + return TRUE; +} + +static void +_gtk_style_property_resolve (GtkStyleProperty *property, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context, + GValue *val, + GValue *val_out) +{ + if (G_VALUE_TYPE (val) == GTK_TYPE_CSS_SPECIAL_VALUE) + { + GtkCssSpecialValue special = g_value_get_enum (val); + + g_value_unset (val); + switch (special) + { + case GTK_CSS_CURRENT_COLOR: + g_assert (property->pspec->value_type == GDK_TYPE_RGBA); + gtk_style_properties_get_property (props, "color", state, val); + break; + case GTK_CSS_INHERIT: + case GTK_CSS_INITIAL: + default: + g_assert_not_reached (); + } + } + else if (G_VALUE_TYPE (val) == GTK_TYPE_SYMBOLIC_COLOR) + { + if (property->pspec->value_type == GDK_TYPE_RGBA) + { + if (resolve_color (props, val)) + goto out; + } + else if (property->pspec->value_type == GDK_TYPE_COLOR) + { + if (resolve_color_rgb (props, val)) + goto out; + } + + g_value_unset (val); + g_value_init (val, property->pspec->value_type); + _gtk_style_property_default_value (property, props, state, val); + } + else if (G_VALUE_TYPE (val) == GDK_TYPE_RGBA) + { + if (g_value_get_boxed (val) == NULL) + _gtk_style_property_default_value (property, props, state, val); + } + else if (G_VALUE_TYPE (val) == GTK_TYPE_GRADIENT) + { + g_return_if_fail (property->pspec->value_type == CAIRO_GOBJECT_TYPE_PATTERN); + + if (!resolve_gradient (props, val)) + { + g_value_unset (val); + g_value_init (val, CAIRO_GOBJECT_TYPE_PATTERN); + _gtk_style_property_default_value (property, props, state, val); + } + } + else if (G_VALUE_TYPE (val) == GTK_TYPE_SHADOW) + { + if (!resolve_shadow (props, val)) + _gtk_style_property_default_value (property, props, state, val); + } + else if (G_VALUE_TYPE (val) == GTK_TYPE_WIN32_THEME_PART) + { + if (resolve_win32_theme_part (props, val, val_out, context)) + return; /* Don't copy val, this sets val_out */ + _gtk_style_property_default_value (property, props, state, val); + } + + out: + g_value_copy (val, val_out); +} + +static void +_gtk_css_style_property_query (GtkStyleProperty *property, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context, + GValue *value) +{ + const GValue *val; + + val = _gtk_style_properties_peek_property (props, GTK_CSS_STYLE_PROPERTY (property), state); + if (val) + _gtk_style_property_resolve (property, props, state, context, (GValue *) val, value); + else + _gtk_style_property_default_value (property, props, state, value); +} + +static void _gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkStylePropertyClass *property_class = GTK_STYLE_PROPERTY_CLASS (klass); object_class->constructed = gtk_css_style_property_constructed; object_class->set_property = gtk_css_style_property_set_property; @@ -130,6 +350,9 @@ _gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass) G_TYPE_VALUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + property_class->assign = _gtk_css_style_property_assign; + property_class->query = _gtk_css_style_property_query; + klass->style_properties = g_ptr_array_new (); } diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c index 25556a7fbc..1c638b3ba3 100644 --- a/gtk/gtkstyleproperty.c +++ b/gtk/gtkstyleproperty.c @@ -437,189 +437,6 @@ _gtk_style_property_parse_value (GtkStyleProperty *property, return _gtk_css_style_parse_value (value, parser, base); } -static void -_gtk_style_property_default_value (GtkStyleProperty *property, - GtkStyleProperties *properties, - GtkStateFlags state, - GValue *value) -{ - g_value_copy (_gtk_css_style_property_get_initial_value (GTK_CSS_STYLE_PROPERTY (property)), value); -} - -static gboolean -resolve_color (GtkStyleProperties *props, - GValue *value) -{ - GdkRGBA color; - - /* Resolve symbolic color to GdkRGBA */ - if (!gtk_symbolic_color_resolve (g_value_get_boxed (value), props, &color)) - return FALSE; - - /* Store it back, this is where GdkRGBA caching happens */ - g_value_unset (value); - g_value_init (value, GDK_TYPE_RGBA); - g_value_set_boxed (value, &color); - - return TRUE; -} - -static gboolean -resolve_color_rgb (GtkStyleProperties *props, - GValue *value) -{ - GdkColor color = { 0 }; - GdkRGBA rgba; - - if (!gtk_symbolic_color_resolve (g_value_get_boxed (value), props, &rgba)) - return FALSE; - - color.red = rgba.red * 65535. + 0.5; - color.green = rgba.green * 65535. + 0.5; - color.blue = rgba.blue * 65535. + 0.5; - - g_value_unset (value); - g_value_init (value, GDK_TYPE_COLOR); - g_value_set_boxed (value, &color); - - return TRUE; -} - -static gboolean -resolve_win32_theme_part (GtkStyleProperties *props, - GValue *value, - GValue *value_out, - GtkStylePropertyContext *context) -{ - GtkWin32ThemePart *part; - cairo_pattern_t *pattern; - - part = g_value_get_boxed (value); - if (part == NULL) - return FALSE; - - pattern = _gtk_win32_theme_part_render (part, context->width, context->height); - - g_value_take_boxed (value_out, pattern); - - return TRUE; -} - - -static gboolean -resolve_gradient (GtkStyleProperties *props, - GValue *value) -{ - cairo_pattern_t *gradient; - - if (!gtk_gradient_resolve (g_value_get_boxed (value), props, &gradient)) - return FALSE; - - /* Store it back, this is where cairo_pattern_t caching happens */ - g_value_unset (value); - g_value_init (value, CAIRO_GOBJECT_TYPE_PATTERN); - g_value_take_boxed (value, gradient); - - return TRUE; -} - -static gboolean -resolve_shadow (GtkStyleProperties *props, - GValue *value) -{ - GtkShadow *resolved, *base; - - base = g_value_get_boxed (value); - - if (base == NULL) - return TRUE; - - if (_gtk_shadow_get_resolved (base)) - return TRUE; - - resolved = _gtk_shadow_resolve (base, props); - if (resolved == NULL) - return FALSE; - - g_value_take_boxed (value, resolved); - - return TRUE; -} - -static void -_gtk_style_property_resolve (GtkStyleProperty *property, - GtkStyleProperties *props, - GtkStateFlags state, - GtkStylePropertyContext *context, - GValue *val, - GValue *val_out) -{ - if (G_VALUE_TYPE (val) == GTK_TYPE_CSS_SPECIAL_VALUE) - { - GtkCssSpecialValue special = g_value_get_enum (val); - - g_value_unset (val); - switch (special) - { - case GTK_CSS_CURRENT_COLOR: - g_assert (property->pspec->value_type == GDK_TYPE_RGBA); - gtk_style_properties_get_property (props, "color", state, val); - break; - case GTK_CSS_INHERIT: - case GTK_CSS_INITIAL: - default: - g_assert_not_reached (); - } - } - else if (G_VALUE_TYPE (val) == GTK_TYPE_SYMBOLIC_COLOR) - { - if (property->pspec->value_type == GDK_TYPE_RGBA) - { - if (resolve_color (props, val)) - goto out; - } - else if (property->pspec->value_type == GDK_TYPE_COLOR) - { - if (resolve_color_rgb (props, val)) - goto out; - } - - g_value_unset (val); - g_value_init (val, property->pspec->value_type); - _gtk_style_property_default_value (property, props, state, val); - } - else if (G_VALUE_TYPE (val) == GDK_TYPE_RGBA) - { - if (g_value_get_boxed (val) == NULL) - _gtk_style_property_default_value (property, props, state, val); - } - else if (G_VALUE_TYPE (val) == GTK_TYPE_GRADIENT) - { - g_return_if_fail (property->pspec->value_type == CAIRO_GOBJECT_TYPE_PATTERN); - - if (!resolve_gradient (props, val)) - { - g_value_unset (val); - g_value_init (val, CAIRO_GOBJECT_TYPE_PATTERN); - _gtk_style_property_default_value (property, props, state, val); - } - } - else if (G_VALUE_TYPE (val) == GTK_TYPE_SHADOW) - { - if (!resolve_shadow (props, val)) - _gtk_style_property_default_value (property, props, state, val); - } - else if (G_VALUE_TYPE (val) == GTK_TYPE_WIN32_THEME_PART) - { - if (resolve_win32_theme_part (props, val, val_out, context)) - return; /* Don't copy val, this sets val_out */ - _gtk_style_property_default_value (property, props, state, val); - } - - out: - g_value_copy (val, val_out); -} - GParameter * _gtk_style_property_unpack (GtkStyleProperty *property, const GValue *value, @@ -633,62 +450,47 @@ _gtk_style_property_unpack (GtkStyleProperty *property, return property->unpack_func (value, n_params); } -static void -_gtk_style_property_pack (GtkStyleProperty *property, - GtkStyleProperties *props, - GtkStateFlags state, - GtkStylePropertyContext *context, - GValue *value) -{ - g_return_if_fail (property != NULL); - g_return_if_fail (property->pack_func != NULL); - g_return_if_fail (GTK_IS_STYLE_PROPERTIES (props)); - g_return_if_fail (G_IS_VALUE (value)); - - property->pack_func (value, props, state, context); -} - +/** + * _gtk_style_property_assign: + * @property: the property + * @props: The properties to assign to + * @state: The state to assign + * @value: (out): the #GValue with the value to be + * assigned + * + * This function is called by gtk_style_properties_set() and in + * turn gtk_style_context_set() and similar functions to set the + * value from code using old APIs. + **/ void _gtk_style_property_assign (GtkStyleProperty *property, GtkStyleProperties *props, GtkStateFlags state, const GValue *value) { + GtkStylePropertyClass *klass; + g_return_if_fail (GTK_IS_STYLE_PROPERTY (property)); g_return_if_fail (GTK_IS_STYLE_PROPERTIES (props)); g_return_if_fail (value != NULL); - if (GTK_IS_CSS_SHORTHAND_PROPERTY (property)) - { - GParameter *parameters; - guint i, n_parameters; - - parameters = _gtk_style_property_unpack (property, value, &n_parameters); + klass = GTK_STYLE_PROPERTY_GET_CLASS (property); - for (i = 0; i < n_parameters; i++) - { - _gtk_style_property_assign (_gtk_style_property_lookup (parameters[i].name), - props, - state, - ¶meters[i].value); - g_value_unset (¶meters[i].value); - } - g_free (parameters); - return; - } - else if (GTK_IS_CSS_STYLE_PROPERTY (property)) - { - _gtk_style_properties_set_property_by_property (props, - GTK_CSS_STYLE_PROPERTY (property), - state, - value); - } - else - { - g_assert_not_reached (); - } + klass->assign (property, props, state, value); } +/** + * _gtk_style_property_query: + * @property: the property + * @props: The properties to query + * @state: The state to query + * @value: (out): an uninitialized #GValue to be filled with the + * contents of the lookup + * + * This function is called by gtk_style_properties_get() and in + * turn gtk_style_context_get() and similar functions to get the + * value to return to code using old APIs. + **/ void _gtk_style_property_query (GtkStyleProperty *property, GtkStyleProperties *props, @@ -696,32 +498,18 @@ _gtk_style_property_query (GtkStyleProperty *property, GtkStylePropertyContext *context, GValue *value) { + GtkStylePropertyClass *klass; g_return_if_fail (property != NULL); g_return_if_fail (GTK_IS_STYLE_PROPERTIES (props)); g_return_if_fail (context != NULL); g_return_if_fail (value != NULL); - g_value_init (value, property->pspec->value_type); + klass = GTK_STYLE_PROPERTY_GET_CLASS (property); - if (GTK_IS_CSS_STYLE_PROPERTY (property)) - { - const GValue *val; - - val = _gtk_style_properties_peek_property (props, GTK_CSS_STYLE_PROPERTY (property), state); - if (val) - _gtk_style_property_resolve (property, props, state, context, (GValue *) val, value); - else - _gtk_style_property_default_value (property, props, state, value); - } - else if (GTK_IS_CSS_SHORTHAND_PROPERTY (property)) - { - _gtk_style_property_pack (property, props, state, context, value); - } - else - { - g_assert_not_reached (); - } + g_value_init (value, property->value_type); + + klass->query (property, props, state, context, value); } #define rgba_init(rgba, r, g, b, a) G_STMT_START{ \ @@ -1168,6 +956,7 @@ _gtk_style_property_register (GParamSpec *pspec, "name", pspec->name, "value-type", pspec->value_type, NULL); + g_assert (node->value_type == pspec->value_type); node->pspec = pspec; node->property_parse_func = property_parse_func; node->parse_func = parse_func; diff --git a/gtk/gtkstylepropertyprivate.h b/gtk/gtkstylepropertyprivate.h index 92c3fea180..7b7b60bbec 100644 --- a/gtk/gtkstylepropertyprivate.h +++ b/gtk/gtkstylepropertyprivate.h @@ -71,6 +71,16 @@ struct _GtkStylePropertyClass { GObjectClass parent_class; + void (* assign) (GtkStyleProperty *property, + GtkStyleProperties *props, + GtkStateFlags state, + const GValue *value); + void (* query) (GtkStyleProperty *property, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context, + GValue *value); + GHashTable *properties; }; |