[gtk+/gtk-style-context] Handle looping transition animations.



commit d6edcac9eb69bfed518dbaa63b040de8223b040a
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Nov 13 13:24:18 2010 +0100

    Handle looping transition animations.

 gtk/gtkanimationdescription.c |   29 +++++++++++++++++++++--------
 gtk/gtkanimationdescription.h |    4 +++-
 gtk/gtkcssprovider.c          |    4 ++--
 gtk/gtkstylecontext.c         |   20 +++++++++++++++-----
 gtk/gtkstyleproperties.c      |    5 +----
 5 files changed, 42 insertions(+), 20 deletions(-)
---
diff --git a/gtk/gtkanimationdescription.c b/gtk/gtkanimationdescription.c
index a0cc3be..cef6ade 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 7770df2..34fc8fc 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 2204cc0..fb608f0 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -364,12 +364,12 @@
  *       </row>
  *       <row>
  *         <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>
  *           <programlisting>
  * transition: 150ms ease-in-out;
- * transition: 1s linear;</programlisting>
+ * transition: 1s linear loop;</programlisting>
  *         </entry>
  *       </row>
  *     </tbody>
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 8023f9b..2fcabd2 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 d1d339c..d5cc2b7 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));
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]