[clutter] actor: Add ::transition-stopped
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter] actor: Add ::transition-stopped
- Date: Thu, 26 Jul 2012 13:08:57 +0000 (UTC)
commit 28c2eeef951207f73f5c2584b3a471271ccdbdcf
Author: Emmanuele Bassi <ebassi gnome org>
Date: Sat Jul 21 12:49:53 2012 -0400
actor: Add ::transition-stopped
The ::transition-stopped signal can be used to get notification of the
end of a transition.
clutter/clutter-actor.c | 97 ++++++++++++++++++++++++++++++++++++------
clutter/clutter-marshal.list | 1 +
examples/basic-actor.c | 27 ++++++------
3 files changed, 99 insertions(+), 26 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 4699340..e135304 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -964,6 +964,7 @@ enum
ALLOCATION_CHANGED,
TRANSITIONS_COMPLETED,
TOUCH_EVENT,
+ TRANSITION_STOPPED,
LAST_SIGNAL
};
@@ -4449,8 +4450,6 @@ clutter_actor_set_rotation_angle (ClutterActor *self,
_clutter_actor_create_transition (self, pspec, *cur_angle_p, angle);
else
_clutter_actor_update_transition (self, pspec, angle);
-
- clutter_actor_queue_redraw (self);
}
/**
@@ -8015,6 +8014,32 @@ clutter_actor_class_init (ClutterActorClass *klass)
G_TYPE_NONE, 0);
/**
+ * ClutterActor::transition-stopped:
+ * @actor: a #ClutterActor
+ * @name: the name of the transition
+ * @is_finished: whether the transition was finished, or stopped
+ *
+ * The ::transition-stopped signal is emitted once a transition
+ * is stopped; a transition is stopped once it reached its total
+ * duration (including eventual repeats), it has been stopped
+ * using clutter_timeline_stop(), or it has been removed from the
+ * transitions applied on @actor, using clutter_actor_remove_transition().
+ *
+ * Since: 1.12
+ */
+ actor_signals[TRANSITION_STOPPED] =
+ g_signal_new (I_("transition-stopped"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
+ G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL,
+ _clutter_marshal_VOID__STRING_BOOLEAN,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN);
+
+ /**
* ClutterActor::touch-event:
* @actor: a #ClutterActor
*
@@ -18350,6 +18375,11 @@ on_transition_stopped (ClutterTransition *transition,
{
ClutterActor *actor = clos->actor;
ClutterAnimationInfo *info;
+ GQuark t_quark;
+ gchar *t_name;
+
+ if (clos->name == NULL)
+ return;
/* reset the caches used by animations */
clutter_actor_store_content_box (actor, NULL);
@@ -18359,6 +18389,9 @@ on_transition_stopped (ClutterTransition *transition,
info = _clutter_actor_get_animation_info (actor);
+ t_quark = g_quark_from_string (clos->name);
+ t_name = g_strdup (clos->name);
+
/* we take a reference here because removing the closure
* will release the reference on the transition, and we
* want the transition to survive the signal emission;
@@ -18368,6 +18401,16 @@ on_transition_stopped (ClutterTransition *transition,
g_object_ref (transition);
g_hash_table_remove (info->transitions, clos->name);
+ /* we emit the ::transition-stopped after removing the
+ * transition, so that we can chain up new transitions
+ * without interfering with the one that just finished
+ */
+ g_signal_emit (actor, actor_signals[TRANSITION_STOPPED], t_quark,
+ t_name,
+ TRUE);
+
+ g_free (t_name);
+
/* if it's the last transition then we clean up */
if (g_hash_table_size (info->transitions) == 0)
{
@@ -18481,6 +18524,9 @@ _clutter_actor_create_transition (ClutterActor *actor,
TransitionClosure *clos;
va_list var_args;
+ g_assert (pspec != NULL);
+ g_assert ((pspec->flags & CLUTTER_PARAM_ANIMATABLE) != 0);
+
info = _clutter_actor_get_animation_info (actor);
/* XXX - this will go away in 2.0
@@ -18559,9 +18605,6 @@ _clutter_actor_create_transition (ClutterActor *actor,
interval = clutter_interval_new_with_values (ptype, &initial, &final);
- g_value_unset (&initial);
- g_value_unset (&final);
-
res = clutter_property_transition_new (pspec->name);
clutter_transition_set_interval (res, interval);
@@ -18572,22 +18615,45 @@ _clutter_actor_create_transition (ClutterActor *actor,
clutter_timeline_set_duration (timeline, info->cur_state->easing_duration);
clutter_timeline_set_progress_mode (timeline, info->cur_state->easing_mode);
- CLUTTER_NOTE (ANIMATION,
- "Created transition for %s:%s (len:%u, mode:%s, delay:%u)",
- _clutter_actor_get_debug_name (actor),
- pspec->name,
- info->cur_state->easing_duration,
- clutter_get_easing_name_for_mode (info->cur_state->easing_mode),
- info->cur_state->easing_delay);
+#ifdef CLUTTER_ENABLE_DEBUG
+ {
+ gchar *initial_v, *final_v;
+
+ initial_v = g_strdup_value_contents (&initial);
+ final_v = g_strdup_value_contents (&final);
+
+ CLUTTER_NOTE (ANIMATION,
+ "Created transition for %s:%s "
+ "(len:%u, mode:%s, delay:%u) "
+ "initial:%s, final:%s",
+ _clutter_actor_get_debug_name (actor),
+ pspec->name,
+ info->cur_state->easing_duration,
+ clutter_get_easing_name_for_mode (info->cur_state->easing_mode),
+ info->cur_state->easing_delay,
+ initial_v, final_v);
+
+ g_free (initial_v);
+ g_free (final_v);
+ }
+#endif /* CLUTTER_ENABLE_DEBUG */
/* this will start the transition as well */
clutter_actor_add_transition (actor, pspec->name, res);
/* the actor now owns the transition */
g_object_unref (res);
+
+ g_value_unset (&initial);
+ g_value_unset (&final);
}
else
- res = clos->transition;
+ {
+ CLUTTER_NOTE (ANIMATION, "Existing transition for %s:%s",
+ _clutter_actor_get_debug_name (actor),
+ pspec->name);
+ res = clos->transition;
+ }
out:
if (call_restore)
@@ -18698,6 +18764,11 @@ clutter_actor_remove_transition (ClutterActor *self,
if (info->transitions == NULL)
return;
+ g_signal_emit (self, actor_signals[TRANSITION_STOPPED],
+ g_quark_from_string (name),
+ name,
+ FALSE);
+
g_hash_table_remove (info->transitions, name);
}
diff --git a/clutter/clutter-marshal.list b/clutter/clutter-marshal.list
index 557bf2a..efe8fb5 100644
--- a/clutter/clutter-marshal.list
+++ b/clutter/clutter-marshal.list
@@ -24,6 +24,7 @@ VOID:OBJECT,PARAM
VOID:OBJECT,POINTER
VOID:OBJECT,UINT
VOID:POINTER
+VOID:STRING,BOOLEAN
VOID:STRING,BOOLEAN,BOOLEAN
VOID:STRING,INT
VOID:UINT
diff --git a/examples/basic-actor.c b/examples/basic-actor.c
index 0ce3967..1bfb427 100644
--- a/examples/basic-actor.c
+++ b/examples/basic-actor.c
@@ -49,36 +49,37 @@ on_crossing (ClutterActor *actor,
}
static void
-on_transition_stopped (ClutterTransition *transition,
- gboolean is_finished,
- ClutterActor *actor)
+on_transition_stopped (ClutterActor *actor,
+ const gchar *transition_name,
+ gboolean is_finished)
{
clutter_actor_save_easing_state (actor);
- clutter_actor_set_easing_duration (actor, 250);
-
clutter_actor_set_rotation_angle (actor, CLUTTER_Y_AXIS, 0.0f);
-
clutter_actor_restore_easing_state (actor);
+
+ /* disconnect so we don't get multiple notifications */
+ g_signal_handlers_disconnect_by_func (actor,
+ on_transition_stopped,
+ NULL);
}
static gboolean
animate_rotation (ClutterActor *actor,
ClutterEvent *event)
{
- ClutterTransition *transition;
-
clutter_actor_save_easing_state (actor);
clutter_actor_set_easing_duration (actor, 1000);
clutter_actor_set_rotation_angle (actor, CLUTTER_Y_AXIS, 360.0);
- transition = clutter_actor_get_transition (actor, "rotation-angle-y");
- g_signal_connect (transition, "stopped",
- G_CALLBACK (on_transition_stopped),
- actor);
-
clutter_actor_restore_easing_state (actor);
+ /* get a notification when the rotation-angle-y transition ends */
+ g_signal_connect (actor,
+ "transition-stopped::rotation-angle-y",
+ G_CALLBACK (on_transition_stopped),
+ NULL);
+
return CLUTTER_EVENT_STOP;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]