diff --git a/gtk/gtkanimationdescription.c b/gtk/gtkanimationdescription.c index a0cc3be533..cef6ade0c8 100644 --- a/gtk/gtkanimationdescription.c +++ b/gtk/gtkanimationdescription.c @@ -25,19 +25,21 @@ struct GtkAnimationDescription { GtkTimelineProgressType progress_type; gdouble duration; - + guint loop : 1; guint ref_count; }; GtkAnimationDescription * gtk_animation_description_new (gdouble duration, - GtkTimelineProgressType progress_type) + GtkTimelineProgressType progress_type, + gboolean loop) { GtkAnimationDescription *desc; desc = g_slice_new (GtkAnimationDescription); desc->duration = duration; desc->progress_type = progress_type; + desc->loop = loop; desc->ref_count = 1; return desc; @@ -55,6 +57,12 @@ gtk_animation_description_get_progress_type (GtkAnimationDescription *desc) return desc->progress_type; } +gboolean +gtk_animation_description_get_loop (GtkAnimationDescription *desc) +{ + return (desc->loop != 0); +} + GtkAnimationDescription * gtk_animation_description_ref (GtkAnimationDescription *desc) { @@ -75,18 +83,23 @@ GtkAnimationDescription * gtk_animation_description_from_string (const gchar *str) { gchar timing_function[16] = { 0, }; - gchar duration_measurement[3] = { 0, }; + gchar duration_unit[3] = { 0, }; GtkTimelineProgressType progress_type; guint duration = 0; + gboolean loop; - if (sscanf (str, "%d%2s %15s", &duration, duration_measurement, timing_function) != 3) + if (sscanf (str, "%d%2s %15s loop", &duration, duration_unit, timing_function) == 3) + loop = TRUE; + else if (sscanf (str, "%d%2s %15s", &duration, duration_unit, timing_function) == 3) + loop = FALSE; + else return NULL; - if (strcmp (duration_measurement, "s") == 0) + if (strcmp (duration_unit, "s") == 0) duration *= 1000; - else if (strcmp (duration_measurement, "ms") != 0) + else if (strcmp (duration_unit, "ms") != 0) { - g_warning ("Unknown duration measurement: %s\n", duration_measurement); + g_warning ("Unknown duration unit: %s\n", duration_unit); return NULL; } @@ -106,7 +119,7 @@ gtk_animation_description_from_string (const gchar *str) return NULL; } - return gtk_animation_description_new ((gdouble) duration, progress_type); + return gtk_animation_description_new ((gdouble) duration, progress_type, loop); } GType diff --git a/gtk/gtkanimationdescription.h b/gtk/gtkanimationdescription.h index 7770df2f02..34fc8fcb95 100644 --- a/gtk/gtkanimationdescription.h +++ b/gtk/gtkanimationdescription.h @@ -32,10 +32,12 @@ typedef struct GtkAnimationDescription GtkAnimationDescription; GType gtk_animation_description_get_type (void) G_GNUC_CONST; GtkAnimationDescription * gtk_animation_description_new (gdouble duration, - GtkTimelineProgressType progress_type); + GtkTimelineProgressType progress_type, + gboolean loop); gdouble gtk_animation_description_get_duration (GtkAnimationDescription *desc); GtkTimelineProgressType gtk_animation_description_get_progress_type (GtkAnimationDescription *desc); +gboolean gtk_animation_description_get_loop (GtkAnimationDescription *desc); GtkAnimationDescription * gtk_animation_description_ref (GtkAnimationDescription *desc); void gtk_animation_description_unref (GtkAnimationDescription *desc); diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c index 2d1b0f09ab..06c866f1b3 100644 --- a/gtk/gtkcssprovider.c +++ b/gtk/gtkcssprovider.c @@ -364,12 +364,12 @@ * * * transition - * duration [s|ms] [linear|ease|ease-in|ease-out|ease-in-out] + * duration [s|ms] [linear|ease|ease-in|ease-out|ease-in-out] [loop]? * * * * transition: 150ms ease-in-out; - * transition: 1s linear; + * transition: 1s linear loop; * * * diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index 8023f9b99d..2fcabd24ac 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -584,6 +584,7 @@ animation_info_new (GtkStyleContext *context, gpointer region_id, gdouble duration, GtkTimelineProgressType progress_type, + gboolean loop, GtkStateType state, gboolean target_value, GdkWindow *window) @@ -600,8 +601,9 @@ animation_info_new (GtkStyleContext *context, info->region_id = region_id; gtk_timeline_set_progress_type (info->timeline, progress_type); + gtk_timeline_set_loop (info->timeline, loop); - if (!target_value) + if (!loop && !target_value) { gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD); gtk_timeline_rewind (info->timeline); @@ -2551,11 +2553,13 @@ gtk_style_context_notify_state_change (GtkStyleContext *context, info = animation_info_lookup (context, region_id, state); - if (info) + if (info && + info->target_value != state_value) { - /* Reverse the animation if target values are the opposite */ - if (info->target_value != state_value) + /* Target values are the opposite */ + if (!gtk_timeline_get_loop (info->timeline)) { + /* Reverse the animation */ if (gtk_timeline_get_direction (info->timeline) == GTK_TIMELINE_DIRECTION_FORWARD) gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD); else @@ -2563,12 +2567,18 @@ gtk_style_context_notify_state_change (GtkStyleContext *context, info->target_value = state_value; } + else + { + /* Take it out of its looping state */ + gtk_timeline_set_loop (info->timeline, FALSE); + } } - else + else if (!info) { info = animation_info_new (context, region_id, gtk_animation_description_get_duration (desc), gtk_animation_description_get_progress_type (desc), + gtk_animation_description_get_loop (desc), state, state_value, window); priv->animations = g_slist_prepend (priv->animations, info); diff --git a/gtk/gtkstyleproperties.c b/gtk/gtkstyleproperties.c index d1d339ca48..d5cc2b73d9 100644 --- a/gtk/gtkstyleproperties.c +++ b/gtk/gtkstyleproperties.c @@ -102,10 +102,7 @@ gtk_style_properties_class_init (GtkStylePropertiesClass *klass) gtk_style_properties_register_property ("engine", GTK_TYPE_THEMING_ENGINE, &val, NULL); g_value_unset (&val); - g_value_init (&val, GTK_TYPE_ANIMATION_DESCRIPTION); - g_value_take_boxed (&val, gtk_animation_description_new (0, GTK_TIMELINE_PROGRESS_LINEAR)); - gtk_style_properties_register_property ("transition", GTK_TYPE_ANIMATION_DESCRIPTION, &val, NULL); - g_value_unset (&val); + gtk_style_properties_register_property ("transition", GTK_TYPE_ANIMATION_DESCRIPTION, NULL, NULL); g_type_class_add_private (object_class, sizeof (GtkStylePropertiesPrivate)); }