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:
@ -1000,6 +1000,26 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset,
|
|||||||
NULL,
|
NULL,
|
||||||
(GDestroyNotify) property_value_free);
|
(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);
|
ruleset->has_inherit |= gtk_style_param_get_inherit (prop->pspec);
|
||||||
g_hash_table_insert (ruleset->style, (gpointer) prop, value);
|
g_hash_table_insert (ruleset->style, (gpointer) prop, value);
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,9 @@ gtk_style_properties_register_property (GtkStylePropertyParser parse_func,
|
|||||||
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
|
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
|
||||||
|
|
||||||
_gtk_style_property_register (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
|
else
|
||||||
g_return_if_fail (style_prop->pspec->value_type == value_type);
|
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;
|
priv = props->priv;
|
||||||
prop = g_hash_table_lookup (priv->properties, style_prop->pspec);
|
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);
|
g_param_value_set_default (node->pspec, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NB: Will return NULL for shorthands */
|
||||||
const GValue *
|
const GValue *
|
||||||
_gtk_style_properties_peek_property (GtkStyleProperties *props,
|
_gtk_style_properties_peek_property (GtkStyleProperties *props,
|
||||||
const gchar *prop_name,
|
const gchar *prop_name,
|
||||||
@ -864,6 +886,8 @@ gtk_style_properties_get_property (GtkStyleProperties *props,
|
|||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
g_value_copy (val, value);
|
g_value_copy (val, value);
|
||||||
|
else if (_gtk_style_property_is_shorthand (node))
|
||||||
|
_gtk_style_property_pack (node, props, state, value);
|
||||||
else
|
else
|
||||||
lookup_default_value (node, value);
|
lookup_default_value (node, value);
|
||||||
|
|
||||||
@ -907,6 +931,15 @@ gtk_style_properties_get_valist (GtkStyleProperties *props,
|
|||||||
{
|
{
|
||||||
G_VALUE_LCOPY (val, args, 0, &error);
|
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
|
else
|
||||||
{
|
{
|
||||||
GValue default_value = { 0 };
|
GValue default_value = { 0 };
|
||||||
|
@ -1281,6 +1281,41 @@ _gtk_css_value_to_string (const GValue *value)
|
|||||||
return g_strdup_value_contents (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
|
static void
|
||||||
gtk_style_property_init (void)
|
gtk_style_property_init (void)
|
||||||
{
|
{
|
||||||
@ -1392,11 +1427,15 @@ _gtk_style_property_lookup (const char *name)
|
|||||||
|
|
||||||
void
|
void
|
||||||
_gtk_style_property_register (GParamSpec *pspec,
|
_gtk_style_property_register (GParamSpec *pspec,
|
||||||
GtkStylePropertyParser parse_func)
|
GtkStylePropertyParser parse_func,
|
||||||
|
GtkStyleUnpackFunc unpack_func,
|
||||||
|
GtkStylePackFunc pack_func)
|
||||||
{
|
{
|
||||||
const GtkStyleProperty *existing;
|
const GtkStyleProperty *existing;
|
||||||
GtkStyleProperty *node;
|
GtkStyleProperty *node;
|
||||||
|
|
||||||
|
g_return_if_fail ((pack_func == NULL) == (unpack_func == NULL));
|
||||||
|
|
||||||
gtk_style_property_init ();
|
gtk_style_property_init ();
|
||||||
|
|
||||||
existing = _gtk_style_property_lookup (pspec->name);
|
existing = _gtk_style_property_lookup (pspec->name);
|
||||||
@ -1410,6 +1449,8 @@ _gtk_style_property_register (GParamSpec *pspec,
|
|||||||
node = g_slice_new0 (GtkStyleProperty);
|
node = g_slice_new0 (GtkStyleProperty);
|
||||||
node->pspec = pspec;
|
node->pspec = pspec;
|
||||||
node->parse_func = parse_func;
|
node->parse_func = parse_func;
|
||||||
|
node->pack_func = pack_func;
|
||||||
|
node->unpack_func = unpack_func;
|
||||||
|
|
||||||
g_hash_table_insert (properties, pspec->name, node);
|
g_hash_table_insert (properties, pspec->name, node);
|
||||||
}
|
}
|
||||||
|
@ -26,16 +26,35 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
typedef struct _GtkStyleProperty GtkStyleProperty;
|
typedef struct _GtkStyleProperty GtkStyleProperty;
|
||||||
|
|
||||||
|
typedef GParameter * (* GtkStyleUnpackFunc) (const GValue *value,
|
||||||
|
guint *n_params);
|
||||||
|
typedef void (* GtkStylePackFunc) (GValue *value,
|
||||||
|
GtkStyleProperties *props,
|
||||||
|
GtkStateFlags flags);
|
||||||
|
|
||||||
struct _GtkStyleProperty
|
struct _GtkStyleProperty
|
||||||
{
|
{
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
GtkStylePropertyParser parse_func;
|
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,
|
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,
|
gboolean _gtk_css_value_parse (GValue *value,
|
||||||
GtkCssParser *parser,
|
GtkCssParser *parser,
|
||||||
|
Reference in New Issue
Block a user