1
0
Fork 0

[animation] Extend ClutterAnimation support to all objects

Instead of limiting the use of ClutterAnimation to ClutterActor
instances, relax the constraint to include all GObject classes.

ClutterAnimation is not using actor-specific API, since it is
only using properties.

The only actor-based API is the clutter_actor_animate() family
of functions.
This commit is contained in:
Emmanuele Bassi 2009-01-08 13:13:39 +00:00
parent 28b0f432b7
commit 068ba1caf0
2 changed files with 74 additions and 80 deletions

View file

@ -27,12 +27,12 @@
* @short_description: Simple implicit animations
*
* #ClutterAnimation is an object providing simple, implicit animations
* for #ClutterActor<!-- -->s.
* for #GObject<!-- -->s.
*
* #ClutterAnimation instances will bind a #GObject property belonging
* to a #ClutterActor to a #ClutterInterval, and will then use a
* #ClutterTimeline to interpolate the property between the initial
* and final values of the interval.
* to a #GObject to a #ClutterInterval, and will then use a #ClutterTimeline
* to interpolate the property between the initial and final values of the
* interval.
*
* For convenience, it is possible to use the clutter_actor_animate()
* function call which will take care of setting up and tearing down
@ -60,7 +60,7 @@ enum
{
PROP_0,
PROP_ACTOR,
PROP_OBJECT,
PROP_MODE,
PROP_DURATION,
PROP_LOOP,
@ -79,7 +79,7 @@ enum
struct _ClutterAnimationPrivate
{
ClutterActor *actor;
GObject *object;
GHashTable *properties;
@ -96,7 +96,7 @@ struct _ClutterAnimationPrivate
static guint animation_signals[LAST_SIGNAL] = { 0, };
static GQuark quark_actor_animation = 0;
static GQuark quark_object_animation = 0;
G_DEFINE_TYPE (ClutterAnimation, clutter_animation, G_TYPE_INITIALLY_UNOWNED);
@ -118,16 +118,14 @@ clutter_animation_dispose (GObject *gobject)
{
ClutterAnimationPrivate *priv = CLUTTER_ANIMATION (gobject)->priv;
if (priv->actor)
if (priv->object)
{
g_object_weak_unref (G_OBJECT (gobject),
on_animation_weak_notify,
priv->actor);
g_object_set_qdata (G_OBJECT (priv->actor),
quark_actor_animation,
NULL);
g_object_unref (priv->actor);
priv->actor = NULL;
priv->object);
g_object_set_qdata (priv->object, quark_object_animation, NULL);
g_object_unref (priv->object);
priv->object = NULL;
}
if (priv->timeline)
@ -168,8 +166,8 @@ clutter_animation_set_property (GObject *gobject,
switch (prop_id)
{
case PROP_ACTOR:
clutter_animation_set_actor (animation, g_value_get_object (value));
case PROP_OBJECT:
clutter_animation_set_object (animation, g_value_get_object (value));
break;
case PROP_MODE:
@ -208,8 +206,8 @@ clutter_animation_get_property (GObject *gobject,
switch (prop_id)
{
case PROP_ACTOR:
g_value_set_object (value, priv->actor);
case PROP_OBJECT:
g_value_set_object (value, priv->object);
break;
case PROP_MODE:
@ -253,7 +251,7 @@ clutter_animation_class_init (ClutterAnimationClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
quark_actor_animation =
quark_object_animation =
g_quark_from_static_string ("clutter-actor-animation");
g_type_class_add_private (klass, sizeof (ClutterAnimationPrivate));
@ -266,18 +264,18 @@ clutter_animation_class_init (ClutterAnimationClass *klass)
gobject_class->finalize = clutter_animation_finalize;
/**
* ClutterAnimation:actor:
* ClutterAnimation:objct:
*
* The actor to which the animation applies.
* The #GObject to which the animation applies.
*
* Since: 1.0
*/
pspec = g_param_spec_object ("actor",
"Actor",
"Actor to which the animation applies",
CLUTTER_TYPE_ACTOR,
pspec = g_param_spec_object ("object",
"Object",
"Object to which the animation applies",
G_TYPE_OBJECT,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_ACTOR, pspec);
g_object_class_install_property (gobject_class, PROP_OBJECT, pspec);
/**
* ClutterAnimation:mode:
@ -427,7 +425,7 @@ clutter_animation_update_property_internal (ClutterAnimation *animation,
* @property_name: the property to control
* @interval: a #ClutterInterval
*
* Binds @interval to the @property_name of the #ClutterActor
* Binds @interval to the @property_name of the #GObject
* attached to @animation. The #ClutterAnimation will take
* ownership of the passed #ClutterInterval.
*
@ -451,10 +449,10 @@ clutter_animation_bind_property (ClutterAnimation *animation,
priv = animation->priv;
if (G_UNLIKELY (!priv->actor))
if (G_UNLIKELY (!priv->object))
{
g_warning ("Cannot bind property `%s': the animation has no "
"actor set. You need to call clutter_animation_set_actor() "
"object set. You need to call clutter_animation_set_object() "
"first to be able to bind a property",
property_name);
return;
@ -468,14 +466,14 @@ clutter_animation_bind_property (ClutterAnimation *animation,
return;
}
klass = G_OBJECT_GET_CLASS (priv->actor);
klass = G_OBJECT_GET_CLASS (priv->object);
pspec = g_object_class_find_property (klass, property_name);
if (!pspec)
{
g_warning ("Cannot bind property `%s': actors of type `%s' have "
g_warning ("Cannot bind property `%s': objects of type `%s' have "
"no such property",
property_name,
g_type_name (G_OBJECT_TYPE (priv->actor)));
g_type_name (G_OBJECT_TYPE (priv->object)));
return;
}
@ -592,14 +590,14 @@ clutter_animation_update_property (ClutterAnimation *animation,
return;
}
klass = G_OBJECT_GET_CLASS (priv->actor);
klass = G_OBJECT_GET_CLASS (priv->object);
pspec = g_object_class_find_property (klass, property_name);
if (!pspec)
{
g_warning ("Cannot bind property `%s': actors of type `%s' have "
g_warning ("Cannot bind property `%s': objects of type `%s' have "
"no such property",
property_name,
g_type_name (G_OBJECT_TYPE (priv->actor)));
g_type_name (G_OBJECT_TYPE (priv->object)));
return;
}
@ -667,7 +665,7 @@ on_alpha_notify (GObject *gobject,
alpha_value = clutter_alpha_get_alpha (CLUTTER_ALPHA (gobject));
g_object_freeze_notify (G_OBJECT (priv->actor));
g_object_freeze_notify (priv->object);
properties = g_hash_table_get_keys (priv->properties);
for (p = properties; p != NULL; p = p->next)
@ -685,14 +683,14 @@ on_alpha_notify (GObject *gobject,
factor = (gdouble) alpha_value / CLUTTER_ALPHA_MAX_ALPHA;
if (clutter_interval_compute_value (interval, factor, &value))
g_object_set_property (G_OBJECT (priv->actor), p_name, &value);
g_object_set_property (priv->object, p_name, &value);
g_value_unset (&value);
}
g_list_free (properties);
g_object_thaw_notify (G_OBJECT (priv->actor));
g_object_thaw_notify (priv->object);
}
/*
@ -709,7 +707,7 @@ on_animation_weak_notify (gpointer data,
clutter_actor_get_gid (CLUTTER_ACTOR (actor)),
actor);
g_object_set_qdata (actor, quark_actor_animation, NULL);
g_object_set_qdata (actor, quark_object_animation, NULL);
}
ClutterAnimation *
@ -719,66 +717,64 @@ clutter_animation_new (void)
}
/**
* clutter_animation_set_actor:
* clutter_animation_set_object:
* @animation: a #ClutterAnimation
* @actor: a #ClutterActor
* @object: a #GObject
*
* Attaches @animation to @actor. The #ClutterAnimation will take a
* reference on @actor.
* Attaches @animation to @object. The #ClutterAnimation will take a
* reference on @object.
*
* Since: 1.0
*/
void
clutter_animation_set_actor (ClutterAnimation *animation,
ClutterActor *actor)
clutter_animation_set_object (ClutterAnimation *animation,
GObject *object)
{
ClutterAnimationPrivate *priv;
g_return_if_fail (CLUTTER_IS_ANIMATION (animation));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_return_if_fail (G_IS_OBJECT (object));
priv = animation->priv;
g_object_ref (actor);
g_object_ref (object);
if (priv->actor)
if (priv->object)
{
g_object_weak_unref (G_OBJECT (animation),
on_animation_weak_notify,
priv->actor);
g_object_set_qdata (G_OBJECT (priv->actor),
quark_actor_animation,
NULL);
g_object_unref (priv->actor);
priv->object);
g_object_set_qdata (priv->object, quark_object_animation, NULL);
g_object_unref (priv->object);
}
priv->actor = actor;
priv->object = object;
g_object_weak_ref (G_OBJECT (animation),
on_animation_weak_notify,
priv->actor);
g_object_set_qdata (G_OBJECT (priv->actor),
quark_actor_animation,
priv->object);
g_object_set_qdata (G_OBJECT (priv->object),
quark_object_animation,
animation);
g_object_notify (G_OBJECT (animation), "actor");
g_object_notify (G_OBJECT (animation), "object");
}
/**
* clutter_animation_get_actor:
* clutter_animation_get_object:
* @animation: a #ClutterAnimation
*
* Retrieves the #ClutterActor attached to @animation.
* Retrieves the #GObject attached to @animation.
*
* Return value: a #ClutterActor
* Return value: a #GObject
*
* Since: 1.0
*/
ClutterActor *
clutter_animation_get_actor (ClutterAnimation *animation)
GObject *
clutter_animation_get_object (ClutterAnimation *animation)
{
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL);
return animation->priv->actor;
return animation->priv->object;
}
static inline void
@ -1125,7 +1121,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
GObjectClass *klass;
const gchar *property_name;
klass = G_OBJECT_GET_CLASS (priv->actor);
klass = G_OBJECT_GET_CLASS (priv->object);
property_name = first_property_name;
while (property_name != NULL)
@ -1145,10 +1141,10 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
pspec = g_object_class_find_property (klass, property_name);
if (!pspec)
{
g_warning ("Cannot bind property `%s': actors of type `%s' do "
g_warning ("Cannot bind property `%s': objects of type `%s' do "
"not have this property",
property_name,
g_type_name (G_OBJECT_TYPE (priv->actor)));
g_type_name (G_OBJECT_TYPE (priv->object)));
break;
}
@ -1178,9 +1174,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
GValue initial = { 0, };
g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_object_get_property (G_OBJECT (priv->actor),
property_name,
&initial);
g_object_get_property (priv->object, property_name, &initial);
interval =
clutter_interval_new_with_values (G_PARAM_SPEC_VALUE_TYPE (pspec),
@ -1199,7 +1193,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
g_value_unset (&initial);
}
else
g_object_set_property (G_OBJECT (priv->actor), property_name, &final);
g_object_set_property (priv->object, property_name, &final);
g_value_unset (&final);
@ -1254,7 +1248,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor,
return NULL;
}
animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation);
animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation);
if (G_LIKELY (!animation))
{
animation = clutter_animation_new ();
@ -1265,7 +1259,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor,
clutter_animation_set_timeline (animation, timeline);
clutter_animation_set_alpha (animation, alpha);
clutter_animation_set_actor (animation, actor);
clutter_animation_set_object (animation, G_OBJECT (actor));
va_start (args, first_property_name);
clutter_animation_setup_valist (animation, first_property_name, args);
@ -1311,7 +1305,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor,
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL);
g_return_val_if_fail (first_property_name != NULL, NULL);
animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation);
animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation);
if (G_LIKELY (!animation))
{
animation = clutter_animation_new ();
@ -1323,7 +1317,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor,
clutter_animation_set_timeline (animation, timeline);
clutter_animation_set_alpha (animation, NULL);
clutter_animation_set_mode (animation, mode);
clutter_animation_set_actor (animation, actor);
clutter_animation_set_object (animation, G_OBJECT (actor));
va_start (args, first_property_name);
clutter_animation_setup_valist (animation, first_property_name, args);
@ -1406,7 +1400,7 @@ clutter_actor_animate (ClutterActor *actor,
g_return_val_if_fail (duration > 0, NULL);
g_return_val_if_fail (first_property_name != NULL, NULL);
animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation);
animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation);
if (G_LIKELY (!animation))
{
/* if there is no animation already attached to the actor,
@ -1416,7 +1410,7 @@ clutter_actor_animate (ClutterActor *actor,
animation = clutter_animation_new ();
clutter_animation_set_timeline (animation, NULL);
clutter_animation_set_alpha (animation, NULL);
clutter_animation_set_actor (animation, actor);
clutter_animation_set_object (animation, G_OBJECT (actor));
CLUTTER_NOTE (ANIMATION, "Created new Animation [%p]", animation);
}

View file

@ -97,9 +97,9 @@ GType clutter_animation_get_type (void) G_GNUC_CONST;
ClutterAnimation * clutter_animation_new (void);
void clutter_animation_set_actor (ClutterAnimation *animation,
ClutterActor *actor);
ClutterActor * clutter_animation_get_actor (ClutterAnimation *animation);
void clutter_animation_set_object (ClutterAnimation *animation,
GObject *object);
GObject * clutter_animation_get_object (ClutterAnimation *animation);
void clutter_animation_set_mode (ClutterAnimation *animation,
ClutterAnimationMode mode);
ClutterAnimationMode clutter_animation_get_mode (ClutterAnimation *animation);