mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
timeline: Add :reverse property
The :reverse property removes the pattern of connecting to the ::completed signal of a Timeline to change the direction. http://bugzilla.clutter-project.org/show_bug.cgi?id=2408
This commit is contained in:
parent
1ce47bb562
commit
71a838815f
@ -66,10 +66,14 @@ struct _ClutterTimelinePrivate
|
|||||||
/* Time we last advanced the elapsed time and showed a frame */
|
/* Time we last advanced the elapsed time and showed a frame */
|
||||||
gint64 last_frame_time;
|
gint64 last_frame_time;
|
||||||
|
|
||||||
guint loop : 1;
|
guint loop : 1;
|
||||||
guint is_playing : 1;
|
guint is_playing : 1;
|
||||||
/* If we've just started playing and haven't yet gotten a tick from the master clock */
|
|
||||||
|
/* If we've just started playing and haven't yet gotten
|
||||||
|
* a tick from the master clock
|
||||||
|
*/
|
||||||
guint waiting_first_tick : 1;
|
guint waiting_first_tick : 1;
|
||||||
|
guint reverse : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -86,11 +90,12 @@ enum
|
|||||||
PROP_DELAY,
|
PROP_DELAY,
|
||||||
PROP_DURATION,
|
PROP_DURATION,
|
||||||
PROP_DIRECTION,
|
PROP_DIRECTION,
|
||||||
|
PROP_REVERSE,
|
||||||
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
static GParamSpec *obj_props[PROP_LAST];
|
static GParamSpec *obj_props[PROP_LAST] = { NULL, };
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -138,20 +143,16 @@ clutter_timeline_set_property (GObject *object,
|
|||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
ClutterTimeline *timeline;
|
ClutterTimeline *timeline = CLUTTER_TIMELINE (object);
|
||||||
ClutterTimelinePrivate *priv;
|
|
||||||
|
|
||||||
timeline = CLUTTER_TIMELINE(object);
|
|
||||||
priv = timeline->priv;
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_LOOP:
|
case PROP_LOOP:
|
||||||
priv->loop = g_value_get_boolean (value);
|
clutter_timeline_set_loop (timeline, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_DELAY:
|
case PROP_DELAY:
|
||||||
priv->delay = g_value_get_uint (value);
|
clutter_timeline_set_delay (timeline, g_value_get_uint (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_DURATION:
|
case PROP_DURATION:
|
||||||
@ -162,6 +163,10 @@ clutter_timeline_set_property (GObject *object,
|
|||||||
clutter_timeline_set_direction (timeline, g_value_get_enum (value));
|
clutter_timeline_set_direction (timeline, g_value_get_enum (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_REVERSE:
|
||||||
|
clutter_timeline_set_reverse (timeline, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -174,11 +179,8 @@ clutter_timeline_get_property (GObject *object,
|
|||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
ClutterTimeline *timeline;
|
ClutterTimeline *timeline = CLUTTER_TIMELINE (object);
|
||||||
ClutterTimelinePrivate *priv;
|
ClutterTimelinePrivate *priv = timeline->priv;
|
||||||
|
|
||||||
timeline = CLUTTER_TIMELINE(object);
|
|
||||||
priv = timeline->priv;
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
@ -198,6 +200,10 @@ clutter_timeline_get_property (GObject *object,
|
|||||||
g_value_set_enum (value, priv->direction);
|
g_value_set_enum (value, priv->direction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_REVERSE:
|
||||||
|
g_value_set_boolean (value, priv->reverse);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -307,6 +313,21 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
|||||||
CLUTTER_TIMELINE_FORWARD,
|
CLUTTER_TIMELINE_FORWARD,
|
||||||
CLUTTER_PARAM_READWRITE);
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterTimeline:reverse:
|
||||||
|
*
|
||||||
|
* Whether the direction of a looping timeline should be reversed
|
||||||
|
* when emitting the #ClutterTimeline::completed signal.
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
obj_props[PROP_REVERSE] =
|
||||||
|
g_param_spec_boolean ("reverse",
|
||||||
|
P_("Reverse"),
|
||||||
|
P_("Whether the direction should be reversed when looping"),
|
||||||
|
FALSE,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
object_class->dispose = clutter_timeline_dispose;
|
object_class->dispose = clutter_timeline_dispose;
|
||||||
object_class->finalize = clutter_timeline_finalize;
|
object_class->finalize = clutter_timeline_finalize;
|
||||||
object_class->set_property = clutter_timeline_set_property;
|
object_class->set_property = clutter_timeline_set_property;
|
||||||
@ -662,6 +683,20 @@ clutter_timeline_do_frame (ClutterTimeline *timeline)
|
|||||||
|
|
||||||
g_signal_emit (timeline, timeline_signals[COMPLETED], 0);
|
g_signal_emit (timeline, timeline_signals[COMPLETED], 0);
|
||||||
|
|
||||||
|
/* reverse the direction of the timeline if :loop and
|
||||||
|
* :reverse are set to TRUE
|
||||||
|
*/
|
||||||
|
if (priv->reverse)
|
||||||
|
{
|
||||||
|
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
|
||||||
|
priv->direction = CLUTTER_TIMELINE_BACKWARD;
|
||||||
|
else
|
||||||
|
priv->direction = CLUTTER_TIMELINE_FORWARD;
|
||||||
|
|
||||||
|
_clutter_notify_by_pspec (G_OBJECT (timeline),
|
||||||
|
obj_props[PROP_DIRECTION]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Again check to see if the user has manually played with
|
/* Again check to see if the user has manually played with
|
||||||
* the elapsed time, before we finally stop or loop the timeline */
|
* the elapsed time, before we finally stop or loop the timeline */
|
||||||
|
|
||||||
@ -692,9 +727,9 @@ clutter_timeline_do_frame (ClutterTimeline *timeline)
|
|||||||
time without emitting the new frame signal so we need to
|
time without emitting the new frame signal so we need to
|
||||||
check for markers again */
|
check for markers again */
|
||||||
check_markers (timeline,
|
check_markers (timeline,
|
||||||
priv->direction == CLUTTER_TIMELINE_FORWARD ?
|
priv->direction == CLUTTER_TIMELINE_FORWARD
|
||||||
priv->elapsed_time :
|
? priv->elapsed_time
|
||||||
priv->duration - priv->elapsed_time);
|
: priv->duration - priv->elapsed_time);
|
||||||
|
|
||||||
g_object_unref (timeline);
|
g_object_unref (timeline);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -1501,3 +1536,86 @@ clutter_timeline_has_marker (ClutterTimeline *timeline,
|
|||||||
return NULL != g_hash_table_lookup (timeline->priv->markers_by_name,
|
return NULL != g_hash_table_lookup (timeline->priv->markers_by_name,
|
||||||
marker_name);
|
marker_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_timeline_set_reverse:
|
||||||
|
* @timeline: a #ClutterTimeline
|
||||||
|
* @reverse: %TRUE if the @timeline should reverse the direction
|
||||||
|
*
|
||||||
|
* Sets whether @timeline should reverse the direction after the
|
||||||
|
* emission of the #ClutterTimeline::completed signal.
|
||||||
|
*
|
||||||
|
* Setting the #ClutterTimeline:reverse property to %TRUE is the
|
||||||
|
* equivalent of connecting a callback to the #ClutterTimeline::completed
|
||||||
|
* signal and changing the direction of the timeline from that callback;
|
||||||
|
* for instance, this code:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* static void
|
||||||
|
* reverse_timeline (ClutterTimeline *timeline)
|
||||||
|
* {
|
||||||
|
* ClutterTimelineDirection dir = clutter_timeline_get_direction (timeline);
|
||||||
|
*
|
||||||
|
* if (dir == CLUTTER_TIMELINE_FORWARD)
|
||||||
|
* dir = CLUTTER_TIMELINE_BACKWARD;
|
||||||
|
* else
|
||||||
|
* dir = CLUTTER_TIMELINE_FORWARD;
|
||||||
|
*
|
||||||
|
* clutter_timeline_set_direction (timeline, dir);
|
||||||
|
* }
|
||||||
|
* ...
|
||||||
|
* timeline = clutter_timeline_new (1000);
|
||||||
|
* clutter_timeline_set_loop (timeline);
|
||||||
|
* g_signal_connect (timeline, "completed",
|
||||||
|
* G_CALLBACK (reverse_timeline),
|
||||||
|
* NULL);
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* can be effectively replaced by:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* timeline = clutter_timeline_new (1000);
|
||||||
|
* clutter_timeline_set_loop (timeline);
|
||||||
|
* clutter_timeline_set_reverse (timeline);
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_timeline_set_reverse (ClutterTimeline *timeline,
|
||||||
|
gboolean reverse)
|
||||||
|
{
|
||||||
|
ClutterTimelinePrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
|
||||||
|
|
||||||
|
reverse = !!reverse;
|
||||||
|
|
||||||
|
priv = timeline->priv;
|
||||||
|
|
||||||
|
if (priv->reverse != reverse)
|
||||||
|
{
|
||||||
|
priv->reverse = reverse;
|
||||||
|
|
||||||
|
_clutter_notify_by_pspec (G_OBJECT (timeline), obj_props[PROP_REVERSE]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_timeline_get_reverse:
|
||||||
|
* @timeline: a #ClutterTimeline
|
||||||
|
*
|
||||||
|
* Retrieves the value set by clutter_timeline_set_reverse().
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the timeline should reverse when looping, and
|
||||||
|
* %FALSE otherwise
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
clutter_timeline_get_reverse (ClutterTimeline *timeline)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE);
|
||||||
|
|
||||||
|
return timeline->priv->reverse;
|
||||||
|
}
|
||||||
|
@ -127,6 +127,9 @@ void clutter_timeline_stop (ClutterTimeline *timeli
|
|||||||
void clutter_timeline_set_loop (ClutterTimeline *timeline,
|
void clutter_timeline_set_loop (ClutterTimeline *timeline,
|
||||||
gboolean loop);
|
gboolean loop);
|
||||||
gboolean clutter_timeline_get_loop (ClutterTimeline *timeline);
|
gboolean clutter_timeline_get_loop (ClutterTimeline *timeline);
|
||||||
|
void clutter_timeline_set_reverse (ClutterTimeline *timeline,
|
||||||
|
gboolean reverse);
|
||||||
|
gboolean clutter_timeline_get_reverse (ClutterTimeline *timeline);
|
||||||
void clutter_timeline_rewind (ClutterTimeline *timeline);
|
void clutter_timeline_rewind (ClutterTimeline *timeline);
|
||||||
void clutter_timeline_skip (ClutterTimeline *timeline,
|
void clutter_timeline_skip (ClutterTimeline *timeline,
|
||||||
guint msecs);
|
guint msecs);
|
||||||
|
@ -660,6 +660,8 @@ clutter_timeline_get_delay
|
|||||||
ClutterTimelineDirection
|
ClutterTimelineDirection
|
||||||
clutter_timeline_set_direction
|
clutter_timeline_set_direction
|
||||||
clutter_timeline_get_direction
|
clutter_timeline_get_direction
|
||||||
|
clutter_timeline_set_reverse
|
||||||
|
clutter_timeline_get_reverse
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_timeline_start
|
clutter_timeline_start
|
||||||
|
@ -44,21 +44,6 @@ scroll_event_cb (ClutterStage *stage,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
timeline_completed (ClutterTimeline *timeline)
|
|
||||||
{
|
|
||||||
ClutterTimelineDirection direction;
|
|
||||||
|
|
||||||
direction = clutter_timeline_get_direction (timeline);
|
|
||||||
|
|
||||||
if (direction == CLUTTER_TIMELINE_FORWARD)
|
|
||||||
direction = CLUTTER_TIMELINE_BACKWARD;
|
|
||||||
else
|
|
||||||
direction = CLUTTER_TIMELINE_FORWARD;
|
|
||||||
|
|
||||||
clutter_timeline_set_direction (timeline, direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PATH_POLY,
|
PATH_POLY,
|
||||||
PATH_ELLIPSE,
|
PATH_ELLIPSE,
|
||||||
@ -160,11 +145,9 @@ test_behave_main (int argc, char *argv[])
|
|||||||
clutter_container_add (CLUTTER_CONTAINER (group), rect, hand, NULL);
|
clutter_container_add (CLUTTER_CONTAINER (group), rect, hand, NULL);
|
||||||
|
|
||||||
/* Make a timeline */
|
/* Make a timeline */
|
||||||
timeline = clutter_timeline_new (4000); /* num frames, fps */
|
timeline = clutter_timeline_new (4000);
|
||||||
clutter_timeline_set_loop (timeline, TRUE);
|
clutter_timeline_set_loop (timeline, TRUE);
|
||||||
g_signal_connect (timeline,
|
clutter_timeline_set_reverse (timeline, TRUE);
|
||||||
"completed", G_CALLBACK (timeline_completed),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Set an alpha func to power behaviour - ramp is constant rise */
|
/* Set an alpha func to power behaviour - ramp is constant rise */
|
||||||
alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR);
|
alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR);
|
||||||
|
Loading…
Reference in New Issue
Block a user