diff --git a/gtk/gtkcssanimatedstyle.c b/gtk/gtkcssanimatedstyle.c index 8cce441e0b..1bfc52b4a6 100644 --- a/gtk/gtkcssanimatedstyle.c +++ b/gtk/gtkcssanimatedstyle.c @@ -42,10 +42,37 @@ G_DEFINE_TYPE (GtkCssAnimatedStyle, gtk_css_animated_style, GTK_TYPE_CSS_STYLE) +static inline gboolean +property_has_color (guint id) +{ + switch (id) + { + case GTK_CSS_PROPERTY_COLOR: + case GTK_CSS_PROPERTY_ICON_PALETTE: + case GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR: + case GTK_CSS_PROPERTY_TEXT_SHADOW: + case GTK_CSS_PROPERTY_BOX_SHADOW: + case GTK_CSS_PROPERTY_BORDER_TOP_COLOR: + case GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR: + case GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR: + case GTK_CSS_PROPERTY_BORDER_LEFT_COLOR: + case GTK_CSS_PROPERTY_OUTLINE_COLOR: + case GTK_CSS_PROPERTY_BACKGROUND_IMAGE: + case GTK_CSS_PROPERTY_ICON_SOURCE: + case GTK_CSS_PROPERTY_ICON_SHADOW: + case GTK_CSS_PROPERTY_CARET_COLOR: + case GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR: + return TRUE; + default: + return FALSE; + } +} + #define DEFINE_VALUES(ENUM, TYPE, NAME) \ static inline void \ -gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ - GtkCssComputeContext *context) \ +gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ + GtkCssComputeContext *context, \ + GtkCssAnimationChange change) \ { \ GtkCssStyle *style = (GtkCssStyle *)animated; \ GtkCssValue **values = (GtkCssValue **)((guint8*)(animated->style->NAME) + sizeof (GtkCssValues)); \ @@ -55,6 +82,7 @@ gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ { \ guint id = NAME ## _props[i]; \ GtkCssValue *original, *computed; \ + gboolean needs_recompute = FALSE; \ \ if (values[i] == NULL) \ continue; \ @@ -62,6 +90,17 @@ gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ original = gtk_css_style_get_original_value (style, id); \ if (original == NULL) \ continue; \ +\ + if ((change & GTK_CSS_ANIMATION_CHANGE_VARIABLES) && \ + gtk_css_value_contains_variables (original)) \ + needs_recompute = TRUE; \ +\ + if ((change & GTK_CSS_ANIMATION_CHANGE_COLOR) && \ + property_has_color (id)) \ + needs_recompute = TRUE; \ +\ + if (!needs_recompute) \ + continue; \ \ computed = gtk_css_value_compute (original, \ id, \ @@ -70,6 +109,9 @@ gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ continue; \ \ gtk_css_animated_style_set_animated_value (animated, id, computed); \ +\ + if (id == GTK_CSS_PROPERTY_COLOR) \ + change |= GTK_CSS_ANIMATION_CHANGE_COLOR; \ } \ } @@ -609,7 +651,6 @@ gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated, GtkCssVariableValue *value) { GtkCssStyle *style = (GtkCssStyle *)animated; - GtkCssComputeContext context = { NULL, }; gtk_internal_return_if_fail (GTK_IS_CSS_ANIMATED_STYLE (style)); gtk_internal_return_if_fail (value != NULL); @@ -628,22 +669,37 @@ gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated, } gtk_css_variable_set_add (style->variables, id, value); +} - context.style = animated->style; - context.parent_style = animated->parent_style; - context.provider = animated->provider; +void +gtk_css_animated_style_recompute (GtkCssAnimatedStyle *style, + GtkCssAnimationChange change) +{ + GtkCssComputeContext context = { NULL, }; + GtkCssValue *shorthands[GTK_CSS_SHORTHAND_PROPERTY_N_PROPERTIES] = { NULL, }; - gtk_css_core_values_recompute (animated, &context); - gtk_css_background_values_recompute (animated, &context); - gtk_css_border_values_recompute (animated, &context); - gtk_css_icon_values_recompute (animated, &context); - gtk_css_outline_values_recompute (animated, &context); - gtk_css_font_values_recompute (animated, &context); - gtk_css_font_variant_values_recompute (animated, &context); - gtk_css_animation_values_recompute (animated, &context); - gtk_css_transition_values_recompute (animated, &context); - gtk_css_size_values_recompute (animated, &context); - gtk_css_other_values_recompute (animated, &context); + context.provider = style->provider; + context.style = style->style; + context.parent_style = style->parent_style; + context.shorthands = shorthands; + + gtk_css_core_values_recompute (style, &context, change); + gtk_css_background_values_recompute (style, &context, change); + gtk_css_border_values_recompute (style, &context, change); + gtk_css_icon_values_recompute (style, &context, change); + gtk_css_outline_values_recompute (style, &context, change); + gtk_css_font_values_recompute (style, &context, change); + gtk_css_font_variant_values_recompute (style, &context, change); + gtk_css_animation_values_recompute (style, &context, change); + gtk_css_transition_values_recompute (style, &context, change); + gtk_css_size_values_recompute (style, &context, change); + gtk_css_other_values_recompute (style, &context, change); + + for (unsigned int i = 0; i < GTK_CSS_SHORTHAND_PROPERTY_N_PROPERTIES; i++) + { + if (shorthands[i]) + gtk_css_value_unref (shorthands[i]); + } } GtkCssVariableValue * diff --git a/gtk/gtkcssanimatedstyleprivate.h b/gtk/gtkcssanimatedstyleprivate.h index d8eab1e458..ada5ad75f8 100644 --- a/gtk/gtkcssanimatedstyleprivate.h +++ b/gtk/gtkcssanimatedstyleprivate.h @@ -73,6 +73,14 @@ GtkCssValue * gtk_css_animated_style_get_intrinsic_value (GtkCssAnimat void gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated, int id, GtkCssVariableValue *value); + +typedef enum { + GTK_CSS_ANIMATION_CHANGE_VARIABLES = 1 << 0, + GTK_CSS_ANIMATION_CHANGE_COLOR = 1 << 1, +} GtkCssAnimationChange; + +void gtk_css_animated_style_recompute (GtkCssAnimatedStyle *style, + GtkCssAnimationChange change); GtkCssVariableValue * gtk_css_animated_style_get_intrinsic_custom_value (GtkCssAnimatedStyle *style, int id); diff --git a/gtk/gtkcssanimation.c b/gtk/gtkcssanimation.c index a380b704c1..d920d4d71a 100644 --- a/gtk/gtkcssanimation.c +++ b/gtk/gtkcssanimation.c @@ -95,6 +95,7 @@ gtk_css_animation_apply_values (GtkStyleAnimation *style_animation, GtkCssKeyframes *resolved_keyframes; double progress; guint i; + GtkCssAnimationChange change = 0; if (!gtk_css_animation_is_executing (animation)) return; @@ -128,13 +129,15 @@ gtk_css_animation_apply_values (GtkStyleAnimation *style_animation, gtk_css_animated_style_set_animated_custom_value (style, variable_id, value); gtk_css_variable_value_unref (value); + + change |= GTK_CSS_ANIMATION_CHANGE_VARIABLES; } for (i = 0; i < _gtk_css_keyframes_get_n_properties (resolved_keyframes); i++) { GtkCssValue *value; guint property_id; - + property_id = _gtk_css_keyframes_get_property_id (resolved_keyframes, i); value = _gtk_css_keyframes_get_value (resolved_keyframes, @@ -142,8 +145,14 @@ gtk_css_animation_apply_values (GtkStyleAnimation *style_animation, progress, gtk_css_animated_style_get_intrinsic_value (style, property_id)); gtk_css_animated_style_set_animated_value (style, property_id, value); + + if (property_id == GTK_CSS_PROPERTY_COLOR) + change |= GTK_CSS_ANIMATION_CHANGE_COLOR; } + if (change != 0) + gtk_css_animated_style_recompute (style, change); + _gtk_css_keyframes_unref (resolved_keyframes); }