2007-11-15 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/clutter-timeline.[ch]: Add ClutterTimeline:direction
	property, defining the direction (forward or backward) of the
	timeline.

	* tests/test-timeline.c: Test the direction property.

	* clutter.symbols: Update exported symbols
This commit is contained in:
Emmanuele Bassi 2007-11-15 17:03:55 +00:00
parent 768d85dcea
commit 0d082df3a5
7 changed files with 216 additions and 53 deletions

View File

@ -1,3 +1,13 @@
2007-11-15 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-timeline.[ch]: Add ClutterTimeline:direction
property, defining the direction (forward or backward) of the
timeline.
* tests/test-timeline.c: Test the direction property.
* clutter.symbols: Update exported symbols
2007-11-15 Emmanuele Bassi <ebassi@openedhand.com> 2007-11-15 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-effect.h: * clutter/clutter-effect.h:

View File

@ -422,9 +422,12 @@ clutter_texture_has_generated_tiles
clutter_texture_is_tiled clutter_texture_is_tiled
clutter_timeline_get_type clutter_timeline_get_type
clutter_timeline_new clutter_timeline_new
clutter_timeline_new_for_duration
clutter_timeline_clone clutter_timeline_clone
clutter_timeline_get_speed clutter_timeline_get_speed
clutter_timeline_set_speed clutter_timeline_set_speed
clutter_timeline_get_direction
clutter_timeline_set_direction
clutter_timeline_start clutter_timeline_start
clutter_timeline_pause clutter_timeline_pause
clutter_timeline_stop clutter_timeline_stop
@ -439,6 +442,8 @@ clutter_timeline_get_n_frames
clutter_timeline_is_playing clutter_timeline_is_playing
clutter_timeline_set_delay clutter_timeline_set_delay
clutter_timeline_get_delay clutter_timeline_get_delay
clutter_timeline_set_duration
clutter_timeline_get_duration
clutter_timeout_pool_new clutter_timeout_pool_new
clutter_timeout_pool_add clutter_timeout_pool_add
clutter_timeout_pool_remove clutter_timeout_pool_remove

View File

@ -49,6 +49,7 @@
#include "clutter-marshal.h" #include "clutter-marshal.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-enum-types.h"
G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT); G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT);
@ -57,12 +58,15 @@ G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT);
struct _ClutterTimelinePrivate struct _ClutterTimelinePrivate
{ {
ClutterTimelineDirection direction;
guint timeout_id; guint timeout_id;
guint delay_id; guint delay_id;
gint current_frame_num;
guint fps; guint fps;
guint n_frames; guint n_frames;
guint current_frame_num;
guint delay; guint delay;
guint duration; guint duration;
@ -80,7 +84,8 @@ enum
PROP_NUM_FRAMES, PROP_NUM_FRAMES,
PROP_LOOP, PROP_LOOP,
PROP_DELAY, PROP_DELAY,
PROP_DURATION PROP_DURATION,
PROP_DIRECTION
}; };
enum enum
@ -186,6 +191,9 @@ clutter_timeline_set_property (GObject *object,
case PROP_DURATION: case PROP_DURATION:
clutter_timeline_set_duration (timeline, g_value_get_uint (value)); clutter_timeline_set_duration (timeline, g_value_get_uint (value));
break; break;
case PROP_DIRECTION:
clutter_timeline_set_direction (timeline, g_value_get_enum (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;
@ -221,6 +229,9 @@ clutter_timeline_get_property (GObject *object,
case PROP_DURATION: case PROP_DURATION:
g_value_set_uint (value, priv->duration); g_value_set_uint (value, priv->duration);
break; break;
case PROP_DIRECTION:
g_value_set_enum (value, priv->direction);
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;
@ -341,6 +352,22 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
0, G_MAXUINT, 0, G_MAXUINT,
1000, 1000,
CLUTTER_PARAM_READWRITE)); CLUTTER_PARAM_READWRITE));
/**
* ClutterTimeline:direction:
*
* The direction of the timeline, either %CLUTTER_TIMELINE_FORWARD or
* %CLUTTER_TIMELINE_BACKWARD.
*
* Since: 0.6
*/
g_object_class_install_property (object_class,
PROP_DIRECTION,
g_param_spec_enum ("direction",
"Direction",
"Direction of the timeline",
CLUTTER_TYPE_TIMELINE_DIRECTION,
CLUTTER_TIMELINE_FORWARD,
CLUTTER_PARAM_READWRITE));
/** /**
* ClutterTimeline::new-frame: * ClutterTimeline::new-frame:
@ -499,10 +526,16 @@ timeline_timeout_func (gpointer data)
priv->last_frame_msecs = msecs; priv->last_frame_msecs = msecs;
/* Advance frames */ /* Advance frames */
priv->current_frame_num += n_frames;; if (priv->direction == CLUTTER_TIMELINE_FORWARD)
priv->current_frame_num += n_frames;
else
priv->current_frame_num -= n_frames;
/* Handle loop or stop */ /* Handle loop or stop */
if (priv->current_frame_num > priv->n_frames) if (((priv->direction == CLUTTER_TIMELINE_FORWARD) &&
(priv->current_frame_num > priv->n_frames)) ||
((priv->direction == CLUTTER_TIMELINE_BACKWARD) &&
(priv->current_frame_num < 0)))
{ {
guint frame_diff; guint frame_diff;
@ -513,8 +546,16 @@ timeline_timeout_func (gpointer data)
priv->n_frames, priv->n_frames,
n_frames - 1); n_frames - 1);
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
{
frame_diff = priv->current_frame_num - priv->n_frames; frame_diff = priv->current_frame_num - priv->n_frames;
priv->current_frame_num = priv->n_frames; priv->current_frame_num = priv->n_frames;
}
else
{
frame_diff = priv->n_frames - priv->current_frame_num;
priv->current_frame_num = 0;
}
/* if we skipped some frame to get here let's see whether we still need /* if we skipped some frame to get here let's see whether we still need
* to emit the last new-frame signal with the last frame * to emit the last new-frame signal with the last frame
@ -699,9 +740,16 @@ clutter_timeline_get_loop (ClutterTimeline *timeline)
void void
clutter_timeline_rewind (ClutterTimeline *timeline) clutter_timeline_rewind (ClutterTimeline *timeline)
{ {
ClutterTimelinePrivate *priv;
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
priv = timeline->priv;
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
clutter_timeline_advance (timeline, 0); clutter_timeline_advance (timeline, 0);
else if (priv->direction == CLUTTER_TIMELINE_BACKWARD)
clutter_timeline_advance (timeline, priv->n_frames);
} }
/** /**
@ -723,9 +771,21 @@ clutter_timeline_skip (ClutterTimeline *timeline,
priv->current_frame_num += n_frames; priv->current_frame_num += n_frames;
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
{
priv->current_frame_num += n_frames;
if (priv->current_frame_num > priv->n_frames) if (priv->current_frame_num > priv->n_frames)
priv->current_frame_num = 1; priv->current_frame_num = 1;
} }
else if (priv->direction == CLUTTER_TIMELINE_BACKWARD)
{
priv->current_frame_num -= n_frames;
if (priv->current_frame_num < 1)
priv->current_frame_num = priv->n_frames - 1;
}
}
/** /**
* clutter_timeline_advance: * clutter_timeline_advance:
@ -744,8 +804,7 @@ clutter_timeline_advance (ClutterTimeline *timeline,
priv = timeline->priv; priv = timeline->priv;
if (frame_num < priv->n_frames) priv->current_frame_num = CLAMP (frame_num, 0, priv->n_frames);
priv->current_frame_num = frame_num;
} }
/** /**
@ -800,12 +859,9 @@ clutter_timeline_set_n_frames (ClutterTimeline *timeline,
if (priv->n_frames != n_frames) if (priv->n_frames != n_frames)
{ {
g_object_ref (timeline);
priv->n_frames = n_frames; priv->n_frames = n_frames;
g_object_notify (G_OBJECT (timeline), "num-frames"); g_object_notify (G_OBJECT (timeline), "num-frames");
g_object_unref (timeline);
} }
} }
@ -905,6 +961,7 @@ clutter_timeline_clone (ClutterTimeline *timeline)
"num-frames", clutter_timeline_get_n_frames (timeline), "num-frames", clutter_timeline_get_n_frames (timeline),
"loop", clutter_timeline_get_loop (timeline), "loop", clutter_timeline_get_loop (timeline),
"delay", clutter_timeline_get_delay (timeline), "delay", clutter_timeline_get_delay (timeline),
"direction", clutter_timeline_get_direction (timeline),
NULL); NULL);
return copy; return copy;
@ -1091,6 +1148,60 @@ clutter_timeline_get_progressx (ClutterTimeline *timeline)
priv = timeline->priv; priv = timeline->priv;
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
return CLUTTER_FIXED_DIV (CLUTTER_INT_TO_FIXED (priv->current_frame_num), return CLUTTER_FIXED_DIV (CLUTTER_INT_TO_FIXED (priv->current_frame_num),
CLUTTER_INT_TO_FIXED (priv->n_frames)); CLUTTER_INT_TO_FIXED (priv->n_frames));
else
return CLUTTER_FIXED_DIV (CLUTTER_INT_TO_FIXED (priv->n_frames),
CLUTTER_INT_TO_FIXED (priv->current_frame_num));
}
/**
* clutter_timeline_get_direction:
* @timeline: a #ClutterTimeline
*
* Retrieves the direction of the timeline set with
* clutter_timeline_set_direction().
*
* Return value: the direction of the timeline
*
* Since: 0.6
*/
ClutterTimelineDirection
clutter_timeline_get_direction (ClutterTimeline *timeline)
{
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), CLUTTER_TIMELINE_FORWARD);
return timeline->priv->direction;
}
/**
* clutter_timeline_set_direction:
* @timeline: a #ClutterTimeline
* @direction: the direction of the timeline
*
* Sets the direction of @timeline, either %CLUTTER_TIMELINE_FORWARD or
* %CLUTTER_TIMELINE_BACKWARD.
*
* Since: 0.6
*/
void
clutter_timeline_set_direction (ClutterTimeline *timeline,
ClutterTimelineDirection direction)
{
ClutterTimelinePrivate *priv;
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
priv = timeline->priv;
if (priv->direction != direction)
{
priv->direction = direction;
if (priv->current_frame_num == 0)
priv->current_frame_num = priv->n_frames;
g_object_notify (G_OBJECT (timeline), "direction");
}
} }

View File

@ -55,6 +55,20 @@ G_BEGIN_DECLS
(G_TYPE_INSTANCE_GET_CLASS ((obj), \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
CLUTTER_TYPE_TIMELINE, ClutterTimelineClass)) CLUTTER_TYPE_TIMELINE, ClutterTimelineClass))
/**
* ClutterTimelineDirection:
* @CLUTTER_TIMELINE_FORWARD: forward direction for a timeline
* @CLUTTER_TIMELINE_BACKWARD: backward direction for a timeline
*
* The direction of a #ClutterTimeline
*
* Since: 0.6
*/
typedef enum {
CLUTTER_TIMELINE_FORWARD,
CLUTTER_TIMELINE_BACKWARD
} ClutterTimelineDirection;
typedef struct _ClutterTimeline ClutterTimeline; typedef struct _ClutterTimeline ClutterTimeline;
typedef struct _ClutterTimelineClass ClutterTimelineClass; typedef struct _ClutterTimelineClass ClutterTimelineClass;
typedef struct _ClutterTimelinePrivate ClutterTimelinePrivate; typedef struct _ClutterTimelinePrivate ClutterTimelinePrivate;
@ -100,6 +114,9 @@ void clutter_timeline_set_duration (ClutterTimeline *timeline,
guint clutter_timeline_get_speed (ClutterTimeline *timeline); guint clutter_timeline_get_speed (ClutterTimeline *timeline);
void clutter_timeline_set_speed (ClutterTimeline *timeline, void clutter_timeline_set_speed (ClutterTimeline *timeline,
guint fps); guint fps);
ClutterTimelineDirection clutter_timeline_get_direction (ClutterTimeline *timeline);
void clutter_timeline_set_direction (ClutterTimeline *timeline,
ClutterTimelineDirection direction);
void clutter_timeline_start (ClutterTimeline *timeline); void clutter_timeline_start (ClutterTimeline *timeline);
void clutter_timeline_pause (ClutterTimeline *timeline); void clutter_timeline_pause (ClutterTimeline *timeline);
void clutter_timeline_stop (ClutterTimeline *timeline); void clutter_timeline_stop (ClutterTimeline *timeline);

View File

@ -1,3 +1,7 @@
2007-11-15 Emmanuele Bassi <ebassi@openedhand.com>
* clutter-sections.txt: Add new ClutterTimeline API
2007-11-15 Emmanuele Bassi <ebassi@openedhand.com> 2007-11-15 Emmanuele Bassi <ebassi@openedhand.com>
* clutter-sections.txt: Add new ClutterEffectTemplate constructor. * clutter-sections.txt: Add new ClutterEffectTemplate constructor.

View File

@ -484,23 +484,36 @@ clutter_perspective_get_type
ClutterTimeline ClutterTimeline
ClutterTimelineClass ClutterTimelineClass
clutter_timeline_new clutter_timeline_new
clutter_timeline_new_for_duration
clutter_timeline_clone clutter_timeline_clone
<SUBSECTION>
clutter_timeline_set_speed clutter_timeline_set_speed
clutter_timeline_get_speed clutter_timeline_get_speed
clutter_timeline_set_duration
clutter_timeline_get_duration
clutter_timeline_set_loop
clutter_timeline_get_loop
clutter_timeline_set_n_frames
clutter_timeline_get_n_frames
clutter_timeline_set_delay
clutter_timeline_get_delay
ClutterTimelineDirection
clutter_timeline_set_direction
clutter_timeline_get_direction
<SUBSECTION
clutter_timeline_start clutter_timeline_start
clutter_timeline_pause clutter_timeline_pause
clutter_timeline_stop clutter_timeline_stop
clutter_timeline_set_loop
clutter_timeline_get_loop
clutter_timeline_rewind clutter_timeline_rewind
clutter_timeline_skip clutter_timeline_skip
clutter_timeline_advance clutter_timeline_advance
clutter_timeline_get_current_frame clutter_timeline_get_current_frame
clutter_timeline_set_n_frames clutter_timeline_get_progress
clutter_timeline_get_n_frames clutter_timeline_get_progressx
clutter_timeline_is_playing clutter_timeline_is_playing
clutter_timeline_set_delay
clutter_timeline_get_delay
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_TIMELINE CLUTTER_TIMELINE
CLUTTER_IS_TIMELINE CLUTTER_IS_TIMELINE

View File

@ -48,8 +48,11 @@ main (int argc, char **argv)
clutter_init (&argc, &argv); clutter_init (&argc, &argv);
timeline_1 = clutter_timeline_new (10, 120); timeline_1 = clutter_timeline_new (10, 120);
timeline_2 = clutter_timeline_clone (timeline_1); timeline_2 = clutter_timeline_clone (timeline_1);
timeline_3 = clutter_timeline_clone (timeline_1); timeline_3 = clutter_timeline_clone (timeline_1);
clutter_timeline_set_direction (timeline_3, CLUTTER_TIMELINE_BACKWARD);
g_signal_connect (timeline_1, g_signal_connect (timeline_1,
"new-frame", G_CALLBACK (timeline_1_new_frame_cb), "new-frame", G_CALLBACK (timeline_1_new_frame_cb),