[clutter/remove-alpha: 2/3] timeline: Allow overriding the progress computation



commit 30c554c5eb41b3bdec91335be893b563f0fc0b80
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Tue Jul 12 12:45:53 2011 +0100

    timeline: Allow overriding the progress computation
    
    The main reason we have ClutterAlpha is to add a progress function to
    ClutterTimeline; while this worked fine to share the same alpha and
    timeline instances with multiple behaviours, it has started to become
    less useful with the introduction of the animation API - both the
    timeline and the alpha are generally hidden behind duration and easing
    mode, and sharing instances is less of a problem given that all timelines
    are now just simple objects driven by the master clock instead of
    separate timeout sources in the main loop.
    
    Instead of using ClutterAlpha as a source to drive the animation, using
    the timeline's new-frame signal and computing the easing curve through
    the transformation of the timeline's progress, we can make the Timeline
    itself return its progress filtered through a progress function.

 clutter/clutter-marshal.list |    1 +
 clutter/clutter-timeline.c   |  270 ++++++++++++++++++++++++++++++++++++++----
 clutter/clutter-timeline.h   |  148 ++++++++++++++++-------
 3 files changed, 352 insertions(+), 67 deletions(-)
---
diff --git a/clutter/clutter-marshal.list b/clutter/clutter-marshal.list
index d189a82..d39efc7 100644
--- a/clutter/clutter-marshal.list
+++ b/clutter/clutter-marshal.list
@@ -4,6 +4,7 @@ BOOLEAN:STRING,UINT,FLAGS
 BOOLEAN:OBJECT
 BOOLEAN:OBJECT,FLOAT,FLOAT
 BOXED:UINT,UINT
+DOUBLE:DOUBLE,DOUBLE
 DOUBLE:VOID
 UINT:VOID
 VOID:BOXED
diff --git a/clutter/clutter-timeline.c b/clutter/clutter-timeline.c
index 2f6e511..cadc08e 100644
--- a/clutter/clutter-timeline.c
+++ b/clutter/clutter-timeline.c
@@ -36,6 +36,7 @@
 #endif
 
 #include "clutter-debug.h"
+#include "clutter-easing.h"
 #include "clutter-enum-types.h"
 #include "clutter-main.h"
 #include "clutter-marshal.h"
@@ -66,6 +67,11 @@ struct _ClutterTimelinePrivate
   /* Time we last advanced the elapsed time and showed a frame */
   gint64 last_frame_time;
 
+  ClutterTimelineProgressFunc progress_func;
+  gpointer progress_data;
+  GDestroyNotify progress_notify;
+  ClutterAnimationMode progress_mode;
+
   guint loop               : 1;
   guint is_playing         : 1;
 
@@ -91,6 +97,7 @@ enum
   PROP_DURATION,
   PROP_DIRECTION,
   PROP_AUTO_REVERSE,
+  PROP_PROGRESS_MODE,
 
   PROP_LAST
 };
@@ -167,6 +174,10 @@ clutter_timeline_set_property (GObject      *object,
       clutter_timeline_set_auto_reverse (timeline, g_value_get_boolean (value));
       break;
 
+    case PROP_PROGRESS_MODE:
+      clutter_timeline_set_progress_mode (timeline, g_value_get_enum (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -179,8 +190,7 @@ clutter_timeline_get_property (GObject    *object,
 			       GValue     *value,
 			       GParamSpec *pspec)
 {
-  ClutterTimeline *timeline = CLUTTER_TIMELINE (object);
-  ClutterTimelinePrivate *priv = timeline->priv;
+  ClutterTimelinePrivate *priv = CLUTTER_TIMELINE (object)->priv;
 
   switch (prop_id)
     {
@@ -193,7 +203,7 @@ clutter_timeline_get_property (GObject    *object,
       break;
 
     case PROP_DURATION:
-      g_value_set_uint (value, clutter_timeline_get_duration (timeline));
+      g_value_set_uint (value, priv->duration);
       break;
 
     case PROP_DIRECTION:
@@ -204,6 +214,10 @@ clutter_timeline_get_property (GObject    *object,
       g_value_set_boolean (value, priv->auto_reverse);
       break;
 
+    case PROP_PROGRESS_MODE:
+      g_value_set_enum (value, priv->progress_mode);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -217,7 +231,7 @@ clutter_timeline_finalize (GObject *object)
   ClutterTimelinePrivate *priv = self->priv;
   ClutterMasterClock *master_clock;
 
-  if (priv->markers_by_name)
+  if (priv->markers_by_name != NULL)
     g_hash_table_destroy (priv->markers_by_name);
 
   if (priv->is_playing)
@@ -226,18 +240,25 @@ clutter_timeline_finalize (GObject *object)
       _clutter_master_clock_remove_timeline (master_clock, self);
     }
 
+  if (priv->progress_func != NULL)
+    {
+      if (priv->progress_notify != NULL)
+        priv->progress_notify (priv->progress_data);
+
+      priv->progress_func = NULL;
+      priv->progress_data = NULL;
+      priv->progress_notify = NULL;
+    }
+
   G_OBJECT_CLASS (clutter_timeline_parent_class)->finalize (object);
 }
 
 static void
 clutter_timeline_dispose (GObject *object)
 {
-  ClutterTimeline *self = CLUTTER_TIMELINE(object);
-  ClutterTimelinePrivate *priv;
-
-  priv = self->priv;
+  ClutterTimelinePrivate *priv = CLUTTER_TIMELINE(object)->priv;
 
-  if (priv->delay_id)
+  if (priv->delay_id != 0)
     {
       g_source_remove (priv->delay_id);
       priv->delay_id = 0;
@@ -328,13 +349,29 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
                           FALSE,
                           CLUTTER_PARAM_READWRITE);
 
+  /**
+   * ClutterTimeline:progress-mode:
+   *
+   * Sets the progress mode of a #ClutterTimeline using one of the easing
+   * modes provided by Clutter itself.
+   *
+   * The progress mode is used when calling clutter_timeline_get_progress().
+   *
+   * Since: 1.8
+   */
+  obj_props[PROP_PROGRESS_MODE] =
+    g_param_spec_enum ("progress-mode",
+                       P_("Progress Mode"),
+                       P_("The easing mode used to compute the progress"),
+                       CLUTTER_TYPE_ANIMATION_MODE,
+                       CLUTTER_LINEAR,
+                       CLUTTER_PARAM_READWRITE);
+
   object_class->dispose      = clutter_timeline_dispose;
   object_class->finalize     = clutter_timeline_finalize;
   object_class->set_property = clutter_timeline_set_property;
   object_class->get_property = clutter_timeline_get_property;
-  g_object_class_install_properties (object_class,
-                                     PROP_LAST,
-                                     obj_props);
+  g_object_class_install_properties (object_class, PROP_LAST, obj_props);
 
   /**
    * ClutterTimeline::new-frame:
@@ -453,9 +490,8 @@ clutter_timeline_init (ClutterTimeline *self)
     G_TYPE_INSTANCE_GET_PRIVATE (self, CLUTTER_TYPE_TIMELINE,
                                  ClutterTimelinePrivate);
 
-  priv->duration = 0;
-  priv->delay = 0;
-  priv->elapsed_time = 0;
+  /* we default to linear progress */
+  priv->progress_mode = CLUTTER_LINEAR;
 }
 
 struct CheckIfMarkerHitClosure
@@ -1015,6 +1051,7 @@ clutter_timeline_clone (ClutterTimeline *timeline)
                        "loop", clutter_timeline_get_loop (timeline),
                        "delay", clutter_timeline_get_delay (timeline),
                        "direction", clutter_timeline_get_direction (timeline),
+                       "progress-mode", clutter_timeline_get_progress_mode (timeline),
                        NULL);
 
   return copy;
@@ -1097,13 +1134,9 @@ clutter_timeline_set_delay (ClutterTimeline *timeline,
 guint
 clutter_timeline_get_duration (ClutterTimeline *timeline)
 {
-  ClutterTimelinePrivate *priv;
-
   g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0);
 
-  priv = timeline->priv;
-
-  return priv->duration;
+  return timeline->priv->duration;
 }
 
 /**
@@ -1139,7 +1172,9 @@ clutter_timeline_set_duration (ClutterTimeline *timeline,
  * clutter_timeline_get_progress:
  * @timeline: a #ClutterTimeline
  *
- * The position of the timeline in a [0, 1] interval.
+ * The position of the timeline, taking #ClutterTimeline:progress-mode or
+ * the function set using clutter_timeline_set_progress_func() into account
+ * when computing the progress value.
  *
  * Return value: the position of the timeline.
  *
@@ -1149,12 +1184,23 @@ gdouble
 clutter_timeline_get_progress (ClutterTimeline *timeline)
 {
   ClutterTimelinePrivate *priv;
+  gdouble retval;
 
   g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0.0);
 
   priv = timeline->priv;
 
-  return (gdouble) priv->elapsed_time / (gdouble) priv->duration;
+  if (priv->progress_func != NULL)
+    {
+      retval = priv->progress_func (priv->elapsed_time,
+                                    priv->duration,
+                                    priv->progress_data);
+    }
+  else
+    retval = (gdouble) priv->elapsed_time
+           / (gdouble) priv->duration;
+
+  return retval;
 }
 
 /**
@@ -1630,3 +1676,183 @@ clutter_timeline_get_auto_reverse (ClutterTimeline *timeline)
 
   return timeline->priv->auto_reverse;
 }
+
+/* static enum/function mapping table for the animation modes
+ * we provide internally
+ *
+ * XXX - keep in sync with ClutterAnimationMode
+ */
+static const struct {
+  ClutterAnimationMode mode;
+  gpointer func;
+} animation_modes[] = {
+  { CLUTTER_CUSTOM_MODE,         NULL },
+
+  { CLUTTER_LINEAR,              _clutter_linear },
+
+  { CLUTTER_EASE_IN_QUAD,        _clutter_ease_in_quad },
+  { CLUTTER_EASE_OUT_QUAD,       _clutter_ease_out_quad },
+  { CLUTTER_EASE_IN_OUT_QUAD,    _clutter_ease_in_out_quad },
+
+  { CLUTTER_EASE_IN_CUBIC,       _clutter_ease_in_cubic },
+  { CLUTTER_EASE_OUT_CUBIC,      _clutter_ease_out_cubic },
+  { CLUTTER_EASE_IN_OUT_CUBIC,   _clutter_ease_in_out_cubic },
+
+  { CLUTTER_EASE_IN_QUART,       _clutter_ease_in_quart },
+  { CLUTTER_EASE_OUT_QUART,      _clutter_ease_out_quart },
+  { CLUTTER_EASE_IN_OUT_QUART,   _clutter_ease_in_out_quart },
+
+  { CLUTTER_EASE_IN_QUINT,       _clutter_ease_in_quint },
+  { CLUTTER_EASE_OUT_QUINT,      _clutter_ease_out_quint },
+  { CLUTTER_EASE_IN_OUT_QUINT,   _clutter_ease_in_out_quint },
+
+  { CLUTTER_EASE_IN_SINE,        _clutter_ease_in_sine },
+  { CLUTTER_EASE_OUT_SINE,       _clutter_ease_out_sine },
+  { CLUTTER_EASE_IN_OUT_SINE,    _clutter_ease_in_out_sine },
+
+  { CLUTTER_EASE_IN_EXPO,        _clutter_ease_in_expo },
+  { CLUTTER_EASE_OUT_EXPO,       _clutter_ease_out_expo },
+  { CLUTTER_EASE_IN_OUT_EXPO,    _clutter_ease_in_out_expo },
+
+  { CLUTTER_EASE_IN_CIRC,        _clutter_ease_in_circ },
+  { CLUTTER_EASE_OUT_CIRC,       _clutter_ease_out_circ },
+  { CLUTTER_EASE_IN_OUT_CIRC,    _clutter_ease_in_out_circ },
+
+  { CLUTTER_EASE_IN_ELASTIC,     _clutter_ease_in_elastic },
+  { CLUTTER_EASE_OUT_ELASTIC,    _clutter_ease_out_elastic },
+  { CLUTTER_EASE_IN_OUT_ELASTIC, _clutter_ease_in_out_elastic },
+
+  { CLUTTER_EASE_IN_BACK,        _clutter_ease_in_back },
+  { CLUTTER_EASE_OUT_BACK,       _clutter_ease_out_back },
+  { CLUTTER_EASE_IN_OUT_BACK,    _clutter_ease_in_out_back },
+
+  { CLUTTER_EASE_IN_BOUNCE,      _clutter_ease_in_bounce },
+  { CLUTTER_EASE_OUT_BOUNCE,     _clutter_ease_out_bounce },
+  { CLUTTER_EASE_IN_OUT_BOUNCE,  _clutter_ease_in_out_bounce },
+
+  { CLUTTER_ANIMATION_LAST,      NULL },
+};
+
+/**
+ * clutter_timeline_set_progress_mode:
+ * @timeline: a #ClutterTimeline
+ * @mode: a #ClutterAnimationMode
+ *
+ * Sets the progress mode of @timeline using one of the easing modes
+ * provided by Clutter itself.
+ *
+ * If a custom progress function is required, use the
+ * clutter_timeline_set_progress_func() instead.
+ *
+ * Since: 1.8
+ */
+void
+clutter_timeline_set_progress_mode (ClutterTimeline      *timeline,
+                                    ClutterAnimationMode  mode)
+{
+  ClutterTimelinePrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
+  g_return_if_fail (mode > CLUTTER_CUSTOM_MODE &&
+                    mode < CLUTTER_ANIMATION_LAST);
+
+  priv = timeline->priv;
+
+  if (priv->progress_mode == mode)
+    return;
+
+  /* sanity checks */
+  g_assert (animation_modes[mode].mode == mode);
+  g_assert (animation_modes[mode].func != NULL);
+
+  if (priv->progress_notify != NULL)
+    priv->progress_notify (priv->progress_data);
+
+  priv->progress_func = NULL;
+  priv->progress_data = NULL;
+  priv->progress_notify = NULL;
+
+  priv->progress_mode = mode;
+
+  /* avoid using a function to just compute a linear progress */
+  if (priv->progress_mode != CLUTTER_LINEAR)
+    priv->progress_func = animation_modes[mode].func;
+
+  g_object_notify_by_pspec (G_OBJECT (timeline),
+                            obj_props[PROP_PROGRESS_MODE]);
+}
+
+/**
+ * clutter_timeline_get_progress_mode:
+ * @timeline: a #ClutterTimeline
+ *
+ * Retrieves the value set using clutter_timeline_set_progress_mode().
+ *
+ * Return value: the progress mode of the #ClutterTimeline
+ *
+ * Since: 1.8
+ */
+ClutterAnimationMode
+clutter_timeline_get_progress_mode (ClutterTimeline *timeline)
+{
+  g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), CLUTTER_LINEAR);
+
+  return timeline->priv->progress_mode;
+}
+
+/**
+ * clutter_timeline_set_progress_func:
+ * @timeline: a #ClutterTimeline
+ * @func: (allow-none): a #ClutterTimelineProgressFunc or %NULL
+ * @user_data: (closure) (scope notified): data to be passed to @func
+ * @notify: function to be called when the progress function is removed
+ *   or when the @timeline is finalized
+ *
+ * Sets a custom progress function for the given @timeline.
+ *
+ * If @func is %NULL, the @timeline will be restored to the default
+ * linear progress function.
+ *
+ * The #ClutterTimelineProgressFunc function will be called each time
+ * clutter_timeline_get_progress() is called, and will receive the
+ * #ClutterTimeline's elapsed time and total duration; the function
+ * should return the progress as a value computed in the [ -1, 2 ]
+ * interval.
+ *
+ * The passed @user_data will be also passed to the progress function.
+ *
+ * The @notify function will be called when the function is unset, either
+ * by calling clutter_timeline_set_progress_mode() or by another call to
+ * this function, and when the @timeline is finalized.
+ *
+ * The #ClutterTimeline:progress-mode will be set as a side effect.
+ *
+ * Since: 1.8
+ */
+void
+clutter_timeline_set_progress_func (ClutterTimeline             *timeline,
+                                    ClutterTimelineProgressFunc  func,
+                                    gpointer                     user_data,
+                                    GDestroyNotify               notify)
+{
+  ClutterTimelinePrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
+
+  priv = timeline->priv;
+
+  if (priv->progress_notify != NULL)
+    priv->progress_notify (priv->progress_data);
+
+  priv->progress_func = func;
+  priv->progress_data = user_data;
+  priv->progress_notify = notify;
+
+  if (func == NULL)
+    priv->progress_mode = CLUTTER_LINEAR;
+  else
+    priv->progress_mode = CLUTTER_CUSTOM_MODE;
+
+  g_object_notify_by_pspec (G_OBJECT (timeline),
+                            obj_props[PROP_PROGRESS_MODE]);
+}
diff --git a/clutter/clutter-timeline.h b/clutter/clutter-timeline.h
index adc0f90..ce7c67a 100644
--- a/clutter/clutter-timeline.h
+++ b/clutter/clutter-timeline.h
@@ -28,8 +28,7 @@
 #ifndef __CLUTTER_TIMELINE_H__
 #define __CLUTTER_TIMELINE_H__
 
-#include <glib-object.h>
-#include <clutter/clutter-fixed.h>
+#include <clutter/clutter-types.h>
 
 G_BEGIN_DECLS
 
@@ -54,6 +53,56 @@ typedef enum {
   CLUTTER_TIMELINE_BACKWARD
 } ClutterTimelineDirection;
 
+/**
+ * ClutterTimelineProgressFunc:
+ * @elapsed: the time elapsed on the timeline
+ * @duration: the total duration of the timeline
+ * @user_data: data passed to the function
+ *
+ * Computes the progress given a value between 0 and 1.
+ *
+ * A simple linear progress can be implemented by returning the same
+ * value passed to the function, e.g.:
+ *
+ * |[
+ * static gdouble
+ * linear_progress (gdouble  elapsed,
+ *                  gdouble  duration,
+ *                  gpointer data)
+ * {
+ *   return elapsed / duration;
+ * }
+ * ]|
+ *
+ * A linear ramp can be implemented by checking whether the @progress
+ * reached the half-way point, e.g.:
+ *
+ * |[
+ * static gdouble
+ * ramp_progress (gdouble  elapsed,
+ *                gdouble  duration,
+ *                gpointer data)
+ * {
+ *   gdouble progress = elapsed / duration;
+ *
+ *   if (progress >= 0.5)
+ *     return 1.0 - progress;
+ *
+ *   return progress;
+ * }
+ * ]|
+ *
+ * The returned value should be within the [ -1.0, 2.0 ] interval, to allow
+ * overshooting progress functions.
+ *
+ * Return value: a value between -1.0 and 2.0
+ *
+ * Since: 1.8
+ */
+typedef gdouble (* ClutterTimelineProgressFunc) (gdouble  elapsed,
+                                                 gdouble  duration,
+                                                 gpointer user_data);
+
 typedef struct _ClutterTimeline        ClutterTimeline;
 typedef struct _ClutterTimelineClass   ClutterTimelineClass; 
 typedef struct _ClutterTimelinePrivate ClutterTimelinePrivate;
@@ -70,6 +119,7 @@ struct _ClutterTimeline
 {
   /*< private >*/
   GObject parent;
+
   ClutterTimelinePrivate *priv;
 };
 
@@ -112,49 +162,57 @@ struct _ClutterTimelineClass
 
 GType clutter_timeline_get_type (void) G_GNUC_CONST;
 
-ClutterTimeline *clutter_timeline_new                   (guint            msecs);
-ClutterTimeline *clutter_timeline_clone                 (ClutterTimeline *timeline);
-
-guint            clutter_timeline_get_duration          (ClutterTimeline *timeline);
-void             clutter_timeline_set_duration          (ClutterTimeline *timeline,
-                                                         guint            msecs);
-ClutterTimelineDirection clutter_timeline_get_direction (ClutterTimeline *timeline);
-void             clutter_timeline_set_direction         (ClutterTimeline *timeline,
-                                                         ClutterTimelineDirection direction);
-void             clutter_timeline_start                 (ClutterTimeline *timeline);
-void             clutter_timeline_pause                 (ClutterTimeline *timeline);
-void             clutter_timeline_stop                  (ClutterTimeline *timeline);
-void             clutter_timeline_set_loop              (ClutterTimeline *timeline,
-                                                         gboolean         loop);
-gboolean         clutter_timeline_get_loop              (ClutterTimeline *timeline);
-void             clutter_timeline_set_auto_reverse      (ClutterTimeline *timeline,
-                                                         gboolean         reverse);
-gboolean         clutter_timeline_get_auto_reverse      (ClutterTimeline *timeline);
-void             clutter_timeline_rewind                (ClutterTimeline *timeline);
-void             clutter_timeline_skip                  (ClutterTimeline *timeline,
-                                                         guint            msecs);
-void             clutter_timeline_advance               (ClutterTimeline *timeline,
-                                                         guint            msecs);
-guint            clutter_timeline_get_elapsed_time      (ClutterTimeline *timeline);
-gdouble          clutter_timeline_get_progress          (ClutterTimeline *timeline);
-gboolean         clutter_timeline_is_playing            (ClutterTimeline *timeline);
-void             clutter_timeline_set_delay             (ClutterTimeline *timeline,
-                                                         guint            msecs);
-guint            clutter_timeline_get_delay             (ClutterTimeline *timeline);
-guint            clutter_timeline_get_delta             (ClutterTimeline *timeline);
-
-void             clutter_timeline_add_marker_at_time    (ClutterTimeline *timeline,
-                                                         const gchar     *marker_name,
-                                                         guint            msecs);
-void             clutter_timeline_remove_marker         (ClutterTimeline *timeline,
-                                                         const gchar     *marker_name);
-gchar **         clutter_timeline_list_markers          (ClutterTimeline *timeline,
-                                                         gint             msecs,
-                                                         gsize           *n_markers) G_GNUC_MALLOC;
-gboolean         clutter_timeline_has_marker            (ClutterTimeline *timeline,
-                                                         const gchar     *marker_name);
-void             clutter_timeline_advance_to_marker     (ClutterTimeline *timeline,
-                                                         const gchar     *marker_name);
+ClutterTimeline *               clutter_timeline_new                    (guint                        msecs);
+ClutterTimeline *               clutter_timeline_clone                  (ClutterTimeline             *timeline);
+
+guint                           clutter_timeline_get_duration           (ClutterTimeline             *timeline);
+void                            clutter_timeline_set_duration           (ClutterTimeline             *timeline,
+                                                                         guint                        msecs);
+ClutterTimelineDirection        clutter_timeline_get_direction          (ClutterTimeline             *timeline);
+void                            clutter_timeline_set_direction          (ClutterTimeline             *timeline,
+                                                                         ClutterTimelineDirection     direction);
+void                            clutter_timeline_start                  (ClutterTimeline             *timeline);
+void                            clutter_timeline_pause                  (ClutterTimeline             *timeline);
+void                            clutter_timeline_stop                   (ClutterTimeline             *timeline);
+void                            clutter_timeline_set_loop               (ClutterTimeline             *timeline,
+                                                                         gboolean                     loop);
+gboolean                        clutter_timeline_get_loop               (ClutterTimeline             *timeline);
+void                            clutter_timeline_set_auto_reverse       (ClutterTimeline             *timeline,
+                                                                         gboolean                     reverse);
+gboolean                        clutter_timeline_get_auto_reverse       (ClutterTimeline             *timeline);
+void                            clutter_timeline_rewind                 (ClutterTimeline             *timeline);
+void                            clutter_timeline_skip                   (ClutterTimeline             *timeline,
+                                                                         guint                        msecs);
+void                            clutter_timeline_advance                (ClutterTimeline             *timeline,
+                                                                         guint                        msecs);
+guint                           clutter_timeline_get_elapsed_time       (ClutterTimeline             *timeline);
+gdouble                         clutter_timeline_get_progress           (ClutterTimeline             *timeline);
+gboolean                        clutter_timeline_is_playing             (ClutterTimeline             *timeline);
+void                            clutter_timeline_set_delay              (ClutterTimeline             *timeline,
+                                                                         guint                        msecs);
+guint                           clutter_timeline_get_delay              (ClutterTimeline             *timeline);
+guint                           clutter_timeline_get_delta              (ClutterTimeline             *timeline);
+
+void                            clutter_timeline_add_marker_at_time     (ClutterTimeline             *timeline,
+                                                                         const gchar                 *marker_name,
+                                                                         guint                        msecs);
+void                            clutter_timeline_remove_marker          (ClutterTimeline             *timeline,
+                                                                         const gchar                 *marker_name);
+gchar **                        clutter_timeline_list_markers           (ClutterTimeline             *timeline,
+                                                                         gint                         msecs,
+                                                                         gsize                       *n_markers) G_GNUC_MALLOC;
+gboolean                        clutter_timeline_has_marker             (ClutterTimeline             *timeline,
+                                                                         const gchar                 *marker_name);
+void                            clutter_timeline_advance_to_marker      (ClutterTimeline             *timeline,
+                                                                         const gchar                 *marker_name);
+
+void                            clutter_timeline_set_progress_mode      (ClutterTimeline             *timeline,
+                                                                         ClutterAnimationMode         mode);
+ClutterAnimationMode            clutter_timeline_get_progress_mode      (ClutterTimeline             *timeline);
+void                            clutter_timeline_set_progress_func      (ClutterTimeline             *timeline,
+                                                                         ClutterTimelineProgressFunc  func,
+                                                                         gpointer                     user_data,
+                                                                         GDestroyNotify               notify);
 
 /*< private >*/
 void             _clutter_timeline_do_tick              (ClutterTimeline *timeline,



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