diff options
author | Benjamin Otte <otte@redhat.com> | 2012-01-01 21:58:45 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2012-01-09 18:37:53 +0100 |
commit | 79a171de0a592dcacdcd2151229ec77733441f15 (patch) | |
tree | 38d08c070fa91036379c6172c299e7dc860bd6a7 /gtk/gtkcssstyleproperty.c | |
parent | b904679a111224039a92e6f50acd97f6218a2d3a (diff) | |
download | gtk+-79a171de0a592dcacdcd2151229ec77733441f15.tar.gz |
styleproperty: Make query() and assign() vfuncs
... and implement them in the 2 known subclasses.
Diffstat (limited to 'gtk/gtkcssstyleproperty.c')
-rw-r--r-- | gtk/gtkcssstyleproperty.c | 223 |
1 files changed, 223 insertions, 0 deletions
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 (); } |