[clutter/remove-alpha: 2/3] timeline: Allow overriding the progress computation
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/remove-alpha: 2/3] timeline: Allow overriding the progress computation
- Date: Mon, 10 Oct 2011 11:07:32 +0000 (UTC)
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]