[animation] Simplify the Animation code

After long deliberation, the Animation class handling of the
:mode, :duration and :loop properties, as well as the conditions
for creating the Alpha and Timeline instances, came out as far too
complicated for their own good.

This is a rework of the API/parameters matrix and behaviour:

  - :mode accessors will create an Alpha, if needed
  - :duration and :loop accessors will create an Alpha and a Timeline
    if needed
  - :alpha will set or unset the Alpha
  - :timeline will set or unset the Timeline

Plus, more documentation on the Animation class itself.

Many thanks to Jonas Bonn <jonas@southpole.se> for the feedback
and the ideas.
This commit is contained in:
Emmanuele Bassi 2009-05-27 18:28:37 +01:00
parent 6fff1bcdc6
commit ccd3b4c886

View File

@ -25,14 +25,43 @@
/** /**
* SECTION:clutter-animation * SECTION:clutter-animation
* @short_description: Simple implicit animations * @short_description: Simple implicit animations
* @See_Also: #ClutterAnimatable, #ClutterInterval, #ClutterAlpha,
* #ClutterTimeline
* *
* #ClutterAnimation is an object providing simple, implicit animations * #ClutterAnimation is an object providing simple, implicit animations
* for #GObject<!-- -->s. * for #GObject<!-- -->s.
* *
* #ClutterAnimation instances will bind a #GObject property belonging * #ClutterAnimation instances will bind one or more #GObject properties
* to a #GObject to a #ClutterInterval, and will then use a #ClutterTimeline * belonging to a #GObject to a #ClutterInterval, and will then use a
* to interpolate the property between the initial and final values of the * #ClutterAlpha to interpolate the property between the initial and final
* interval. * values of the interval.
*
* The duration of the animation is set using clutter_animation_set_duration().
* The easing mode of the animation is set using clutter_animation_set_mode().
*
* If you want to control the animation you should retrieve the
* #ClutterTimeline using clutter_animation_get_timeline() and then
* use #ClutterTimeline functions like clutter_timeline_start(),
* clutter_timeline_pause() or clutter_timeline_stop().
*
* A #ClutterAnimation will emit the #ClutterAnimation::completed signal
* when the #ClutterTimeline used by the animation is completed; unlike
* #ClutterTimeline, though, the #ClutterAnimation::completed will not be
* emitted if #ClutterAnimation:loop is set to %TRUE - that is, a looping
* animation never completes.
*
* If your animation depends on user control you can force its completion
* using clutter_animation_completed().
*
* If the #GObject instance bound to a #ClutterAnimation implements the
* #ClutterAnimatable interface it is possible for that instance to
* control the way the initial and final states are interpolated.
*
* #ClutterAnimation<!-- -->s are distinguished from #ClutterBehaviour<!-- -->s
* because the former can only control #GObject properties of a single
* #GObject instance, while the latter can control multiple properties
* using accessor functions inside the #ClutterBehaviour::alpha_notify
* virtual function, and can control multiple #ClutterActor<!-- -->s as well.
* *
* For convenience, it is possible to use the clutter_actor_animate() * For convenience, it is possible to use the clutter_actor_animate()
* function call which will take care of setting up and tearing down * function call which will take care of setting up and tearing down
@ -87,11 +116,6 @@ struct _ClutterAnimationPrivate
ClutterAlpha *alpha; ClutterAlpha *alpha;
gulong mode;
guint loop : 1;
guint duration;
guint timeline_started_id; guint timeline_started_id;
guint timeline_completed_id; guint timeline_completed_id;
guint alpha_notify_id; guint alpha_notify_id;
@ -123,34 +147,31 @@ clutter_animation_dispose (GObject *gobject)
ClutterAnimationPrivate *priv = CLUTTER_ANIMATION (gobject)->priv; ClutterAnimationPrivate *priv = CLUTTER_ANIMATION (gobject)->priv;
ClutterTimeline *timeline; ClutterTimeline *timeline;
timeline = clutter_animation_get_timeline (CLUTTER_ANIMATION (gobject)); if (priv->alpha != NULL)
if (timeline != NULL) timeline = clutter_alpha_get_timeline (priv->alpha);
{ else
if (priv->timeline_started_id) timeline = NULL;
{
g_signal_handler_disconnect (timeline, priv->timeline_started_id);
priv->timeline_started_id = 0;
}
if (priv->timeline_completed_id) if (timeline != NULL && priv->timeline_started_id != 0)
{ g_signal_handler_disconnect (timeline, priv->timeline_started_id);
if (timeline != NULL && priv->timeline_completed_id != 0)
g_signal_handler_disconnect (timeline, priv->timeline_completed_id); g_signal_handler_disconnect (timeline, priv->timeline_completed_id);
priv->timeline_started_id = 0;
priv->timeline_completed_id = 0; priv->timeline_completed_id = 0;
}
}
if (priv->alpha != NULL) if (priv->alpha != NULL)
{ {
if (priv->alpha_notify_id) if (priv->alpha_notify_id != 0)
{
g_signal_handler_disconnect (priv->alpha, priv->alpha_notify_id); g_signal_handler_disconnect (priv->alpha, priv->alpha_notify_id);
priv->alpha_notify_id = 0;
}
g_object_unref (priv->alpha); g_object_unref (priv->alpha);
priv->alpha = NULL;
} }
priv->alpha_notify_id = 0;
priv->alpha = NULL;
if (priv->object != NULL) if (priv->object != NULL)
{ {
g_object_weak_unref (G_OBJECT (gobject), g_object_weak_unref (G_OBJECT (gobject),
@ -158,9 +179,10 @@ clutter_animation_dispose (GObject *gobject)
priv->object); priv->object);
g_object_set_qdata (priv->object, quark_object_animation, NULL); g_object_set_qdata (priv->object, quark_object_animation, NULL);
g_object_unref (priv->object); g_object_unref (priv->object);
priv->object = NULL;
} }
priv->object = NULL;
G_OBJECT_CLASS (clutter_animation_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_animation_parent_class)->dispose (gobject);
} }
@ -393,7 +415,6 @@ clutter_animation_init (ClutterAnimation *self)
{ {
self->priv = CLUTTER_ANIMATION_GET_PRIVATE (self); self->priv = CLUTTER_ANIMATION_GET_PRIVATE (self);
self->priv->mode = CLUTTER_LINEAR;
self->priv->properties = self->priv->properties =
g_hash_table_new_full (g_str_hash, g_str_equal, g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free, (GDestroyNotify) g_free,
@ -826,7 +847,7 @@ clutter_animation_get_alpha_internal (ClutterAnimation *animation)
ClutterAlpha *alpha; ClutterAlpha *alpha;
alpha = clutter_alpha_new (); alpha = clutter_alpha_new ();
clutter_alpha_set_mode (alpha, priv->mode); clutter_alpha_set_mode (alpha, CLUTTER_LINEAR);
priv->alpha_notify_id = priv->alpha_notify_id =
g_signal_connect (alpha, "notify::alpha", g_signal_connect (alpha, "notify::alpha",
@ -834,6 +855,8 @@ clutter_animation_get_alpha_internal (ClutterAnimation *animation)
animation); animation);
priv->alpha = g_object_ref_sink (alpha); priv->alpha = g_object_ref_sink (alpha);
g_object_notify (G_OBJECT (animation), "alpha");
} }
return priv->alpha; return priv->alpha;
@ -841,28 +864,17 @@ clutter_animation_get_alpha_internal (ClutterAnimation *animation)
static ClutterTimeline * static ClutterTimeline *
clutter_animation_get_timeline_internal (ClutterAnimation *animation) clutter_animation_get_timeline_internal (ClutterAnimation *animation)
{
ClutterAlpha *alpha;
alpha = clutter_animation_get_alpha_internal (animation);
return clutter_alpha_get_timeline (alpha);
}
static inline void
clutter_animation_create_timeline (ClutterAnimation *animation)
{ {
ClutterAnimationPrivate *priv = animation->priv; ClutterAnimationPrivate *priv = animation->priv;
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterAlpha *alpha; ClutterAlpha *alpha;
alpha = clutter_animation_get_alpha_internal (animation); alpha = clutter_animation_get_alpha_internal (animation);
timeline = clutter_alpha_get_timeline (alpha);
if (timeline != NULL)
return timeline;
timeline = g_object_new (CLUTTER_TYPE_TIMELINE, timeline = g_object_new (CLUTTER_TYPE_TIMELINE, NULL);
"duration", priv->duration,
"loop", priv->loop,
NULL);
clutter_alpha_set_timeline (alpha, timeline);
priv->timeline_started_id = priv->timeline_started_id =
g_signal_connect (timeline, "started", g_signal_connect (timeline, "started",
@ -874,10 +886,14 @@ clutter_animation_create_timeline (ClutterAnimation *animation)
G_CALLBACK (on_timeline_completed), G_CALLBACK (on_timeline_completed),
animation); animation);
/* since we are creating it ourselves, we can offload clutter_alpha_set_timeline (alpha, timeline);
* the ownership of the timeline to the alpha itself
*/ /* the alpha owns the timeline now */
g_object_unref (timeline); g_object_unref (timeline);
g_object_notify (G_OBJECT (animation), "timeline");
return timeline;
} }
/* /*
@ -985,21 +1001,6 @@ clutter_animation_get_object (ClutterAnimation *animation)
return animation->priv->object; return animation->priv->object;
} }
static inline void
clutter_animation_set_mode_internal (ClutterAnimation *animation,
gulong mode)
{
ClutterAnimationPrivate *priv = animation->priv;
ClutterAlpha *alpha;
priv->mode = mode;
alpha = clutter_animation_get_alpha_internal (animation);
clutter_alpha_set_mode (alpha, priv->mode);
g_object_notify (G_OBJECT (animation), "mode");
}
/** /**
* clutter_animation_set_mode: * clutter_animation_set_mode:
* @animation: a #ClutterAnimation * @animation: a #ClutterAnimation
@ -1009,15 +1010,30 @@ clutter_animation_set_mode_internal (ClutterAnimation *animation,
* a logical id, either coming from the #ClutterAnimationMode enumeration * a logical id, either coming from the #ClutterAnimationMode enumeration
* or the return value of clutter_alpha_register_func(). * or the return value of clutter_alpha_register_func().
* *
* This function will also set #ClutterAnimation:alpha if needed.
*
* Since: 1.0 * Since: 1.0
*/ */
void void
clutter_animation_set_mode (ClutterAnimation *animation, clutter_animation_set_mode (ClutterAnimation *animation,
gulong mode) gulong mode)
{ {
ClutterTimeline *timeline;
ClutterAlpha *alpha;
g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); g_return_if_fail (CLUTTER_IS_ANIMATION (animation));
clutter_animation_set_mode_internal (animation, mode); g_object_freeze_notify (G_OBJECT (animation));
alpha = clutter_animation_get_alpha_internal (animation);
clutter_alpha_set_mode (alpha, mode);
timeline = clutter_animation_get_timeline_internal (animation);
clutter_alpha_set_timeline (alpha, timeline);
g_object_notify (G_OBJECT (animation), "mode");
g_object_thaw_notify (G_OBJECT (animation));
} }
/** /**
@ -1034,16 +1050,13 @@ clutter_animation_set_mode (ClutterAnimation *animation,
gulong gulong
clutter_animation_get_mode (ClutterAnimation *animation) clutter_animation_get_mode (ClutterAnimation *animation)
{ {
ClutterAnimationPrivate *priv; ClutterAlpha *alpha;
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), CLUTTER_LINEAR); g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), CLUTTER_LINEAR);
priv = animation->priv; alpha = clutter_animation_get_alpha_internal (animation);
if (priv->alpha != NULL) return clutter_alpha_get_mode (alpha);
return clutter_alpha_get_mode (priv->alpha);
return priv->mode;
} }
/** /**
@ -1053,39 +1066,22 @@ clutter_animation_get_mode (ClutterAnimation *animation)
* *
* Sets the duration of @animation in milliseconds. * Sets the duration of @animation in milliseconds.
* *
* This function will set #ClutterAnimation:alpha and
* #ClutterAnimation:timeline if needed.
*
* Since: 1.0 * Since: 1.0
*/ */
void void
clutter_animation_set_duration (ClutterAnimation *animation, clutter_animation_set_duration (ClutterAnimation *animation,
gint msecs) gint msecs)
{ {
ClutterAnimationPrivate *priv;
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterAlpha *alpha;
g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); g_return_if_fail (CLUTTER_IS_ANIMATION (animation));
priv = animation->priv; timeline = clutter_animation_get_timeline_internal (animation);
clutter_timeline_set_duration (timeline, msecs);
priv->duration = msecs; clutter_timeline_rewind (timeline);
alpha = clutter_animation_get_alpha_internal (animation);
timeline = clutter_alpha_get_timeline (alpha);
if (timeline == NULL)
clutter_animation_create_timeline (animation);
else
{
gboolean was_playing;
was_playing = clutter_timeline_is_playing (timeline);
if (was_playing)
clutter_timeline_stop (timeline);
clutter_timeline_set_duration (timeline, priv->duration);
if (was_playing)
clutter_timeline_start (timeline);
}
g_object_notify (G_OBJECT (animation), "duration"); g_object_notify (G_OBJECT (animation), "duration");
} }
@ -1100,29 +1096,20 @@ clutter_animation_set_duration (ClutterAnimation *animation,
* A looping #ClutterAnimation will not emit the #ClutterAnimation::completed * A looping #ClutterAnimation will not emit the #ClutterAnimation::completed
* signal when finished. * signal when finished.
* *
* This function will set #ClutterAnimation:alpha and
* #ClutterAnimation:timeline if needed.
*
* Since: 1.0 * Since: 1.0
*/ */
void void
clutter_animation_set_loop (ClutterAnimation *animation, clutter_animation_set_loop (ClutterAnimation *animation,
gboolean loop) gboolean loop)
{ {
ClutterAnimationPrivate *priv;
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterAlpha *alpha;
g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); g_return_if_fail (CLUTTER_IS_ANIMATION (animation));
priv = animation->priv; timeline = clutter_animation_get_timeline_internal (animation);
alpha = clutter_animation_get_alpha_internal (animation);
timeline = clutter_alpha_get_timeline (alpha);
if (timeline == NULL)
{
priv->loop = loop;
clutter_animation_create_timeline (animation);
}
else
clutter_timeline_set_loop (timeline, loop); clutter_timeline_set_loop (timeline, loop);
g_object_notify (G_OBJECT (animation), "loop"); g_object_notify (G_OBJECT (animation), "loop");
@ -1141,22 +1128,13 @@ clutter_animation_set_loop (ClutterAnimation *animation,
gboolean gboolean
clutter_animation_get_loop (ClutterAnimation *animation) clutter_animation_get_loop (ClutterAnimation *animation)
{ {
ClutterAnimationPrivate *priv; ClutterTimeline *timeline;
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE); g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE);
priv = animation->priv; timeline = clutter_animation_get_timeline_internal (animation);
if (priv->alpha != NULL)
{
ClutterTimeline *timeline;
timeline = clutter_alpha_get_timeline (priv->alpha);
if (timeline != NULL)
return clutter_timeline_get_loop (timeline); return clutter_timeline_get_loop (timeline);
}
return priv->loop;
} }
/** /**
@ -1172,39 +1150,23 @@ clutter_animation_get_loop (ClutterAnimation *animation)
guint guint
clutter_animation_get_duration (ClutterAnimation *animation) clutter_animation_get_duration (ClutterAnimation *animation)
{ {
ClutterAnimationPrivate *priv; ClutterTimeline *timeline;
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), 0); g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), 0);
priv = animation->priv; timeline = clutter_animation_get_timeline_internal (animation);
if (priv->alpha != NULL)
{
ClutterTimeline *timeline;
timeline = clutter_alpha_get_timeline (priv->alpha);
if (timeline != NULL)
return clutter_timeline_get_duration (timeline); return clutter_timeline_get_duration (timeline);
}
return priv->duration;
} }
/** /**
* clutter_animation_set_timeline: * clutter_animation_set_timeline:
* @animation: a #ClutterAnimation * @animation: a #ClutterAnimation
* @timeline: a #ClutterTimeline or %NULL * @timeline: a #ClutterTimeline, or %NULL to unset the
* current #ClutterTimeline
* *
* Sets the #ClutterTimeline used by @animation. * Sets the #ClutterTimeline used by @animation.
* *
* The #ClutterAnimation:duration and #ClutterAnimation:loop properties
* will be set using the corresponding #ClutterTimeline properties as a
* side effect.
*
* If @timeline is %NULL a new #ClutterTimeline will be constructed
* using the current values of the #ClutterAnimation:duration and
* #ClutterAnimation:loop properties.
*
* Since: 1.0 * Since: 1.0
*/ */
void void
@ -1220,41 +1182,33 @@ clutter_animation_set_timeline (ClutterAnimation *animation,
priv = animation->priv; priv = animation->priv;
cur_timeline = clutter_animation_get_timeline_internal (animation); if (priv->alpha != NULL)
cur_timeline = clutter_alpha_get_timeline (priv->alpha);
else
cur_timeline = NULL;
if (cur_timeline == timeline) if (cur_timeline == timeline)
return; return;
g_object_freeze_notify (G_OBJECT (animation)); g_object_freeze_notify (G_OBJECT (animation));
if (priv->timeline_started_id != 0) if (cur_timeline != NULL && priv->timeline_started_id != 0)
g_signal_handler_disconnect (cur_timeline, priv->timeline_started_id); g_signal_handler_disconnect (cur_timeline, priv->timeline_started_id);
if (priv->timeline_completed_id != 0) if (cur_timeline != NULL && priv->timeline_completed_id != 0)
g_signal_handler_disconnect (cur_timeline, priv->timeline_completed_id); g_signal_handler_disconnect (cur_timeline, priv->timeline_completed_id);
priv->timeline_started_id = 0; priv->timeline_started_id = 0;
priv->timeline_completed_id = 0; priv->timeline_completed_id = 0;
if (timeline == NULL)
{
timeline = g_object_new (CLUTTER_TYPE_TIMELINE,
"duration", priv->duration,
"loop", priv->loop,
NULL);
}
else
{
priv->duration = clutter_timeline_get_duration (timeline);
g_object_notify (G_OBJECT (animation), "duration");
priv->loop = clutter_timeline_get_loop (timeline);
g_object_notify (G_OBJECT (animation), "loop");
}
alpha = clutter_animation_get_alpha_internal (animation); alpha = clutter_animation_get_alpha_internal (animation);
clutter_alpha_set_timeline (alpha, timeline); clutter_alpha_set_timeline (alpha, timeline);
g_object_notify (G_OBJECT (animation), "timeline"); g_object_notify (G_OBJECT (animation), "timeline");
g_object_notify (G_OBJECT (animation), "duration");
g_object_notify (G_OBJECT (animation), "loop");
if (timeline)
{
priv->timeline_started_id = priv->timeline_started_id =
g_signal_connect (timeline, "started", g_signal_connect (timeline, "started",
G_CALLBACK (on_timeline_started), G_CALLBACK (on_timeline_started),
@ -1263,6 +1217,7 @@ clutter_animation_set_timeline (ClutterAnimation *animation,
g_signal_connect (timeline, "completed", g_signal_connect (timeline, "completed",
G_CALLBACK (on_timeline_completed), G_CALLBACK (on_timeline_completed),
animation); animation);
}
g_object_thaw_notify (G_OBJECT (animation)); g_object_thaw_notify (G_OBJECT (animation));
} }
@ -1288,14 +1243,10 @@ clutter_animation_get_timeline (ClutterAnimation *animation)
/** /**
* clutter_animation_set_alpha: * clutter_animation_set_alpha:
* @animation: a #ClutterAnimation * @animation: a #ClutterAnimation
* @alpha: a #ClutterAlpha, or %NULL * @alpha: a #ClutterAlpha, or %NULL to unset the current #ClutterAlpha
* *
* Sets @alpha as the #ClutterAlpha used by @animation. * Sets @alpha as the #ClutterAlpha used by @animation.
* *
* If @alpha is %NULL, a new #ClutterAlpha will be constructed from
* the current value of the #ClutterAnimation:mode and the current
* #ClutterAnimation:timeline.
*
* If @alpha is not %NULL, the #ClutterAnimation will take ownership * If @alpha is not %NULL, the #ClutterAnimation will take ownership
* of the #ClutterAlpha instance. * of the #ClutterAlpha instance.
* *
@ -1316,45 +1267,22 @@ clutter_animation_set_alpha (ClutterAnimation *animation,
if (priv->alpha == alpha) if (priv->alpha == alpha)
return; return;
/* retrieve the old timeline, if any */
if (priv->alpha != NULL) if (priv->alpha != NULL)
{
timeline = clutter_alpha_get_timeline (priv->alpha); timeline = clutter_alpha_get_timeline (priv->alpha);
if (timeline != NULL)
g_object_ref (timeline);
}
else else
timeline = NULL; timeline = NULL;
if (alpha == NULL) /* disconnect the old timeline first */
if (timeline != NULL && priv->timeline_started_id != 0)
{ {
/* this will create a new alpha */
alpha = clutter_animation_get_alpha_internal (animation);
/* if we had a timeline before, we should have the same timeline now */
if (timeline != NULL)
{
clutter_alpha_set_timeline (alpha, timeline);
g_object_unref (timeline);
}
else
clutter_animation_create_timeline (animation);
}
else
{
if (timeline != NULL)
{
/* if we had a timeline before then we need to disconnect
* the signal handlers from it
*/
if (priv->timeline_started_id != 0)
g_signal_handler_disconnect (timeline, priv->timeline_started_id); g_signal_handler_disconnect (timeline, priv->timeline_started_id);
priv->timeline_started_id = 0;
}
if (priv->timeline_completed_id != 0) if (timeline != NULL && priv->timeline_completed_id != 0)
{
g_signal_handler_disconnect (timeline, priv->timeline_completed_id); g_signal_handler_disconnect (timeline, priv->timeline_completed_id);
priv->timeline_completed_id = 0;
/* we don't need this timeline anymore */
g_object_unref (timeline);
} }
/* then we need to disconnect the signal handler from the old alpha */ /* then we need to disconnect the signal handler from the old alpha */
@ -1366,23 +1294,24 @@ clutter_animation_set_alpha (ClutterAnimation *animation,
if (priv->alpha != NULL) if (priv->alpha != NULL)
{ {
/* this will take care of any reference we hold on the timeline */
g_object_unref (priv->alpha); g_object_unref (priv->alpha);
priv->alpha = NULL; priv->alpha = NULL;
} }
if (alpha == NULL)
return;
priv->alpha = g_object_ref_sink (alpha); priv->alpha = g_object_ref_sink (alpha);
priv->alpha_notify_id = priv->alpha_notify_id =
g_signal_connect (priv->alpha, "notify::value", g_signal_connect (priv->alpha, "notify::value",
G_CALLBACK (on_alpha_notify), G_CALLBACK (on_alpha_notify),
animation); animation);
/* if the alpha has a timeline then we use it */ /* if the alpha has a timeline then we use it, otherwise we create one */
timeline = clutter_alpha_get_timeline (priv->alpha); timeline = clutter_alpha_get_timeline (priv->alpha);
if (timeline != NULL) if (timeline != NULL)
{ {
priv->duration = clutter_timeline_get_duration (timeline);
priv->loop = clutter_timeline_get_loop (timeline);
priv->timeline_started_id = priv->timeline_started_id =
g_signal_connect (timeline, "started", g_signal_connect (timeline, "started",
G_CALLBACK (on_timeline_started), G_CALLBACK (on_timeline_started),
@ -1393,8 +1322,7 @@ clutter_animation_set_alpha (ClutterAnimation *animation,
animation); animation);
} }
else else
clutter_animation_create_timeline (animation); timeline = clutter_animation_get_timeline_internal (animation);
}
/* emit all relevant notifications */ /* emit all relevant notifications */
g_object_notify (G_OBJECT (animation), "mode"); g_object_notify (G_OBJECT (animation), "mode");
@ -1419,7 +1347,7 @@ clutter_animation_get_alpha (ClutterAnimation *animation)
{ {
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL);
return animation->priv->alpha; return clutter_animation_get_alpha_internal (animation);
} }
/** /**
@ -1722,6 +1650,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor,
if (animation == NULL) if (animation == NULL)
{ {
animation = clutter_animation_new (); animation = clutter_animation_new ();
clutter_animation_set_object (animation, G_OBJECT (actor));
g_signal_connect (animation, "completed", g_signal_connect (animation, "completed",
G_CALLBACK (on_animation_completed), G_CALLBACK (on_animation_completed),
@ -1733,7 +1662,6 @@ clutter_actor_animate_with_alpha (ClutterActor *actor,
CLUTTER_NOTE (ANIMATION, "Reusing Animation [%p]", animation); CLUTTER_NOTE (ANIMATION, "Reusing Animation [%p]", animation);
clutter_animation_set_alpha (animation, alpha); clutter_animation_set_alpha (animation, alpha);
clutter_animation_set_object (animation, G_OBJECT (actor));
va_start (args, first_property_name); va_start (args, first_property_name);
clutter_animation_setup_valist (animation, first_property_name, args); clutter_animation_setup_valist (animation, first_property_name, args);
@ -1786,6 +1714,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor,
if (animation == NULL) if (animation == NULL)
{ {
animation = clutter_animation_new (); animation = clutter_animation_new ();
clutter_animation_set_object (animation, G_OBJECT (actor));
g_signal_connect (animation, "completed", g_signal_connect (animation, "completed",
G_CALLBACK (on_animation_completed), G_CALLBACK (on_animation_completed),
@ -1796,9 +1725,8 @@ clutter_actor_animate_with_timeline (ClutterActor *actor,
else else
CLUTTER_NOTE (ANIMATION, "Reusing Animation [%p]", animation); CLUTTER_NOTE (ANIMATION, "Reusing Animation [%p]", animation);
clutter_animation_set_timeline (animation, timeline);
clutter_animation_set_mode (animation, mode); clutter_animation_set_mode (animation, mode);
clutter_animation_set_object (animation, G_OBJECT (actor)); clutter_animation_set_timeline (animation, timeline);
va_start (args, first_property_name); va_start (args, first_property_name);
clutter_animation_setup_valist (animation, first_property_name, args); clutter_animation_setup_valist (animation, first_property_name, args);
@ -2130,6 +2058,7 @@ clutter_actor_animate_with_timelinev (ClutterActor *actor,
if (animation == NULL) if (animation == NULL)
{ {
animation = clutter_animation_new (); animation = clutter_animation_new ();
clutter_animation_set_object (animation, G_OBJECT (actor));
g_signal_connect (animation, "completed", g_signal_connect (animation, "completed",
G_CALLBACK (on_animation_completed), G_CALLBACK (on_animation_completed),
@ -2140,9 +2069,8 @@ clutter_actor_animate_with_timelinev (ClutterActor *actor,
else else
CLUTTER_NOTE (ANIMATION, "Reusing Animation [%p]", animation); CLUTTER_NOTE (ANIMATION, "Reusing Animation [%p]", animation);
clutter_animation_set_timeline (animation, timeline);
clutter_animation_set_mode (animation, mode); clutter_animation_set_mode (animation, mode);
clutter_animation_set_object (animation, G_OBJECT (actor)); clutter_animation_set_timeline (animation, timeline);
clutter_animation_setupv (animation, n_properties, properties, values); clutter_animation_setupv (animation, n_properties, properties, values);
clutter_animation_start (animation); clutter_animation_start (animation);
@ -2206,6 +2134,7 @@ clutter_actor_animate_with_alphav (ClutterActor *actor,
if (animation == NULL) if (animation == NULL)
{ {
animation = clutter_animation_new (); animation = clutter_animation_new ();
clutter_animation_set_object (animation, G_OBJECT (actor));
g_signal_connect (animation, "completed", g_signal_connect (animation, "completed",
G_CALLBACK (on_animation_completed), G_CALLBACK (on_animation_completed),
@ -2217,7 +2146,6 @@ clutter_actor_animate_with_alphav (ClutterActor *actor,
CLUTTER_NOTE (ANIMATION, "Reusing Animation [%p]", animation); CLUTTER_NOTE (ANIMATION, "Reusing Animation [%p]", animation);
clutter_animation_set_alpha (animation, alpha); clutter_animation_set_alpha (animation, alpha);
clutter_animation_set_object (animation, G_OBJECT (actor));
clutter_animation_setupv (animation, n_properties, properties, values); clutter_animation_setupv (animation, n_properties, properties, values);
clutter_animation_start (animation); clutter_animation_start (animation);