summaryrefslogtreecommitdiff
path: root/gtk/gtkcssstyleproperty.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2012-01-01 21:58:45 +0100
committerBenjamin Otte <otte@redhat.com>2012-01-09 18:37:53 +0100
commit79a171de0a592dcacdcd2151229ec77733441f15 (patch)
tree38d08c070fa91036379c6172c299e7dc860bd6a7 /gtk/gtkcssstyleproperty.c
parentb904679a111224039a92e6f50acd97f6218a2d3a (diff)
downloadgtk+-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.c223
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 ();
}