[gtk+] style: Add support for shorthand properties
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] style: Add support for shorthand properties
- Date: Sun, 22 May 2011 04:14:22 +0000 (UTC)
commit 42a4bd1c5b8e1721ac25d3ed08481113a4a26f71
Author: Benjamin Otte <otte redhat com>
Date: Sat May 21 23:47:19 2011 +0200
style: Add support for shorthand properties
Shorthand properties are basically the same a in CSS. For storage in
style properties or the CSS provider, they are unpacked into the real
values, so it is possible to partially override them.
No properties are yet converted to the new world yet, this is just the
code for supporting them.
gtk/gtkcssprovider.c | 20 +++++++++++++++++++
gtk/gtkstyleproperties.c | 35 ++++++++++++++++++++++++++++++++-
gtk/gtkstyleproperty.c | 43 ++++++++++++++++++++++++++++++++++++++++-
gtk/gtkstylepropertyprivate.h | 23 ++++++++++++++++++++-
4 files changed, 117 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 4f09c5e..6f8cbe4 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -1000,6 +1000,26 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset,
NULL,
(GDestroyNotify) property_value_free);
+ if (_gtk_style_property_is_shorthand (prop))
+ {
+ GParameter *parameters;
+ guint i, n_parameters;
+
+ parameters = _gtk_style_property_unpack (prop, value, &n_parameters);
+
+ for (i = 0; i < n_parameters; i++)
+ {
+ const GtkStyleProperty *child;
+ GValue *value;
+
+ child = _gtk_style_property_lookup (parameters[i].name);
+ value = g_memdup (¶meters[i].value, sizeof (GValue));
+ gtk_css_ruleset_add (ruleset, child, value);
+ }
+ g_free (parameters);
+ return;
+ }
+
ruleset->has_inherit |= gtk_style_param_get_inherit (prop->pspec);
g_hash_table_insert (ruleset->style, (gpointer) prop, value);
}
diff --git a/gtk/gtkstyleproperties.c b/gtk/gtkstyleproperties.c
index 1c5f0d9..a2cb8e5 100644
--- a/gtk/gtkstyleproperties.c
+++ b/gtk/gtkstyleproperties.c
@@ -311,7 +311,9 @@ gtk_style_properties_register_property (GtkStylePropertyParser parse_func,
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
_gtk_style_property_register (pspec,
- parse_func);
+ parse_func,
+ NULL,
+ NULL);
}
/**
@@ -511,6 +513,25 @@ _gtk_style_properties_set_property_by_property (GtkStyleProperties *props,
else
g_return_if_fail (style_prop->pspec->value_type == value_type);
+ if (_gtk_style_property_is_shorthand (style_prop))
+ {
+ GParameter *parameters;
+ guint i, n_parameters;
+
+ parameters = _gtk_style_property_unpack (style_prop, value, &n_parameters);
+
+ for (i = 0; i < n_parameters; i++)
+ {
+ gtk_style_properties_set_property (props,
+ parameters[i].name,
+ state,
+ ¶meters[i].value);
+ g_value_unset (¶meters[i].value);
+ }
+ g_free (parameters);
+ return;
+ }
+
priv = props->priv;
prop = g_hash_table_lookup (priv->properties, style_prop->pspec);
@@ -789,6 +810,7 @@ lookup_default_value (const GtkStyleProperty *node,
g_param_value_set_default (node->pspec, value);
}
+/* NB: Will return NULL for shorthands */
const GValue *
_gtk_style_properties_peek_property (GtkStyleProperties *props,
const gchar *prop_name,
@@ -864,6 +886,8 @@ gtk_style_properties_get_property (GtkStyleProperties *props,
if (val)
g_value_copy (val, value);
+ else if (_gtk_style_property_is_shorthand (node))
+ _gtk_style_property_pack (node, props, state, value);
else
lookup_default_value (node, value);
@@ -907,6 +931,15 @@ gtk_style_properties_get_valist (GtkStyleProperties *props,
{
G_VALUE_LCOPY (val, args, 0, &error);
}
+ else if (_gtk_style_property_is_shorthand (node))
+ {
+ GValue packed = { 0 };
+
+ g_value_init (&packed, node->pspec->value_type);
+ _gtk_style_property_pack (node, props, state, &packed);
+ G_VALUE_LCOPY (&packed, args, 0, &error);
+ g_value_unset (&packed);
+ }
else
{
GValue default_value = { 0 };
diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c
index 022e577..2d6bda6 100644
--- a/gtk/gtkstyleproperty.c
+++ b/gtk/gtkstyleproperty.c
@@ -1281,6 +1281,41 @@ _gtk_css_value_to_string (const GValue *value)
return g_strdup_value_contents (value);
}
+gboolean
+_gtk_style_property_is_shorthand (const GtkStyleProperty *property)
+{
+ g_return_val_if_fail (property != NULL, FALSE);
+
+ return property->pack_func != NULL;
+}
+
+GParameter *
+_gtk_style_property_unpack (const GtkStyleProperty *property,
+ const GValue *value,
+ guint *n_params)
+{
+ g_return_val_if_fail (property != NULL, NULL);
+ g_return_val_if_fail (property->unpack_func != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+ g_return_val_if_fail (n_params != NULL, NULL);
+
+ return property->unpack_func (value, n_params);
+}
+
+void
+_gtk_style_property_pack (const GtkStyleProperty *property,
+ GtkStyleProperties *props,
+ GtkStateFlags state,
+ 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);
+}
+
static void
gtk_style_property_init (void)
{
@@ -1392,11 +1427,15 @@ _gtk_style_property_lookup (const char *name)
void
_gtk_style_property_register (GParamSpec *pspec,
- GtkStylePropertyParser parse_func)
+ GtkStylePropertyParser parse_func,
+ GtkStyleUnpackFunc unpack_func,
+ GtkStylePackFunc pack_func)
{
const GtkStyleProperty *existing;
GtkStyleProperty *node;
+ g_return_if_fail ((pack_func == NULL) == (unpack_func == NULL));
+
gtk_style_property_init ();
existing = _gtk_style_property_lookup (pspec->name);
@@ -1410,6 +1449,8 @@ _gtk_style_property_register (GParamSpec *pspec,
node = g_slice_new0 (GtkStyleProperty);
node->pspec = pspec;
node->parse_func = parse_func;
+ node->pack_func = pack_func;
+ node->unpack_func = unpack_func;
g_hash_table_insert (properties, pspec->name, node);
}
diff --git a/gtk/gtkstylepropertyprivate.h b/gtk/gtkstylepropertyprivate.h
index 57dd0d9..38850a1 100644
--- a/gtk/gtkstylepropertyprivate.h
+++ b/gtk/gtkstylepropertyprivate.h
@@ -26,16 +26,35 @@ G_BEGIN_DECLS
typedef struct _GtkStyleProperty GtkStyleProperty;
+typedef GParameter * (* GtkStyleUnpackFunc) (const GValue *value,
+ guint *n_params);
+typedef void (* GtkStylePackFunc) (GValue *value,
+ GtkStyleProperties *props,
+ GtkStateFlags flags);
+
struct _GtkStyleProperty
{
GParamSpec *pspec;
GtkStylePropertyParser parse_func;
+ GtkStyleUnpackFunc unpack_func;
+ GtkStylePackFunc pack_func;
};
-const GtkStyleProperty * _gtk_style_property_lookup (const char *name);
+const GtkStyleProperty * _gtk_style_property_lookup (const char *name);
void _gtk_style_property_register (GParamSpec *pspec,
- GtkStylePropertyParser parse_func);
+ GtkStylePropertyParser parse_func,
+ GtkStyleUnpackFunc unpack_func,
+ GtkStylePackFunc pack_func);
+
+gboolean _gtk_style_property_is_shorthand (const GtkStyleProperty *property);
+GParameter * _gtk_style_property_unpack (const GtkStyleProperty *property,
+ const GValue *value,
+ guint *n_params);
+void _gtk_style_property_pack (const GtkStyleProperty *property,
+ GtkStyleProperties *props,
+ GtkStateFlags state,
+ GValue *value);
gboolean _gtk_css_value_parse (GValue *value,
GtkCssParser *parser,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]