[gtk+/wip/watson/progress-tracker: 5/7] WIP: port css animation and transition to tracker



commit c33c8e127cedc9bfc8fb838badb8b8be608a5a13
Author: Matt Watson <mattdangerw gmail com>
Date:   Sun Mar 6 22:45:27 2016 -0800

    WIP: port css animation and transition to tracker

 gtk/gtkcssanimatedstyle.c       |   10 ++---
 gtk/gtkcssanimation.c           |   74 +++++++++---------------------
 gtk/gtkcssanimationprivate.h    |    5 +-
 gtk/gtkcsstransition.c          |   60 +++++++++++--------------
 gtk/gtkcsstransitionprivate.h   |   14 +++---
 gtk/gtkprogresstracker.c        |   94 +++++++++++++++++++++++++-------------
 gtk/gtkprogresstrackerprivate.h |   37 +++++++++++-----
 gtk/gtkstack.c                  |   46 ++++++++++---------
 gtk/gtkstyleanimation.c         |   16 +++----
 gtk/gtkstyleanimationprivate.h  |   12 ++---
 10 files changed, 184 insertions(+), 184 deletions(-)
---
diff --git a/gtk/gtkcssanimatedstyle.c b/gtk/gtkcssanimatedstyle.c
index 2c92fa7..ae88577 100644
--- a/gtk/gtkcssanimatedstyle.c
+++ b/gtk/gtkcssanimatedstyle.c
@@ -71,7 +71,7 @@ gtk_css_animated_style_is_static (GtkCssStyle *style)
 
   for (list = animated->animations; list; list = list->next)
     {
-      if (!_gtk_style_animation_is_static (list->data, animated->current_time))
+      if (!_gtk_style_animation_is_static (list->data))
         return FALSE;
     }
 
@@ -301,8 +301,8 @@ gtk_css_animated_style_create_css_transitions (GSList              *animations,
       animation = _gtk_css_transition_new (i,
                                            gtk_css_style_get_value (source, i),
                                            _gtk_css_array_value_get_nth (timing_functions, i),
-                                           timestamp + delay * G_USEC_PER_SEC,
-                                           timestamp + (delay + duration) * G_USEC_PER_SEC);
+                                           duration * G_USEC_PER_SEC,
+                                           delay * G_USEC_PER_SEC);
       animations = g_slist_prepend (animations, animation);
     }
 
@@ -368,7 +368,6 @@ gtk_css_animated_style_create_css_animations (GSList                  *animation
       if (animation)
         {
           animation = _gtk_css_animation_copy (GTK_CSS_ANIMATION (animation),
-                                               timestamp,
                                                _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth 
(play_states, i)));
         }
       else
@@ -381,7 +380,6 @@ gtk_css_animated_style_create_css_animations (GSList                  *animation
 
           animation = _gtk_css_animation_new (name,
                                               keyframes,
-                                              timestamp,
                                               _gtk_css_number_value_get (_gtk_css_array_value_get_nth 
(delays, i), 100) * G_USEC_PER_SEC,
                                               _gtk_css_number_value_get (_gtk_css_array_value_get_nth 
(durations, i), 100) * G_USEC_PER_SEC,
                                               _gtk_css_array_value_get_nth (timing_functions, i),
@@ -472,7 +470,7 @@ gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source,
     {
       GtkStyleAnimation *animation = l->data;
       
-      if (_gtk_style_animation_is_finished (animation, timestamp))
+      if (_gtk_style_animation_is_finished (animation))
         continue;
 
       animations = g_slist_prepend (animations, g_object_ref (animation));
diff --git a/gtk/gtkcssanimation.c b/gtk/gtkcssanimation.c
index c1b10c7..49c5998 100644
--- a/gtk/gtkcssanimation.c
+++ b/gtk/gtkcssanimation.c
@@ -22,41 +22,25 @@
 #include "gtkcssanimationprivate.h"
 
 #include "gtkcsseasevalueprivate.h"
+#include "gtkprogresstrackerprivate.h"
 
 #include <math.h>
 
 G_DEFINE_TYPE (GtkCssAnimation, _gtk_css_animation, GTK_TYPE_STYLE_ANIMATION)
 
-/* NB: Return value can be negative (if animation hasn't started yet) */
-static gint64
-gtk_css_animation_get_elapsed (GtkCssAnimation *animation,
-                               gint64           for_time_us)
-{
-  if (animation->play_state == GTK_CSS_PLAY_STATE_PAUSED)
-    return animation->timestamp;
-  else
-    return for_time_us - animation->timestamp;
-}
-/* NB: Return value can be negative and +-Inf */
-static double
-gtk_css_animation_get_iteration (GtkCssAnimation *animation,
-                                 gint64           for_time_us)
-{
-  return (double) gtk_css_animation_get_elapsed (animation, for_time_us) / animation->duration;
-}
-
 static gboolean
-gtk_css_animation_is_executing_at_iteration (GtkCssAnimation *animation,
-                                             double           iteration)
+gtk_css_animation_is_executing (GtkCssAnimation *animation)
 {
+  GtkProgressState state = gtk_progress_tracker_get_state (&animation->tracker);
+
   switch (animation->fill_mode)
     {
     case GTK_CSS_FILL_NONE:
-      return iteration >= 0 && iteration <= animation->iteration_count;
+      return state == GTK_PROGRESS_STATE_DURING;
     case GTK_CSS_FILL_FORWARDS:
-      return iteration >= 0;
+      return state != GTK_PROGRESS_STATE_BEFORE;
     case GTK_CSS_FILL_BACKWARDS:
-      return iteration <= animation->iteration_count;
+      return state != GTK_PROGRESS_STATE_AFTER;
     case GTK_CSS_FILL_BOTH:
       return TRUE;
     default:
@@ -65,10 +49,10 @@ gtk_css_animation_is_executing_at_iteration (GtkCssAnimation *animation,
 }
 
 static double
-gtk_css_animation_get_progress_from_iteration (GtkCssAnimation *animation,
-                                               double           iteration)
+gtk_css_animation_get_ease (GtkCssAnimation *animation)
 {
   gboolean reverse;
+  double iteration = gtk_progress_tracker_get_iteration (&animation->tracker);
   double completed;
 
   iteration = CLAMP (iteration, 0.0, animation->iteration_count);
@@ -92,11 +76,7 @@ gtk_css_animation_get_progress_from_iteration (GtkCssAnimation *animation,
       g_return_val_if_reached (0.0);
     }
 
-  iteration -= completed;
-  if (reverse)
-    iteration = 1.0 - iteration;
-
-  return iteration;
+    return gtk_progress_tracker_get_ease (&animation->tracker, animation->ease, reverse);
 }
 
 static void
@@ -105,17 +85,17 @@ gtk_css_animation_set_values (GtkStyleAnimation    *style_animation,
                               GtkCssAnimatedStyle  *style)
 {
   GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation);
-  double iteration, progress;
+  double ease;
   guint i;
 
-  iteration = gtk_css_animation_get_iteration (animation, for_time_us);
+  if (animation->play_state != GTK_CSS_PLAY_STATE_PAUSED)
+    gtk_progress_tracker_next_frame (&animation->tracker, for_time_us);
 
-  if (!gtk_css_animation_is_executing_at_iteration (animation, iteration))
+  if (!gtk_css_animation_is_executing (animation))
     return;
 
-  progress = gtk_css_animation_get_progress_from_iteration (animation, iteration);
-  progress = _gtk_css_ease_value_transform (animation->ease, progress);
-  
+  ease = gtk_css_animation_get_ease (animation);
+
   for (i = 0; i < _gtk_css_keyframes_get_n_properties (animation->keyframes); i++)
     {
       GtkCssValue *value;
@@ -125,7 +105,7 @@ gtk_css_animation_set_values (GtkStyleAnimation    *style_animation,
 
       value = _gtk_css_keyframes_get_value (animation->keyframes,
                                             i,
-                                            progress,
+                                            ease,
                                             gtk_css_animated_style_get_intrinsic_value (style, property_id));
       gtk_css_animated_style_set_animated_value (style, property_id, value);
       _gtk_css_value_unref (value);
@@ -133,15 +113,13 @@ gtk_css_animation_set_values (GtkStyleAnimation    *style_animation,
 }
 
 static gboolean
-gtk_css_animation_is_finished (GtkStyleAnimation *style_animation,
-                               gint64             at_time_us)
+gtk_css_animation_is_finished (GtkStyleAnimation *style_animation)
 {
   return FALSE;
 }
 
 static gboolean
-gtk_css_animation_is_static (GtkStyleAnimation *style_animation,
-                             gint64             at_time_us)
+gtk_css_animation_is_static (GtkStyleAnimation *style_animation)
 {
   GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation);
   double iteration;
@@ -149,7 +127,7 @@ gtk_css_animation_is_static (GtkStyleAnimation *style_animation,
   if (animation->play_state == GTK_CSS_PLAY_STATE_PAUSED)
     return TRUE;
 
-  iteration = gtk_css_animation_get_iteration (animation, at_time_us);
+  iteration = gtk_progress_tracker_get_iteration (&animation->tracker);
 
   return iteration >= animation->iteration_count;
 }
@@ -187,7 +165,6 @@ _gtk_css_animation_init (GtkCssAnimation *animation)
 GtkStyleAnimation *
 _gtk_css_animation_new (const char      *name,
                         GtkCssKeyframes *keyframes,
-                        gint64           timestamp,
                         gint64           delay_us,
                         gint64           duration_us,
                         GtkCssValue     *ease,
@@ -207,11 +184,6 @@ _gtk_css_animation_new (const char      *name,
 
   animation->name = g_strdup (name);
   animation->keyframes = _gtk_css_keyframes_ref (keyframes);
-  if (play_state == GTK_CSS_PLAY_STATE_PAUSED)
-    animation->timestamp = - delay_us;
-  else
-    animation->timestamp = timestamp + delay_us;
-
   animation->duration = duration_us;
   animation->ease = _gtk_css_value_ref (ease);
   animation->direction = direction;
@@ -219,6 +191,8 @@ _gtk_css_animation_new (const char      *name,
   animation->fill_mode = fill_mode;
   animation->iteration_count = iteration_count;
 
+  gtk_progress_tracker_start (&animation->tracker, duration_us, delay_us, iteration_count);
+
   return GTK_STYLE_ANIMATION (animation);
 }
 
@@ -232,7 +206,6 @@ _gtk_css_animation_get_name (GtkCssAnimation *animation)
 
 GtkStyleAnimation *
 _gtk_css_animation_copy (GtkCssAnimation *animation,
-                         gint64           at_time_us,
                          GtkCssPlayState  play_state)
 {
   g_return_val_if_fail (GTK_IS_CSS_ANIMATION (animation), NULL);
@@ -242,8 +215,7 @@ _gtk_css_animation_copy (GtkCssAnimation *animation,
 
   return _gtk_css_animation_new (animation->name,
                                  animation->keyframes,
-                                 at_time_us,
-                                 - gtk_css_animation_get_elapsed (animation, at_time_us),
+                                 - gtk_progress_tracker_get_iteration (&animation->tracker) * 
animation->duration,
                                  animation->duration,
                                  animation->ease,
                                  animation->direction,
diff --git a/gtk/gtkcssanimationprivate.h b/gtk/gtkcssanimationprivate.h
index 928b614..6cf3b46 100644
--- a/gtk/gtkcssanimationprivate.h
+++ b/gtk/gtkcssanimationprivate.h
@@ -23,6 +23,7 @@
 #include "gtkstyleanimationprivate.h"
 
 #include "gtkcsskeyframesprivate.h"
+#include "gtkprogresstrackerprivate.h"
 
 G_BEGIN_DECLS
 
@@ -43,12 +44,12 @@ struct _GtkCssAnimation
   char            *name;
   GtkCssKeyframes *keyframes;
   GtkCssValue     *ease;
-  gint64           timestamp;           /* elapsed time when paused, start time when playing (can be 
negative) */
   gint64           duration;            /* duration of 1 cycle */
   double           iteration_count;
   GtkCssDirection  direction;
   GtkCssPlayState  play_state;
   GtkCssFillMode   fill_mode;
+  GtkProgressTracker tracker;
 };
 
 struct _GtkCssAnimationClass
@@ -60,7 +61,6 @@ GType                   _gtk_css_animation_get_type        (void) G_GNUC_CONST;
 
 GtkStyleAnimation *     _gtk_css_animation_new             (const char         *name,
                                                             GtkCssKeyframes    *keyframes,
-                                                            gint64              timestamp,
                                                             gint64              delay_us,
                                                             gint64              duration_us,
                                                             GtkCssValue        *ease,
@@ -70,7 +70,6 @@ GtkStyleAnimation *     _gtk_css_animation_new             (const char         *
                                                             double              iteration_count);
 
 GtkStyleAnimation *     _gtk_css_animation_copy            (GtkCssAnimation   *animation,
-                                                            gint64             at_time_us,
                                                             GtkCssPlayState    play_state);
 
 const char *            _gtk_css_animation_get_name        (GtkCssAnimation   *animation);
diff --git a/gtk/gtkcsstransition.c b/gtk/gtkcsstransition.c
index 747bac1..d5ff14d 100644
--- a/gtk/gtkcsstransition.c
+++ b/gtk/gtkcsstransition.c
@@ -22,6 +22,7 @@
 #include "gtkcsstransitionprivate.h"
 
 #include "gtkcsseasevalueprivate.h"
+#include "gtkprogresstrackerprivate.h"
 
 G_DEFINE_TYPE (GtkCssTransition, _gtk_css_transition, GTK_TYPE_STYLE_ANIMATION)
 
@@ -32,50 +33,43 @@ gtk_css_transition_set_values (GtkStyleAnimation   *animation,
 {
   GtkCssTransition *transition = GTK_CSS_TRANSITION (animation);
   GtkCssValue *value, *end;
-  double progress;
+  double ease;
 
   end = gtk_css_animated_style_get_intrinsic_value (style, transition->property);
 
-  if (transition->start_time >= for_time_us)
-    value = _gtk_css_value_ref (transition->start);
-  else if (transition->end_time > for_time_us)
-    {
-      progress = (double) (for_time_us - transition->start_time) / (transition->end_time - 
transition->start_time);
-      progress = _gtk_css_ease_value_transform (transition->ease, progress);
-
-      value = _gtk_css_value_transition (transition->start,
-                                         end,
-                                         transition->property,
-                                         progress);
-      if (value == NULL)
-        value = _gtk_css_value_ref (end);
-    }
-  else
-    value = NULL;
-
-  if (value)
-    {
-      gtk_css_animated_style_set_animated_value (style, transition->property, value);
-      _gtk_css_value_unref (value);
-    }
+  gtk_progress_tracker_next_frame (&transition->tracker, for_time_us);
+  if (gtk_progress_tracker_get_state (&transition->tracker) != GTK_PROGRESS_STATE_DURING)
+    return;
+
+  ease = gtk_progress_tracker_get_ease (&transition->tracker,
+                                        transition->ease,
+                                        FALSE);
+  value = _gtk_css_value_transition (transition->start,
+                                     end,
+                                     transition->property,
+                                     ease);
+
+  if (value == NULL)
+    value = _gtk_css_value_ref (end);
+
+  gtk_css_animated_style_set_animated_value (style, transition->property, value);
+  _gtk_css_value_unref (value);
 }
 
 static gboolean
-gtk_css_transition_is_finished (GtkStyleAnimation *animation,
-                                gint64             at_time_us)
+gtk_css_transition_is_finished (GtkStyleAnimation *animation)
 {
   GtkCssTransition *transition = GTK_CSS_TRANSITION (animation);
 
-  return at_time_us >= transition->end_time;
+  return gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER;
 }
 
 static gboolean
-gtk_css_transition_is_static (GtkStyleAnimation *animation,
-                              gint64             at_time_us)
+gtk_css_transition_is_static (GtkStyleAnimation *animation)
 {
   GtkCssTransition *transition = GTK_CSS_TRANSITION (animation);
 
-  return at_time_us >= transition->end_time;
+  return gtk_progress_tracker_get_iteration (&transition->tracker) == GTK_PROGRESS_STATE_AFTER;
 }
 
 static void
@@ -111,22 +105,20 @@ GtkStyleAnimation *
 _gtk_css_transition_new (guint        property,
                          GtkCssValue *start,
                          GtkCssValue *ease,
-                         gint64       start_time_us,
-                         gint64       end_time_us)
+                         gint64       duration_us,
+                         gint64       delay_us)
 {
   GtkCssTransition *transition;
 
   g_return_val_if_fail (start != NULL, NULL);
   g_return_val_if_fail (ease != NULL, NULL);
-  g_return_val_if_fail (start_time_us <= end_time_us, NULL);
 
   transition = g_object_new (GTK_TYPE_CSS_TRANSITION, NULL);
 
   transition->property = property;
   transition->start = _gtk_css_value_ref (start);
   transition->ease = _gtk_css_value_ref (ease);
-  transition->start_time = start_time_us;
-  transition->end_time = end_time_us;
+  gtk_progress_tracker_start (&transition->tracker, duration_us, delay_us, 1.0);
 
   return GTK_STYLE_ANIMATION (transition);
 }
diff --git a/gtk/gtkcsstransitionprivate.h b/gtk/gtkcsstransitionprivate.h
index 2d075b0..919e042 100644
--- a/gtk/gtkcsstransitionprivate.h
+++ b/gtk/gtkcsstransitionprivate.h
@@ -21,6 +21,7 @@
 #define __GTK_CSS_TRANSITION_PRIVATE_H__
 
 #include "gtkstyleanimationprivate.h"
+#include "gtkprogresstrackerprivate.h"
 
 G_BEGIN_DECLS
 
@@ -38,11 +39,10 @@ struct _GtkCssTransition
 {
   GtkStyleAnimation parent;
 
-  guint        property;
-  GtkCssValue *start;
-  GtkCssValue *ease;
-  gint64       start_time;
-  gint64       end_time;
+  guint               property;
+  GtkCssValue        *start;
+  GtkCssValue        *ease;
+  GtkProgressTracker  tracker;
 };
 
 struct _GtkCssTransitionClass
@@ -55,8 +55,8 @@ GType                   _gtk_css_transition_get_type        (void) G_GNUC_CONST;
 GtkStyleAnimation *     _gtk_css_transition_new             (guint               property,
                                                              GtkCssValue        *start,
                                                              GtkCssValue        *ease,
-                                                             gint64              start_time_us,
-                                                             gint64              end_time_us);
+                                                             gint64              duration_us,
+                                                             gint64              delay_us);
 
 guint                   _gtk_css_transition_get_property    (GtkCssTransition   *transition);
 
diff --git a/gtk/gtkprogresstracker.c b/gtk/gtkprogresstracker.c
index aa8edb4..d6e736e 100644
--- a/gtk/gtkprogresstracker.c
+++ b/gtk/gtkprogresstracker.c
@@ -18,71 +18,101 @@
  */
 
 #include "gtkprogresstrackerprivate.h"
+#include "gtkcsseasevalueprivate.h"
+
+#include <math.h>
 
 void
-gtk_progress_tracker_start (GtkProgressTracker *helper,
-                            guint duration)
+gtk_progress_tracker_start (GtkProgressTracker *tracker,
+                            guint64 duration,
+                            gint64 delay,
+                            gdouble iteration_count)
 {
-  helper->is_running = TRUE;
-  helper->progress = 0.0;
-  /* We will not actually record a start time until our first frame has been
-   * recorded. */
-  helper->start_time = 0;
-  helper->end_time = duration;
+  tracker->is_running = TRUE;
+  tracker->last_frame_time = 0;
+  tracker->duration = duration;
+  tracker->iteration = - delay / (gdouble) duration;
+  tracker->iteration_count = iteration_count;
 }
 
 void
-gtk_progress_tracker_finish (GtkProgressTracker *helper)
+gtk_progress_tracker_finish (GtkProgressTracker *tracker)
 {
-  helper->is_running = FALSE;
+  tracker->is_running = FALSE;
 }
 
 void
-gtk_progress_tracker_next_frame (GtkProgressTracker *helper,
-                                 guint frame_time)
+gtk_progress_tracker_next_frame (GtkProgressTracker *tracker,
+                                 guint64 frame_time)
 {
-  if (!helper->is_running)
-    return;
+  gdouble delta;
 
-  if (helper->start_time == 0)
-    {
-      helper->start_time += frame_time;
-      helper->end_time += frame_time;
-    }
+  if (!tracker->is_running)
+    return;
 
-  if (frame_time >= helper->end_time)
+  if (tracker->last_frame_time == 0)
     {
-      helper->is_running = FALSE;
+      tracker->last_frame_time = frame_time;
       return;
     }
 
-  helper->progress = (frame_time - helper->start_time) / (double) (helper->end_time - helper->start_time);
+  delta = (frame_time - tracker->last_frame_time) / (gdouble) tracker->duration;
+  tracker->last_frame_time = frame_time;
+  tracker->iteration += delta;
 }
 
-gboolean
-gtk_progress_tracker_is_running (GtkProgressTracker *helper)
+GtkProgressState
+gtk_progress_tracker_get_state (GtkProgressTracker *tracker)
 {
-  return helper->is_running;
+  if (!tracker->is_running || tracker->iteration > tracker->iteration_count)
+    return GTK_PROGRESS_STATE_AFTER;
+  if (tracker->iteration < 0)
+    return GTK_PROGRESS_STATE_BEFORE;
+  return GTK_PROGRESS_STATE_DURING;
 }
 
 gdouble
-gtk_progress_tracker_get_progress (GtkProgressTracker *helper)
+gtk_progress_tracker_get_iteration (GtkProgressTracker *tracker)
 {
-  return helper->is_running ? helper->progress : 1.0;
+  return tracker->is_running ? tracker->iteration : 1.0;
+}
+
+gdouble
+gtk_progress_tracker_get_progress (GtkProgressTracker *tracker,
+                                   gboolean reversed)
+{
+  gdouble progress;
+
+  if (!tracker->is_running)
+    return reversed ? 0.0 : 1.0;
+
+  progress = CLAMP (tracker->iteration, 0, tracker->iteration_count);
+  progress = progress - floor (progress);
+
+  return reversed ? 1.0 - progress : progress;
 }
 
 /* From clutter-easing.c, based on Robert Penner's
  * infamous easing equations, MIT license.
  */
-static double
-ease_out_cubic (double t)
+static gdouble
+ease_out_cubic (gdouble t)
 {
-  double p = t - 1;
+  gdouble p = t - 1;
   return p * p * p + 1;
 }
 
 gdouble
-gtk_progress_tracker_get_ease (GtkProgressTracker *helper)
+gtk_progress_tracker_get_ease (GtkProgressTracker *tracker,
+                               GtkCssValue *ease,
+                               gboolean reversed)
 {
-  return ease_out_cubic (gtk_progress_tracker_get_progress (helper));
+  gdouble progress = gtk_progress_tracker_get_progress (tracker, reversed);
+
+  /* XXX: We've combined our css easing and non css easing here in the same
+   * function. Would be nice to open up csseasevalue so you could create one
+   * without a css parser, and use the same easings across the entire codebase */
+  if (ease == NULL)
+    return ease_out_cubic (progress);
+  return _gtk_css_ease_value_transform (ease, progress);
 }
diff --git a/gtk/gtkprogresstrackerprivate.h b/gtk/gtkprogresstrackerprivate.h
index 442a4f4..49d61db 100644
--- a/gtk/gtkprogresstrackerprivate.h
+++ b/gtk/gtkprogresstrackerprivate.h
@@ -21,32 +21,47 @@
 #define __GTK_PROGRESS_TRACKER_PRIVATE_H__
 
 #include <glib-object.h>
+#include "gtkcsseasevalueprivate.h"
 
 G_BEGIN_DECLS
 
+typedef enum {
+  GTK_PROGRESS_STATE_BEFORE,
+  GTK_PROGRESS_STATE_DURING,
+  GTK_PROGRESS_STATE_AFTER,
+} GtkProgressState;
+
 typedef struct _GtkProgressTracker GtkProgressTracker;
 
 struct _GtkProgressTracker
 {
   gboolean is_running;
-  guint start_time;
-  guint end_time;
-  double progress;
+  guint64 last_frame_time;
+  guint64 duration;
+  gdouble iteration;
+  gdouble iteration_count;
 };
 
-void                 gtk_progress_tracker_start        (GtkProgressTracker *helper,
-                                                        guint duration);
+void                 gtk_progress_tracker_start        (GtkProgressTracker *tracker,
+                                                        guint64 duration,
+                                                        gint64 delay,
+                                                        gdouble iteration_count);
+
+void                 gtk_progress_tracker_finish       (GtkProgressTracker *tracker);
 
-void                 gtk_progress_tracker_finish       (GtkProgressTracker *helper);
+void                 gtk_progress_tracker_next_frame   (GtkProgressTracker *tracker,
+                                                        guint64 frame_time);
 
-void                 gtk_progress_tracker_next_frame   (GtkProgressTracker *helper,
-                                                        guint frame_time);
+GtkProgressState     gtk_progress_tracker_get_state    (GtkProgressTracker *tracker);
 
-gboolean             gtk_progress_tracker_is_running   (GtkProgressTracker *helper);
+gdouble              gtk_progress_tracker_get_iteration (GtkProgressTracker *tracker);
 
-gdouble              gtk_progress_tracker_get_progress (GtkProgressTracker *helper);
+gdouble              gtk_progress_tracker_get_progress (GtkProgressTracker *tracker,
+                                                        gboolean reverse);
 
-gdouble              gtk_progress_tracker_get_ease     (GtkProgressTracker *helper);
+gdouble              gtk_progress_tracker_get_ease     (GtkProgressTracker *tracker,
+                                                        GtkCssValue *ease,
+                                                        gboolean reverse);
 
 G_END_DECLS
 
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index 7103941..e63c9e5 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -145,7 +145,7 @@ typedef struct {
   cairo_surface_t *last_visible_surface;
   GtkAllocation last_visible_surface_allocation;
   guint tick_id;
-  GtkProgressTracker progress_tracker;
+  GtkProgressTracker tracker;
   gboolean first_frame_skipped;
 
   gint last_visible_widget_width;
@@ -853,12 +853,12 @@ get_bin_window_x (GtkStack            *stack,
   GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
   int x = 0;
 
-  if (gtk_progress_tracker_is_running (&priv->progress_tracker))
+  if (gtk_progress_tracker_get_state (&priv->tracker) != GTK_PROGRESS_STATE_AFTER)
     {
       if (is_left_transition (priv->active_transition_type))
-        x = allocation->width * (1 - gtk_progress_tracker_get_ease (&priv->progress_tracker));
+        x = allocation->width * (1 - gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE));
       if (is_right_transition (priv->active_transition_type))
-        x = -allocation->width * (1 - gtk_progress_tracker_get_ease (&priv->progress_tracker));
+        x = -allocation->width * (1 - gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE));
     }
 
   return x;
@@ -871,12 +871,12 @@ get_bin_window_y (GtkStack            *stack,
   GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
   int y = 0;
 
-  if (gtk_progress_tracker_is_running (&priv->progress_tracker))
+  if (gtk_progress_tracker_get_state (&priv->tracker) != GTK_PROGRESS_STATE_AFTER)
     {
       if (is_up_transition (priv->active_transition_type))
-        y = allocation->height * (1 - gtk_progress_tracker_get_ease (&priv->progress_tracker));
+        y = allocation->height * (1 - gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE));
       if (is_down_transition(priv->active_transition_type))
-        y = -allocation->height * (1 - gtk_progress_tracker_get_ease (&priv->progress_tracker));
+        y = -allocation->height * (1 - gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE));
     }
 
   return y;
@@ -901,7 +901,7 @@ gtk_stack_progress_updated (GtkStack *stack)
                        get_bin_window_x (stack, &allocation), get_bin_window_y (stack, &allocation));
     }
 
-  if (!gtk_progress_tracker_is_running (&priv->progress_tracker))
+  if (gtk_progress_tracker_get_state (&priv->tracker) == GTK_PROGRESS_STATE_AFTER)
     {
       if (priv->last_visible_surface != NULL)
         {
@@ -926,18 +926,18 @@ gtk_stack_transition_cb (GtkWidget     *widget,
   GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
 
   if (priv->first_frame_skipped)
-    gtk_progress_tracker_next_frame (&priv->progress_tracker,
+    gtk_progress_tracker_next_frame (&priv->tracker,
                                      gdk_frame_clock_get_frame_time (frame_clock));
   else
     priv->first_frame_skipped = TRUE;
 
   /* Finish animation early if not mapped anymore */
   if (!gtk_widget_get_mapped (widget))
-    gtk_progress_tracker_finish (&priv->progress_tracker);
+    gtk_progress_tracker_finish (&priv->tracker);
 
   gtk_stack_progress_updated (GTK_STACK (widget));
 
-  if (!gtk_progress_tracker_is_running (&priv->progress_tracker))
+  if (gtk_progress_tracker_get_state (&priv->tracker) == GTK_PROGRESS_STATE_AFTER)
     {
       priv->tick_id = 0;
       g_object_notify_by_pspec (G_OBJECT (stack), stack_props[PROP_TRANSITION_RUNNING]);
@@ -1023,14 +1023,16 @@ gtk_stack_start_transition (GtkStack               *stack,
       priv->active_transition_type = effective_transition_type (stack, transition_type);
       priv->first_frame_skipped = FALSE;
       gtk_stack_schedule_ticks (stack);
-      gtk_progress_tracker_start (&priv->progress_tracker,
-                                  priv->transition_duration * 1000);
+      gtk_progress_tracker_start (&priv->tracker,
+                                  priv->transition_duration * 1000,
+                                  0,
+                                  1.0);
     }
   else
     {
       gtk_stack_unschedule_ticks (stack);
       priv->active_transition_type = GTK_STACK_TRANSITION_TYPE_NONE;
-      gtk_progress_tracker_finish (&priv->progress_tracker);
+      gtk_progress_tracker_finish (&priv->tracker);
       gtk_stack_progress_updated (GTK_STACK (widget));
     }
 }
@@ -1946,7 +1948,7 @@ gtk_stack_draw_crossfade (GtkWidget *widget,
 {
   GtkStack *stack = GTK_STACK (widget);
   GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
-  gdouble progress = gtk_progress_tracker_get_progress (&priv->progress_tracker);
+  gdouble progress = gtk_progress_tracker_get_progress (&priv->tracker, FALSE);
 
   cairo_push_group (cr);
   gtk_container_propagate_draw (GTK_CONTAINER (stack),
@@ -1994,22 +1996,22 @@ gtk_stack_draw_under (GtkWidget *widget,
     {
     case GTK_STACK_TRANSITION_TYPE_UNDER_DOWN:
       y = 0;
-      height = allocation.height * (gtk_progress_tracker_get_ease (&priv->progress_tracker));
+      height = allocation.height * (gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE));
       pos_y = height;
       break;
     case GTK_STACK_TRANSITION_TYPE_UNDER_UP:
-      y = allocation.height * (1 - gtk_progress_tracker_get_ease (&priv->progress_tracker));
+      y = allocation.height * (1 - gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE));
       height = allocation.height - y;
       pos_y = y - allocation.height;
       break;
     case GTK_STACK_TRANSITION_TYPE_UNDER_LEFT:
-      x = allocation.width * (1 - gtk_progress_tracker_get_ease (&priv->progress_tracker));
+      x = allocation.width * (1 - gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE));
       width = allocation.width - x;
       pos_x = x - allocation.width;
       break;
     case GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT:
       x = 0;
-      width = allocation.width * (gtk_progress_tracker_get_ease (&priv->progress_tracker));
+      width = allocation.width * (gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE));
       pos_x = width;
       break;
     default:
@@ -2140,7 +2142,7 @@ gtk_stack_render (GtkCssGadget *gadget,
 
   if (priv->visible_child)
     {
-      if (gtk_progress_tracker_is_running (&priv->progress_tracker))
+      if (gtk_progress_tracker_get_state (&priv->tracker) != GTK_PROGRESS_STATE_AFTER)
         {
           if (priv->last_visible_surface == NULL &&
               priv->last_visible_child != NULL)
@@ -2406,13 +2408,13 @@ gtk_stack_measure (GtkCssGadget   *gadget,
     {
       if (orientation == GTK_ORIENTATION_VERTICAL && !priv->vhomogeneous)
         {
-          gdouble t = priv->interpolate_size ? gtk_progress_tracker_get_ease (&priv->progress_tracker) : 1.0;
+          gdouble t = priv->interpolate_size ? gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE) : 
1.0;
           *minimum = LERP (*minimum, priv->last_visible_widget_height, t);
           *natural = LERP (*natural, priv->last_visible_widget_height, t);
         }
       if (orientation == GTK_ORIENTATION_HORIZONTAL && !priv->hhomogeneous)
         {
-          gdouble t = priv->interpolate_size ? gtk_progress_tracker_get_ease (&priv->progress_tracker) : 1.0;
+          gdouble t = priv->interpolate_size ? gtk_progress_tracker_get_ease (&priv->tracker, NULL, FALSE) : 
1.0;
           *minimum = LERP (*minimum, priv->last_visible_widget_width, t);
           *natural = LERP (*natural, priv->last_visible_widget_width, t);
         }
diff --git a/gtk/gtkstyleanimation.c b/gtk/gtkstyleanimation.c
index 3c1a887..0ca8852 100644
--- a/gtk/gtkstyleanimation.c
+++ b/gtk/gtkstyleanimation.c
@@ -31,15 +31,13 @@ gtk_style_animation_real_set_values (GtkStyleAnimation    *animation,
 }
 
 static gboolean
-gtk_style_animation_real_is_finished (GtkStyleAnimation *animation,
-                                      gint64             at_time_us)
+gtk_style_animation_real_is_finished (GtkStyleAnimation *animation)
 {
   return TRUE;
 }
 
 static gboolean
-gtk_style_animation_real_is_static (GtkStyleAnimation *animation,
-                                    gint64             at_time_us)
+gtk_style_animation_real_is_static (GtkStyleAnimation *animation)
 {
   return FALSE;
 }
@@ -73,8 +71,7 @@ _gtk_style_animation_set_values (GtkStyleAnimation    *animation,
 }
 
 gboolean
-_gtk_style_animation_is_finished (GtkStyleAnimation *animation,
-                                  gint64             at_time_us)
+_gtk_style_animation_is_finished (GtkStyleAnimation *animation)
 {
   GtkStyleAnimationClass *klass;
 
@@ -82,7 +79,7 @@ _gtk_style_animation_is_finished (GtkStyleAnimation *animation,
 
   klass = GTK_STYLE_ANIMATION_GET_CLASS (animation);
 
-  return klass->is_finished (animation, at_time_us);
+  return klass->is_finished (animation);
 }
 
 /**
@@ -97,8 +94,7 @@ _gtk_style_animation_is_finished (GtkStyleAnimation *animation,
  * Returns: %TRUE if @animation will not change anymore after @at_time_us
  **/
 gboolean
-_gtk_style_animation_is_static (GtkStyleAnimation *animation,
-                                gint64             at_time_us)
+_gtk_style_animation_is_static (GtkStyleAnimation *animation)
 {
   GtkStyleAnimationClass *klass;
 
@@ -106,5 +102,5 @@ _gtk_style_animation_is_static (GtkStyleAnimation *animation,
 
   klass = GTK_STYLE_ANIMATION_GET_CLASS (animation);
 
-  return klass->is_static (animation, at_time_us);
+  return klass->is_static (animation);
 }
diff --git a/gtk/gtkstyleanimationprivate.h b/gtk/gtkstyleanimationprivate.h
index 6981004..5fc3a96 100644
--- a/gtk/gtkstyleanimationprivate.h
+++ b/gtk/gtkstyleanimationprivate.h
@@ -43,10 +43,8 @@ struct _GtkStyleAnimationClass
 {
   GObjectClass parent_class;
 
-  gboolean      (* is_finished)                         (GtkStyleAnimation      *animation,
-                                                         gint64                  at_time_us);
-  gboolean      (* is_static)                           (GtkStyleAnimation      *animation,
-                                                         gint64                  at_time_us);
+  gboolean      (* is_finished)                         (GtkStyleAnimation      *animation);
+  gboolean      (* is_static)                           (GtkStyleAnimation      *animation);
   void          (* set_values)                          (GtkStyleAnimation      *animation,
                                                          gint64                  for_time_us,
                                                          GtkCssAnimatedStyle    *style);
@@ -57,10 +55,8 @@ GType           _gtk_style_animation_get_type           (void) G_GNUC_CONST;
 void            _gtk_style_animation_set_values         (GtkStyleAnimation      *animation,
                                                          gint64                  for_time_us,
                                                          GtkCssAnimatedStyle    *style);
-gboolean        _gtk_style_animation_is_finished        (GtkStyleAnimation      *animation,
-                                                         gint64                  at_time_us);
-gboolean        _gtk_style_animation_is_static          (GtkStyleAnimation      *animation,
-                                                         gint64                  at_time_us);
+gboolean        _gtk_style_animation_is_finished        (GtkStyleAnimation      *animation);
+gboolean        _gtk_style_animation_is_static          (GtkStyleAnimation      *animation);
 
 
 G_END_DECLS


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