2007-07-22 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/clutter-behaviour.[ch]: Rename ClutterBehaviour::apply
	and ClutterBehaviour::remove to ClutterBehaviour::applied and
	ClutterBehaviour::removed respectively, and emit them when the
	behaviour has been applied (or does no longer apply) to an actor.

	(clutter_behaviour_dispose), (clutter_behaviour_finalize),
	(clutter_behaviour_class_init): Move the actor removal to the
	::dispose virtual function, and remove the ::finalize one;
	document the missing properties and signals.

	(clutter_behaviour_clear): Add function to clear a behaviour:
	every actor will be unreffed and the ClutterBehaviour::removed
	signal will be emitted.
This commit is contained in:
Emmanuele Bassi 2007-07-22 22:30:47 +00:00
parent 9157740741
commit fe11263b84
3 changed files with 105 additions and 51 deletions

View File

@ -1,3 +1,19 @@
2007-07-22 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-behaviour.[ch]: Rename ClutterBehaviour::apply
and ClutterBehaviour::remove to ClutterBehaviour::applied and
ClutterBehaviour::removed respectively, and emit them when the
behaviour has been applied (or does no longer apply) to an actor.
(clutter_behaviour_dispose), (clutter_behaviour_finalize),
(clutter_behaviour_class_init): Move the actor removal to the
::dispose virtual function, and remove the ::finalize one;
document the missing properties and signals.
(clutter_behaviour_clear): Add function to clear a behaviour:
every actor will be unreffed and the ClutterBehaviour::removed
signal will be emitted.
2007-07-21 Matthew Allum <mallum@openedhand.com> 2007-07-21 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-event.c: * clutter/clutter-event.c:

View File

@ -158,8 +158,8 @@ enum
}; };
enum { enum {
APPLY, APPLIED,
REMOVE, REMOVED,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -171,17 +171,14 @@ static guint behave_signals[LAST_SIGNAL] = { 0 };
ClutterBehaviourPrivate)) ClutterBehaviourPrivate))
static void static void
clutter_behaviour_finalize (GObject *object) clutter_behaviour_dispose (GObject *gobject)
{ {
ClutterBehaviour *self = CLUTTER_BEHAVIOUR (object); ClutterBehaviour *self = CLUTTER_BEHAVIOUR (gobject);
clutter_behaviour_set_alpha (self, NULL); clutter_behaviour_set_alpha (self, NULL);
clutter_behaviour_clear (self);
/* FIXME: Should we also emit remove signals here ? */ G_OBJECT_CLASS (clutter_behaviour_parent_class)->dispose (gobject);
g_slist_foreach (self->priv->actors, (GFunc) g_object_unref, NULL);
g_slist_free (self->priv->actors);
G_OBJECT_CLASS (clutter_behaviour_parent_class)->finalize (object);
} }
static void static void
@ -190,9 +187,7 @@ clutter_behaviour_set_property (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
ClutterBehaviour *behaviour; ClutterBehaviour *behaviour = CLUTTER_BEHAVIOUR (object);
behaviour = CLUTTER_BEHAVIOUR(object);
switch (prop_id) switch (prop_id)
{ {
@ -211,11 +206,8 @@ clutter_behaviour_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
ClutterBehaviour *behaviour; ClutterBehaviour *behaviour = CLUTTER_BEHAVIOUR (object);
ClutterBehaviourPrivate *priv; ClutterBehaviourPrivate *priv = behaviour->priv;
behaviour = CLUTTER_BEHAVIOUR(object);
priv = CLUTTER_BEHAVIOUR_GET_PRIVATE(behaviour);
switch (prop_id) switch (prop_id)
{ {
@ -241,23 +233,32 @@ clutter_behaviour_class_init (ClutterBehaviourClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = clutter_behaviour_finalize; object_class->dispose = clutter_behaviour_dispose;
object_class->set_property = clutter_behaviour_set_property; object_class->set_property = clutter_behaviour_set_property;
object_class->get_property = clutter_behaviour_get_property; object_class->get_property = clutter_behaviour_get_property;
/**
* ClutterBehaviour:alpha:
*
* The #ClutterAlpha object used to drive this behaviour. A #ClutterAlpha
* object binds a #ClutterTimeline and a function which computes a value
* (the "alpha") depending on the time. Each time the alpha value changes
* the alpha-notify virtual function is called.
*
* Since: 0.2
*/
g_object_class_install_property (object_class, g_object_class_install_property (object_class,
PROP_ALPHA, PROP_ALPHA,
g_param_spec_object ("alpha", g_param_spec_object ("alpha",
"Alpha", "Alpha",
"Alpha Object to drive the behaviour", "Alpha Object to drive the behaviour",
CLUTTER_TYPE_ALPHA, CLUTTER_TYPE_ALPHA,
G_PARAM_CONSTRUCT |
CLUTTER_PARAM_READWRITE)); CLUTTER_PARAM_READWRITE));
klass->alpha_notify = clutter_behaviour_alpha_notify_unimplemented; klass->alpha_notify = clutter_behaviour_alpha_notify_unimplemented;
/** /**
* ClutterBehaviour::apply: * ClutterBehaviour::applied:
* @behaviour: the #ClutterBehaviour that received the signal * @behaviour: the #ClutterBehaviour that received the signal
* @actor: the actor the behaviour was applied to. * @actor: the actor the behaviour was applied to.
* *
@ -266,29 +267,29 @@ clutter_behaviour_class_init (ClutterBehaviourClass *klass)
* *
* Since: 0.4 * Since: 0.4
*/ */
behave_signals[APPLY] = behave_signals[APPLIED] =
g_signal_new ("apply", g_signal_new ("applied",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterBehaviourClass, apply), G_STRUCT_OFFSET (ClutterBehaviourClass, applied),
NULL, NULL, NULL, NULL,
clutter_marshal_VOID__OBJECT, clutter_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_NONE, 1,
CLUTTER_TYPE_ACTOR); CLUTTER_TYPE_ACTOR);
/** /**
* ClutterBehaviour::remove: * ClutterBehaviour::removed:
* @behaviour: the #ClutterBehaviour that received the signal * @behaviour: the #ClutterBehaviour that received the signal
* @actor: the actor added to the group * @actor: the removed actor
* *
* The ::remove signal is emitted each time an actor has been removed * The ::removed signal is emitted each time a behaviour is not applied
* from the group * to an actor anymore.
* *
*/ */
behave_signals[REMOVE] = behave_signals[REMOVED] =
g_signal_new ("remove", g_signal_new ("removed",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterBehaviourClass, remove), G_STRUCT_OFFSET (ClutterBehaviourClass, removed),
NULL, NULL, NULL, NULL,
clutter_marshal_VOID__OBJECT, clutter_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_NONE, 1,
@ -320,10 +321,14 @@ void
clutter_behaviour_apply (ClutterBehaviour *behave, clutter_behaviour_apply (ClutterBehaviour *behave,
ClutterActor *actor) ClutterActor *actor)
{ {
ClutterBehaviourPrivate *priv;
g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave));
g_return_if_fail (CLUTTER_IS_ACTOR (actor)); g_return_if_fail (CLUTTER_IS_ACTOR (actor));
if (g_slist_find (behave->priv->actors, actor)) priv = behave->priv;
if (g_slist_find (priv->actors, actor))
{ {
g_warning ("The behaviour of type %s already applies " g_warning ("The behaviour of type %s already applies "
"to the actor of type %s", "to the actor of type %s",
@ -332,11 +337,9 @@ clutter_behaviour_apply (ClutterBehaviour *behave,
return; return;
} }
g_object_ref (actor); priv->actors = g_slist_prepend (priv->actors, g_object_ref (actor));
g_signal_emit (behave, behave_signals[APPLY], 0, actor); g_signal_emit (behave, behave_signals[APPLIED], 0, actor);
behave->priv->actors = g_slist_prepend (behave->priv->actors, actor);
} }
/** /**
@ -348,7 +351,7 @@ clutter_behaviour_apply (ClutterBehaviour *behave,
* *
* Return value: TRUE if actor has behaviour. FALSE otherwise. * Return value: TRUE if actor has behaviour. FALSE otherwise.
* *
* Since: 0.3 * Since: 0.4
*/ */
gboolean gboolean
clutter_behaviour_is_applied (ClutterBehaviour *behave, clutter_behaviour_is_applied (ClutterBehaviour *behave,
@ -374,10 +377,14 @@ void
clutter_behaviour_remove (ClutterBehaviour *behave, clutter_behaviour_remove (ClutterBehaviour *behave,
ClutterActor *actor) ClutterActor *actor)
{ {
ClutterBehaviourPrivate *priv;
g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave));
g_return_if_fail (CLUTTER_IS_ACTOR (actor)); g_return_if_fail (CLUTTER_IS_ACTOR (actor));
if (!g_slist_find (behave->priv->actors, actor)) priv = behave->priv;
if (!g_slist_find (priv->actors, actor))
{ {
g_warning ("The behaviour of type %s is not applied " g_warning ("The behaviour of type %s is not applied "
"to the actor of type %s", "to the actor of type %s",
@ -386,11 +393,11 @@ clutter_behaviour_remove (ClutterBehaviour *behave,
return; return;
} }
priv->actors = g_slist_remove (priv->actors, actor);
g_signal_emit (behave, behave_signals[REMOVED], 0, actor);
g_object_unref (actor); g_object_unref (actor);
g_signal_emit (behave, behave_signals[REMOVE], 0, actor);
behave->priv->actors = g_slist_remove (behave->priv->actors, actor);
} }
/** /**
@ -567,7 +574,7 @@ clutter_behaviour_set_alpha (ClutterBehaviour *behave,
* @behave: a #ClutterBehaviour * @behave: a #ClutterBehaviour
* *
* Retrieves all the actors to which @behave applies. It is not recommended * Retrieves all the actors to which @behave applies. It is not recommended
* derived classes use this in there alpha notify method but use * for derived classes to use this in there alpha notify method but use
* #clutter_behaviour_actors_foreach as it avoids alot of needless allocations. * #clutter_behaviour_actors_foreach as it avoids alot of needless allocations.
* *
* Return value: a list of actors. You should free the returned list * Return value: a list of actors. You should free the returned list
@ -578,13 +585,44 @@ clutter_behaviour_set_alpha (ClutterBehaviour *behave,
GSList * GSList *
clutter_behaviour_get_actors (ClutterBehaviour *behave) clutter_behaviour_get_actors (ClutterBehaviour *behave)
{ {
ClutterBehaviourPrivate *priv;
GSList *retval, *l; GSList *retval, *l;
g_return_val_if_fail (CLUTTER_BEHAVIOUR (behave), NULL); g_return_val_if_fail (CLUTTER_BEHAVIOUR (behave), NULL);
priv = behave->priv;
retval = NULL; retval = NULL;
for (l = behave->priv->actors; l != NULL; l = l->next) for (l = priv->actors; l != NULL; l = l->next)
retval = g_slist_prepend (retval, l->data); retval = g_slist_prepend (retval, l->data);
return g_slist_reverse (retval); return retval;
}
/**
* clutter_behaviour_clear:
* @behave: a #ClutterBehaviour
*
* Removes every actor from the list that @behave holds.
*
* Since: 0.4
*/
void
clutter_behaviour_clear (ClutterBehaviour *behave)
{
ClutterBehaviourPrivate *priv;
GSList *l;
g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave));
priv = behave->priv;
for (l = priv->actors; l != NULL; l = l->next)
{
ClutterActor *actor = l->data;
g_signal_emit (behave, behave_signals[REMOVED], 0, actor);
g_object_unref (actor);
}
g_slist_free (priv->actors);
priv->actors = NULL;
} }

View File

@ -112,9 +112,9 @@ struct _ClutterBehaviourClass
void (*alpha_notify) (ClutterBehaviour *behave, void (*alpha_notify) (ClutterBehaviour *behave,
guint32 alpha_value); guint32 alpha_value);
void (*apply) (ClutterBehaviour *behave, void (*applied) (ClutterBehaviour *behave,
ClutterActor *actor); ClutterActor *actor);
void (*remove) (ClutterBehaviour *behave, void (*removed) (ClutterBehaviour *behave,
ClutterActor *actor); ClutterActor *actor);
/* padding, for future expansion */ /* padding, for future expansion */
@ -142,9 +142,9 @@ GSList * clutter_behaviour_get_actors (ClutterBehaviour *beh
ClutterAlpha *clutter_behaviour_get_alpha (ClutterBehaviour *behave); ClutterAlpha *clutter_behaviour_get_alpha (ClutterBehaviour *behave);
void clutter_behaviour_set_alpha (ClutterBehaviour *behave, void clutter_behaviour_set_alpha (ClutterBehaviour *behave,
ClutterAlpha *alpha); ClutterAlpha *alpha);
gboolean clutter_behaviour_is_applied (ClutterBehaviour *behave, gboolean clutter_behaviour_is_applied (ClutterBehaviour *behave,
ClutterActor *actor); ClutterActor *actor);
void clutter_behaviour_clear (ClutterBehaviour *behave);
G_END_DECLS G_END_DECLS