css: Introduce dependencies for value computations

When values are computed, they might depend on various other values and
we need to track this so we can update the values when those other
values change. This is the first step in making that happen.

This patch does not do any dependency tracking at all, instead it uses
GTK_CSS_DEPENDS_ON_EVERYTHING as a sort of FIXME.
This commit is contained in:
Benjamin Otte 2012-07-16 14:48:43 +02:00
parent 9e7e65ca6e
commit 0e2f35ed88
24 changed files with 153 additions and 85 deletions

View File

@ -41,9 +41,10 @@ gtk_css_value_array_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_array_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_array_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssValue *result;
gboolean changed = FALSE;
@ -52,10 +53,12 @@ gtk_css_value_array_compute (GtkCssValue *value,
if (value->n_values == 0)
return _gtk_css_value_ref (value);
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
result = _gtk_css_array_value_new_from_array (value->values, value->n_values);
for (i = 0; i < value->n_values; i++)
{
result->values[i] = _gtk_css_value_compute (value->values[i], property_id, context);
result->values[i] = _gtk_css_value_compute (value->values[i], property_id, context, NULL);
changed |= (result->values[i] != value->values[i]);
}

View File

@ -41,15 +41,18 @@ gtk_css_value_bg_size_free (GtkCssValue *value)
}
GtkCssValue *
gtk_css_value_bg_size_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_bg_size_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
if (value->x == NULL && value->y == NULL)
return _gtk_css_value_ref (value);
return _gtk_css_bg_size_value_new (value->x ? _gtk_css_value_compute (value->x, property_id, context) : NULL,
value->y ? _gtk_css_value_compute (value->y, property_id, context) : NULL);
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
return _gtk_css_bg_size_value_new (value->x ? _gtk_css_value_compute (value->x, property_id, context, NULL) : NULL,
value->y ? _gtk_css_value_compute (value->y, property_id, context, NULL) : NULL);
}
static gboolean

View File

@ -42,14 +42,17 @@ gtk_css_value_border_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_border_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_border_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssValue *computed;
gboolean changed = FALSE;
guint i;
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
computed = _gtk_css_border_value_new (NULL, NULL, NULL, NULL);
computed->fill = value->fill;
@ -57,7 +60,7 @@ gtk_css_value_border_compute (GtkCssValue *value,
{
if (value->values[i])
{
computed->values[i] = _gtk_css_value_compute (value->values[i], property_id, context);
computed->values[i] = _gtk_css_value_compute (value->values[i], property_id, context, NULL);
changed |= (computed->values[i] != value->values[i]);
}
}

View File

@ -113,7 +113,7 @@ _gtk_css_computed_values_compute_value (GtkCssComputedValues *values,
else
_gtk_css_value_ref (specified);
g_ptr_array_index (values->values, id) = _gtk_css_value_compute (specified, id, context);
g_ptr_array_index (values->values, id) = _gtk_css_value_compute (specified, id, context, NULL);
if (section)
{

View File

@ -37,14 +37,17 @@ gtk_css_value_corner_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_corner_compute (GtkCssValue *corner,
guint property_id,
GtkStyleContext *context)
gtk_css_value_corner_compute (GtkCssValue *corner,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssValue *x, *y;
x = _gtk_css_value_compute (corner->x, property_id, context);
y = _gtk_css_value_compute (corner->y, property_id, context);
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
x = _gtk_css_value_compute (corner->x, property_id, context, NULL);
y = _gtk_css_value_compute (corner->y, property_id, context, NULL);
if (x == corner->x && y == corner->y)
{
_gtk_css_value_unref (x);

View File

@ -50,9 +50,10 @@ gtk_css_value_ease_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_ease_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_ease_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
return _gtk_css_value_ref (value);
}

View File

@ -35,9 +35,10 @@ gtk_css_value_engine_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_engine_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_engine_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
return _gtk_css_value_ref (value);
}

View File

@ -36,9 +36,10 @@ gtk_css_value_enum_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_enum_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_enum_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
return _gtk_css_value_ref (value);
}

View File

@ -420,7 +420,7 @@ gtk_css_image_linear_compute (GtkCssImage *image,
copy = g_object_new (GTK_TYPE_CSS_IMAGE_LINEAR, NULL);
copy->repeating = linear->repeating;
copy->angle = _gtk_css_value_compute (linear->angle, property_id, context);
copy->angle = _gtk_css_value_compute (linear->angle, property_id, context, NULL);
g_array_set_size (copy->stops, linear->stops->len);
for (i = 0; i < linear->stops->len; i++)
@ -430,10 +430,10 @@ gtk_css_image_linear_compute (GtkCssImage *image,
stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
scopy = &g_array_index (copy->stops, GtkCssImageLinearColorStop, i);
scopy->color = _gtk_css_value_compute (stop->color, property_id, context);
scopy->color = _gtk_css_value_compute (stop->color, property_id, context, NULL);
if (stop->offset)
scopy->offset = _gtk_css_value_compute (stop->offset, property_id, context);
scopy->offset = _gtk_css_value_compute (stop->offset, property_id, context, NULL);
else
scopy->offset = NULL;
}

View File

@ -34,9 +34,10 @@ gtk_css_value_image_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_image_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_image_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssImage *image, *computed;
@ -53,6 +54,8 @@ gtk_css_value_image_compute (GtkCssValue *value,
return _gtk_css_value_ref (value);
}
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
return _gtk_css_image_value_new (computed);
}

View File

@ -34,18 +34,22 @@ gtk_css_value_inherit_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_inherit_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_inherit_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkStyleContext *parent = gtk_style_context_get_parent (context);
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
if (parent)
return _gtk_css_value_ref (_gtk_style_context_peek_property (parent, property_id));
else
return _gtk_css_value_compute (_gtk_css_style_property_get_initial_value (_gtk_css_style_property_lookup_by_id (property_id)),
property_id,
context);
context,
NULL);
}
static gboolean

View File

@ -33,13 +33,15 @@ gtk_css_value_initial_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_initial_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_initial_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
return _gtk_css_value_compute (_gtk_css_style_property_get_initial_value (_gtk_css_style_property_lookup_by_id (property_id)),
property_id,
context);
context,
dependencies);
}
static gboolean

View File

@ -35,9 +35,10 @@ gtk_css_value_number_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_number_compute (GtkCssValue *number,
guint property_id,
GtkStyleContext *context)
gtk_css_value_number_compute (GtkCssValue *number,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkBorderStyle border_style;
@ -73,6 +74,8 @@ gtk_css_value_number_compute (GtkCssValue *number,
break;
}
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
switch (number->unit)
{
default:

View File

@ -37,14 +37,15 @@ gtk_css_value_position_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_position_compute (GtkCssValue *position,
guint property_id,
GtkStyleContext *context)
gtk_css_value_position_compute (GtkCssValue *position,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssValue *x, *y;
x = _gtk_css_value_compute (position->x, property_id, context);
y = _gtk_css_value_compute (position->y, property_id, context);
x = _gtk_css_value_compute (position->x, property_id, context, NULL);
y = _gtk_css_value_compute (position->y, property_id, context, NULL);
if (x == position->x && y == position->y)
{
_gtk_css_value_unref (x);
@ -52,6 +53,8 @@ gtk_css_value_position_compute (GtkCssValue *position,
return _gtk_css_value_ref (position);
}
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
return _gtk_css_position_value_new (x, y);
}

View File

@ -34,9 +34,10 @@ gtk_css_value_repeat_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_repeat_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_repeat_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
return _gtk_css_value_ref (value);
}

View File

@ -35,9 +35,10 @@ gtk_css_value_rgba_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_rgba_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_rgba_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
return _gtk_css_value_ref (value);
}

View File

@ -48,9 +48,10 @@ gtk_css_value_shadows_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_shadows_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_shadows_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssValue *result;
guint i;
@ -58,10 +59,12 @@ gtk_css_value_shadows_compute (GtkCssValue *value,
if (value->len == 0)
return _gtk_css_value_ref (value);
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
result = gtk_css_shadows_value_new (value->values, value->len);
for (i = 0; i < value->len; i++)
{
result->values[i] = _gtk_css_value_compute (value->values[i], property_id, context);
result->values[i] = _gtk_css_value_compute (value->values[i], property_id, context, NULL);
}
return result;

View File

@ -60,16 +60,19 @@ gtk_css_value_shadow_free (GtkCssValue *shadow)
}
static GtkCssValue *
gtk_css_value_shadow_compute (GtkCssValue *shadow,
guint property_id,
GtkStyleContext *context)
gtk_css_value_shadow_compute (GtkCssValue *shadow,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
return gtk_css_shadow_value_new (_gtk_css_value_compute (shadow->hoffset, property_id, context),
_gtk_css_value_compute (shadow->voffset, property_id, context),
_gtk_css_value_compute (shadow->radius, property_id, context),
_gtk_css_value_compute (shadow->spread, property_id, context),
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
return gtk_css_shadow_value_new (_gtk_css_value_compute (shadow->hoffset, property_id, context, NULL),
_gtk_css_value_compute (shadow->voffset, property_id, context, NULL),
_gtk_css_value_compute (shadow->radius, property_id, context, NULL),
_gtk_css_value_compute (shadow->spread, property_id, context, NULL),
shadow->inset,
_gtk_css_value_compute (shadow->color, property_id, context));
_gtk_css_value_compute (shadow->color, property_id, context, NULL));
}
static gboolean

View File

@ -33,9 +33,10 @@ gtk_css_value_string_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_string_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_string_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
return _gtk_css_value_ref (value);
}

View File

@ -35,12 +35,15 @@ gtk_css_value_typed_free (GtkCssValue *value)
}
static GtkCssValue *
gtk_css_value_typed_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_typed_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssCustomProperty *custom = GTK_CSS_CUSTOM_PROPERTY (_gtk_css_style_property_lookup_by_id (property_id));
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
return _gtk_css_style_compute_value (context, custom->pspec->value_type, value);
}

View File

@ -56,6 +56,16 @@ typedef enum { /*< skip >*/
GTK_CSS_CHANGE_PARENT_POSITION | GTK_CSS_CHANGE_PARENT_SIBLING_POSITION | \
GTK_CSS_CHANGE_PARENT_STATE | GTK_CSS_CHANGE_PARENT_SIBLING_STATE)
typedef enum /*< skip >*/ {
GTK_CSS_DEPENDS_ON_PARENT = (1 << 0),
GTK_CSS_EQUALS_PARENT = (1 << 1),
GTK_CSS_DEPENDS_ON_COLOR = (1 << 2),
GTK_CSS_DEPENDS_ON_FONT_SIZE = (1 << 3)
} GtkCssDependencies;
#define GTK_CSS_DEPENDS_ON_EVERYTHING (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT \
| GTK_CSS_DEPENDS_ON_COLOR | GTK_CSS_DEPENDS_ON_FONT_SIZE)
enum { /*< skip >*/
GTK_CSS_PROPERTY_COLOR,
GTK_CSS_PROPERTY_FONT_SIZE,

View File

@ -66,6 +66,9 @@ _gtk_css_value_unref (GtkCssValue *value)
* @value: the value to compute from
* @property_id: the ID of the property to compute
* @context: the context to use for resolving
* @dependencies: (out) (allow-none): Set to the dependencies of the
* computed values that indicate when this value needs to be
* recomputed and how.
*
* Converts the specified @value into the computed value for the CSS
* property given by @property_id using the information in @context.
@ -73,17 +76,24 @@ _gtk_css_value_unref (GtkCssValue *value)
* <ulink url="http://www.w3.org/TR/css3-cascade/#computed>
* the CSS documentation</ulink>.
*
* Returns: the comptued value
* Returns: the computed value
**/
GtkCssValue *
_gtk_css_value_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
_gtk_css_value_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssDependencies fallback;
g_return_val_if_fail (value != NULL, NULL);
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
return value->class->compute (value, property_id, context);
if (dependencies == NULL)
dependencies = &fallback;
*dependencies = 0;
return value->class->compute (value, property_id, context, dependencies);
}
gboolean

View File

@ -44,7 +44,8 @@ struct _GtkCssValueClass {
GtkCssValue * (* compute) (GtkCssValue *value,
guint property_id,
GtkStyleContext *context);
GtkStyleContext *context,
GtkCssDependencies *dependencies);
gboolean (* equal) (const GtkCssValue *value1,
const GtkCssValue *value2);
GtkCssValue * (* transition) (GtkCssValue *start,
@ -65,7 +66,8 @@ void _gtk_css_value_unref (GtkCssValue
GtkCssValue *_gtk_css_value_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context);
GtkStyleContext *context,
GtkCssDependencies *dependencies);
gboolean _gtk_css_value_equal (const GtkCssValue *value1,
const GtkCssValue *value2);
gboolean _gtk_css_value_equal0 (const GtkCssValue *value1,

View File

@ -142,7 +142,8 @@ gtk_css_value_symbolic_get_fallback (guint property_id,
case GTK_CSS_PROPERTY_OUTLINE_COLOR:
return _gtk_css_value_compute (_gtk_css_style_property_get_initial_value (_gtk_css_style_property_lookup_by_id (property_id)),
property_id,
context);
context,
NULL);
default:
if (property_id < GTK_CSS_PROPERTY_N_PROPERTIES)
g_warning ("No fallback color defined for property '%s'",
@ -152,12 +153,15 @@ gtk_css_value_symbolic_get_fallback (guint property_id,
}
static GtkCssValue *
gtk_css_value_symbolic_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context)
gtk_css_value_symbolic_compute (GtkCssValue *value,
guint property_id,
GtkStyleContext *context,
GtkCssDependencies *dependencies)
{
GtkCssValue *resolved, *current;
*dependencies = GTK_CSS_DEPENDS_ON_EVERYTHING;
/* The computed value of the currentColor keyword is the computed
* value of the color property. If the currentColor keyword is
* set on the color property itself, it is treated as color: inherit.