Commit bcf81a0e authored by Carlos Garnacho's avatar Carlos Garnacho

Handle looping transition animations.

parent 1123159d
...@@ -25,19 +25,21 @@ struct GtkAnimationDescription ...@@ -25,19 +25,21 @@ struct GtkAnimationDescription
{ {
GtkTimelineProgressType progress_type; GtkTimelineProgressType progress_type;
gdouble duration; gdouble duration;
guint loop : 1;
guint ref_count; guint ref_count;
}; };
GtkAnimationDescription * GtkAnimationDescription *
gtk_animation_description_new (gdouble duration, gtk_animation_description_new (gdouble duration,
GtkTimelineProgressType progress_type) GtkTimelineProgressType progress_type,
gboolean loop)
{ {
GtkAnimationDescription *desc; GtkAnimationDescription *desc;
desc = g_slice_new (GtkAnimationDescription); desc = g_slice_new (GtkAnimationDescription);
desc->duration = duration; desc->duration = duration;
desc->progress_type = progress_type; desc->progress_type = progress_type;
desc->loop = loop;
desc->ref_count = 1; desc->ref_count = 1;
return desc; return desc;
...@@ -55,6 +57,12 @@ gtk_animation_description_get_progress_type (GtkAnimationDescription *desc) ...@@ -55,6 +57,12 @@ gtk_animation_description_get_progress_type (GtkAnimationDescription *desc)
return desc->progress_type; return desc->progress_type;
} }
gboolean
gtk_animation_description_get_loop (GtkAnimationDescription *desc)
{
return (desc->loop != 0);
}
GtkAnimationDescription * GtkAnimationDescription *
gtk_animation_description_ref (GtkAnimationDescription *desc) gtk_animation_description_ref (GtkAnimationDescription *desc)
{ {
...@@ -75,18 +83,23 @@ GtkAnimationDescription * ...@@ -75,18 +83,23 @@ GtkAnimationDescription *
gtk_animation_description_from_string (const gchar *str) gtk_animation_description_from_string (const gchar *str)
{ {
gchar timing_function[16] = { 0, }; gchar timing_function[16] = { 0, };
gchar duration_measurement[3] = { 0, }; gchar duration_unit[3] = { 0, };
GtkTimelineProgressType progress_type; GtkTimelineProgressType progress_type;
guint duration = 0; 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; return NULL;
if (strcmp (duration_measurement, "s") == 0) if (strcmp (duration_unit, "s") == 0)
duration *= 1000; 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; return NULL;
} }
...@@ -106,7 +119,7 @@ gtk_animation_description_from_string (const gchar *str) ...@@ -106,7 +119,7 @@ gtk_animation_description_from_string (const gchar *str)
return NULL; return NULL;
} }
return gtk_animation_description_new ((gdouble) duration, progress_type); return gtk_animation_description_new ((gdouble) duration, progress_type, loop);
} }
GType GType
......
...@@ -32,10 +32,12 @@ typedef struct GtkAnimationDescription GtkAnimationDescription; ...@@ -32,10 +32,12 @@ typedef struct GtkAnimationDescription GtkAnimationDescription;
GType gtk_animation_description_get_type (void) G_GNUC_CONST; GType gtk_animation_description_get_type (void) G_GNUC_CONST;
GtkAnimationDescription * gtk_animation_description_new (gdouble duration, GtkAnimationDescription * gtk_animation_description_new (gdouble duration,
GtkTimelineProgressType progress_type); GtkTimelineProgressType progress_type,
gboolean loop);
gdouble gtk_animation_description_get_duration (GtkAnimationDescription *desc); gdouble gtk_animation_description_get_duration (GtkAnimationDescription *desc);
GtkTimelineProgressType gtk_animation_description_get_progress_type (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); GtkAnimationDescription * gtk_animation_description_ref (GtkAnimationDescription *desc);
void gtk_animation_description_unref (GtkAnimationDescription *desc); void gtk_animation_description_unref (GtkAnimationDescription *desc);
......
...@@ -364,12 +364,12 @@ ...@@ -364,12 +364,12 @@
* </row> * </row>
* <row> * <row>
* <entry>transition</entry> * <entry>transition</entry>
* <entry><programlisting>duration [s|ms] [linear|ease|ease-in|ease-out|ease-in-out]</programlisting></entry> * <entry><programlisting>duration [s|ms] [linear|ease|ease-in|ease-out|ease-in-out] [loop]?</programlisting></entry>
* <entry></entry> * <entry></entry>
* <entry> * <entry>
* <programlisting> * <programlisting>
* transition: 150ms ease-in-out; * transition: 150ms ease-in-out;
* transition: 1s linear;</programlisting> * transition: 1s linear loop;</programlisting>
* </entry> * </entry>
* </row> * </row>
* </tbody> * </tbody>
......
...@@ -584,6 +584,7 @@ animation_info_new (GtkStyleContext *context, ...@@ -584,6 +584,7 @@ animation_info_new (GtkStyleContext *context,
gpointer region_id, gpointer region_id,
gdouble duration, gdouble duration,
GtkTimelineProgressType progress_type, GtkTimelineProgressType progress_type,
gboolean loop,
GtkStateType state, GtkStateType state,
gboolean target_value, gboolean target_value,
GdkWindow *window) GdkWindow *window)
...@@ -600,8 +601,9 @@ animation_info_new (GtkStyleContext *context, ...@@ -600,8 +601,9 @@ animation_info_new (GtkStyleContext *context,
info->region_id = region_id; info->region_id = region_id;
gtk_timeline_set_progress_type (info->timeline, progress_type); 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_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD);
gtk_timeline_rewind (info->timeline); gtk_timeline_rewind (info->timeline);
...@@ -2551,11 +2553,13 @@ gtk_style_context_notify_state_change (GtkStyleContext *context, ...@@ -2551,11 +2553,13 @@ gtk_style_context_notify_state_change (GtkStyleContext *context,
info = animation_info_lookup (context, region_id, state); 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 */ /* Target values are the opposite */
if (info->target_value != state_value) if (!gtk_timeline_get_loop (info->timeline))
{ {
/* Reverse the animation */
if (gtk_timeline_get_direction (info->timeline) == GTK_TIMELINE_DIRECTION_FORWARD) if (gtk_timeline_get_direction (info->timeline) == GTK_TIMELINE_DIRECTION_FORWARD)
gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD); gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD);
else else
...@@ -2563,12 +2567,18 @@ gtk_style_context_notify_state_change (GtkStyleContext *context, ...@@ -2563,12 +2567,18 @@ gtk_style_context_notify_state_change (GtkStyleContext *context,
info->target_value = state_value; 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, info = animation_info_new (context, region_id,
gtk_animation_description_get_duration (desc), gtk_animation_description_get_duration (desc),
gtk_animation_description_get_progress_type (desc), gtk_animation_description_get_progress_type (desc),
gtk_animation_description_get_loop (desc),
state, state_value, window); state, state_value, window);
priv->animations = g_slist_prepend (priv->animations, info); priv->animations = g_slist_prepend (priv->animations, info);
......
...@@ -102,10 +102,7 @@ gtk_style_properties_class_init (GtkStylePropertiesClass *klass) ...@@ -102,10 +102,7 @@ gtk_style_properties_class_init (GtkStylePropertiesClass *klass)
gtk_style_properties_register_property ("engine", GTK_TYPE_THEMING_ENGINE, &val, NULL); gtk_style_properties_register_property ("engine", GTK_TYPE_THEMING_ENGINE, &val, NULL);
g_value_unset (&val); g_value_unset (&val);
g_value_init (&val, GTK_TYPE_ANIMATION_DESCRIPTION); gtk_style_properties_register_property ("transition", GTK_TYPE_ANIMATION_DESCRIPTION, NULL, NULL);
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);
g_type_class_add_private (object_class, sizeof (GtkStylePropertiesPrivate)); g_type_class_add_private (object_class, sizeof (GtkStylePropertiesPrivate));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment