mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 03:20:46 -05:00
actor: Add ::transition-stopped
The ::transition-stopped signal can be used to get notification of the end of a transition.
This commit is contained in:
parent
e0e5ab9dd4
commit
28c2eeef95
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -8014,6 +8013,32 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
_clutter_marshal_VOID__VOID,
|
||||
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);
|
||||
|
||||
#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)",
|
||||
"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);
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user