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.
This commit is contained in:
Benjamin Otte 2011-05-21 23:47:19 +02:00
parent 70e654f1a5
commit 42a4bd1c5b
4 changed files with 117 additions and 4 deletions

View File

@ -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 (&parameters[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);
}

View File

@ -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,
&parameters[i].value);
g_value_unset (&parameters[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 };

View File

@ -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);
}

View File

@ -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,