stylecontext: Refactor update_properties()

It now always returns a new instance.
This commit is contained in:
Benjamin Otte
2014-12-17 04:18:44 +01:00
parent 7406ec84bc
commit b7be202089
5 changed files with 108 additions and 40 deletions

View File

@ -445,12 +445,14 @@ gtk_css_animated_style_new (GtkCssStyle *base_style,
GtkCssStyle * GtkCssStyle *
gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source, gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source,
GtkCssStyle *base,
gint64 timestamp) gint64 timestamp)
{ {
GtkCssAnimatedStyle *result; GtkCssAnimatedStyle *result;
GSList *l, *animations; GSList *l, *animations;
gtk_internal_return_val_if_fail (GTK_IS_CSS_ANIMATED_STYLE (source), NULL); gtk_internal_return_val_if_fail (GTK_IS_CSS_ANIMATED_STYLE (source), NULL);
gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (base), NULL);
animations = NULL; animations = NULL;
for (l = source->animations; l; l = l->next) for (l = source->animations; l; l = l->next)
@ -469,7 +471,7 @@ gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source,
result = g_object_new (GTK_TYPE_CSS_ANIMATED_STYLE, NULL); result = g_object_new (GTK_TYPE_CSS_ANIMATED_STYLE, NULL);
result->style = g_object_ref (source->style); result->style = g_object_ref (base);
result->current_time = timestamp; result->current_time = timestamp;
result->animations = animations; result->animations = animations;

View File

@ -59,6 +59,7 @@ GtkCssStyle * gtk_css_animated_style_new (GtkCssStyle
int scale, int scale,
GtkCssStyle *previous_style); GtkCssStyle *previous_style);
GtkCssStyle * gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source, GtkCssStyle * gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source,
GtkCssStyle *base,
gint64 timestamp); gint64 timestamp);
void gtk_css_animated_style_set_animated_value(GtkCssAnimatedStyle *style, void gtk_css_animated_style_set_animated_value(GtkCssAnimatedStyle *style,

View File

@ -137,17 +137,81 @@ gtk_css_static_style_init (GtkCssStaticStyle *style)
style->depends_on_font_size = _gtk_bitmask_new (); style->depends_on_font_size = _gtk_bitmask_new ();
} }
static void
maybe_unref_section (gpointer section)
{
if (section)
gtk_css_section_unref (section);
}
static void
gtk_css_static_style_set_value (GtkCssStaticStyle *style,
guint id,
GtkCssValue *value,
GtkCssSection *section)
{
if (style->values == NULL)
style->values = g_ptr_array_new_with_free_func ((GDestroyNotify)_gtk_css_value_unref);
if (id >= style->values->len)
g_ptr_array_set_size (style->values, id + 1);
if (g_ptr_array_index (style->values, id))
_gtk_css_value_unref (g_ptr_array_index (style->values, id));
g_ptr_array_index (style->values, id) = _gtk_css_value_ref (value);
if (style->sections && style->sections->len > id && g_ptr_array_index (style->sections, id))
{
gtk_css_section_unref (g_ptr_array_index (style->sections, id));
g_ptr_array_index (style->sections, id) = NULL;
}
if (section)
{
if (style->sections == NULL)
style->sections = g_ptr_array_new_with_free_func (maybe_unref_section);
if (style->sections->len <= id)
g_ptr_array_set_size (style->sections, id + 1);
g_ptr_array_index (style->sections, id) = gtk_css_section_ref (section);
}
}
GtkCssStyle * GtkCssStyle *
gtk_css_static_style_new (void) gtk_css_static_style_new (void)
{ {
return g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL); return g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL);
} }
static void GtkCssStyle *
maybe_unref_section (gpointer section) gtk_css_static_style_copy (GtkCssStaticStyle *original,
const GtkBitmask *properties_to_not_copy)
{ {
if (section) GtkCssStaticStyle *copy;
gtk_css_section_unref (section); guint i;
copy = g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL);
copy->depends_on_parent = _gtk_bitmask_subtract (_gtk_bitmask_union (copy->depends_on_parent, original->depends_on_parent),
properties_to_not_copy);
copy->equals_parent = _gtk_bitmask_subtract (_gtk_bitmask_union (copy->equals_parent, original->equals_parent),
properties_to_not_copy);
copy->depends_on_color = _gtk_bitmask_subtract (_gtk_bitmask_union (copy->depends_on_color, original->depends_on_color),
properties_to_not_copy);
copy->depends_on_font_size = _gtk_bitmask_subtract (_gtk_bitmask_union (copy->depends_on_font_size, original->depends_on_font_size),
properties_to_not_copy);
for (i = 0; i < original->values->len; i++)
{
if (_gtk_bitmask_get (properties_to_not_copy, i))
continue;
gtk_css_static_style_set_value (copy,
i,
gtk_css_static_style_get_value (GTK_CSS_STYLE (original), i),
gtk_css_static_style_get_section (GTK_CSS_STYLE (original), i));
}
return GTK_CSS_STYLE (copy);
} }
void void
@ -185,14 +249,7 @@ gtk_css_static_style_compute_value (GtkCssStaticStyle *style,
value = _gtk_css_value_compute (specified, id, provider, scale, GTK_CSS_STYLE (style), parent_style, &dependencies); value = _gtk_css_value_compute (specified, id, provider, scale, GTK_CSS_STYLE (style), parent_style, &dependencies);
if (style->values == NULL) gtk_css_static_style_set_value (style, id, value, section);
style->values = g_ptr_array_new_with_free_func ((GDestroyNotify)_gtk_css_value_unref);
if (id >= style->values->len)
g_ptr_array_set_size (style->values, id + 1);
if (g_ptr_array_index (style->values, id))
_gtk_css_value_unref (g_ptr_array_index (style->values, id));
g_ptr_array_index (style->values, id) = _gtk_css_value_ref (value);
if (dependencies & (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT)) if (dependencies & (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT))
style->depends_on_parent = _gtk_bitmask_set (style->depends_on_parent, id, TRUE); style->depends_on_parent = _gtk_bitmask_set (style->depends_on_parent, id, TRUE);
@ -203,22 +260,6 @@ gtk_css_static_style_compute_value (GtkCssStaticStyle *style,
if (dependencies & (GTK_CSS_DEPENDS_ON_FONT_SIZE)) if (dependencies & (GTK_CSS_DEPENDS_ON_FONT_SIZE))
style->depends_on_font_size = _gtk_bitmask_set (style->depends_on_font_size, id, TRUE); style->depends_on_font_size = _gtk_bitmask_set (style->depends_on_font_size, id, TRUE);
if (style->sections && style->sections->len > id && g_ptr_array_index (style->sections, id))
{
gtk_css_section_unref (g_ptr_array_index (style->sections, id));
g_ptr_array_index (style->sections, id) = NULL;
}
if (section)
{
if (style->sections == NULL)
style->sections = g_ptr_array_new_with_free_func (maybe_unref_section);
if (style->sections->len <= id)
g_ptr_array_set_size (style->sections, id + 1);
g_ptr_array_index (style->sections, id) = gtk_css_section_ref (section);
}
_gtk_css_value_unref (value); _gtk_css_value_unref (value);
_gtk_css_value_unref (specified); _gtk_css_value_unref (specified);
} }

View File

@ -55,6 +55,8 @@ struct _GtkCssStaticStyleClass
GType gtk_css_static_style_get_type (void) G_GNUC_CONST; GType gtk_css_static_style_get_type (void) G_GNUC_CONST;
GtkCssStyle * gtk_css_static_style_new (void); GtkCssStyle * gtk_css_static_style_new (void);
GtkCssStyle * gtk_css_static_style_copy (GtkCssStaticStyle *original,
const GtkBitmask *properties_to_not_copy);
void gtk_css_static_style_compute_value (GtkCssStaticStyle *style, void gtk_css_static_style_compute_value (GtkCssStaticStyle *style,
GtkStyleProviderPrivate*provider, GtkStyleProviderPrivate*provider,

View File

@ -681,7 +681,7 @@ create_query_path (GtkStyleContext *context,
return path; return path;
} }
static void static GtkCssStyle *
update_properties (GtkStyleContext *context, update_properties (GtkStyleContext *context,
GtkCssStyle *style, GtkCssStyle *style,
const GtkCssNodeDeclaration *decl, const GtkCssNodeDeclaration *decl,
@ -692,6 +692,7 @@ update_properties (GtkStyleContext *context,
GtkWidgetPath *path; GtkWidgetPath *path;
GtkCssLookup *lookup; GtkCssLookup *lookup;
GtkBitmask *changes; GtkBitmask *changes;
GtkCssStyle *result;
priv = context->priv; priv = context->priv;
@ -699,9 +700,10 @@ update_properties (GtkStyleContext *context,
if (_gtk_bitmask_is_empty (changes)) if (_gtk_bitmask_is_empty (changes))
{ {
_gtk_bitmask_free (changes); _gtk_bitmask_free (changes);
return; return g_object_ref (style);
} }
result = gtk_css_static_style_copy (GTK_CSS_STATIC_STYLE (style), changes);
path = create_query_path (context, decl); path = create_query_path (context, decl);
lookup = _gtk_css_lookup_new (changes); lookup = _gtk_css_lookup_new (changes);
@ -714,12 +716,14 @@ update_properties (GtkStyleContext *context,
_gtk_css_lookup_resolve (lookup, _gtk_css_lookup_resolve (lookup,
GTK_STYLE_PROVIDER_PRIVATE (priv->cascade), GTK_STYLE_PROVIDER_PRIVATE (priv->cascade),
priv->scale, priv->scale,
GTK_CSS_STATIC_STYLE (style), GTK_CSS_STATIC_STYLE (result),
priv->parent ? style_values_lookup (priv->parent) : NULL); priv->parent ? style_values_lookup (priv->parent) : NULL);
_gtk_css_lookup_free (lookup); _gtk_css_lookup_free (lookup);
gtk_widget_path_free (path); gtk_widget_path_free (path);
_gtk_bitmask_free (changes); _gtk_bitmask_free (changes);
return result;
} }
static GtkCssStyle * static GtkCssStyle *
@ -2694,7 +2698,9 @@ gtk_style_context_update_cache (GtkStyleContext *context,
const GtkCssNodeDeclaration *decl = key; const GtkCssNodeDeclaration *decl = key;
GtkCssStyle *values = value; GtkCssStyle *values = value;
update_properties (context, values, decl, parent_changes); values = update_properties (context, values, decl, parent_changes);
g_hash_table_iter_replace (&iter, values);
} }
gtk_style_context_clear_property_cache (context); gtk_style_context_clear_property_cache (context);
@ -2843,18 +2849,34 @@ _gtk_style_context_validate (GtkStyleContext *context,
if (!_gtk_bitmask_is_empty (parent_changes)) if (!_gtk_bitmask_is_empty (parent_changes))
{ {
GtkCssStyle *new_values;
if (GTK_IS_CSS_ANIMATED_STYLE (current)) if (GTK_IS_CSS_ANIMATED_STYLE (current))
update_properties (context, GTK_CSS_ANIMATED_STYLE (current)->style, info->decl, parent_changes); {
GtkCssStyle *new_base;
new_base = update_properties (context, GTK_CSS_ANIMATED_STYLE (current)->style, info->decl, parent_changes);
new_values = gtk_css_animated_style_new_advance (GTK_CSS_ANIMATED_STYLE (current),
new_base,
timestamp);
g_object_unref (new_base);
}
else else
update_properties (context, current, info->decl, parent_changes); {
new_values = update_properties (context, current, info->decl, parent_changes);
} }
if (change & GTK_CSS_CHANGE_ANIMATE && style_info_set_values (info, new_values);
g_object_unref (new_values);
}
else if (change & GTK_CSS_CHANGE_ANIMATE &&
gtk_style_context_is_animating (context)) gtk_style_context_is_animating (context))
{ {
GtkCssStyle *new_values; GtkCssStyle *new_values;
new_values = gtk_css_animated_style_new_advance (GTK_CSS_ANIMATED_STYLE (info->values), timestamp); new_values = gtk_css_animated_style_new_advance (GTK_CSS_ANIMATED_STYLE (info->values),
GTK_CSS_ANIMATED_STYLE (info->values)->style,
timestamp);
style_info_set_values (info, new_values); style_info_set_values (info, new_values);
g_object_unref (new_values); g_object_unref (new_values);