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>
* clutter/clutter-effect.h:

View File

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

View File

@ -49,6 +49,7 @@
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT);
@ -57,12 +58,15 @@ G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT);
struct _ClutterTimelinePrivate
{
ClutterTimelineDirection direction;
guint timeout_id;
guint delay_id;
gint current_frame_num;
guint fps;
guint n_frames;
guint current_frame_num;
guint delay;
guint duration;
@ -80,7 +84,8 @@ enum
PROP_NUM_FRAMES,
PROP_LOOP,
PROP_DELAY,
PROP_DURATION
PROP_DURATION,
PROP_DIRECTION
};
enum
@ -186,6 +191,9 @@ clutter_timeline_set_property (GObject *object,
case PROP_DURATION:
clutter_timeline_set_duration (timeline, g_value_get_uint (value));
break;
case PROP_DIRECTION:
clutter_timeline_set_direction (timeline, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -221,6 +229,9 @@ clutter_timeline_get_property (GObject *object,
case PROP_DURATION:
g_value_set_uint (value, priv->duration);
break;
case PROP_DIRECTION:
g_value_set_enum (value, priv->direction);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -341,6 +352,22 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
0, G_MAXUINT,
1000,
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:
@ -499,10 +526,16 @@ timeline_timeout_func (gpointer data)
priv->last_frame_msecs = msecs;
/* 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 */
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;
@ -513,8 +546,16 @@ timeline_timeout_func (gpointer data)
priv->n_frames,
n_frames - 1);
frame_diff = priv->current_frame_num - priv->n_frames;
priv->current_frame_num = priv->n_frames;
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
{
frame_diff = 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
* to emit the last new-frame signal with the last frame
@ -699,9 +740,16 @@ clutter_timeline_get_loop (ClutterTimeline *timeline)
void
clutter_timeline_rewind (ClutterTimeline *timeline)
{
ClutterTimelinePrivate *priv;
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
clutter_timeline_advance (timeline, 0);
priv = timeline->priv;
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
clutter_timeline_advance (timeline, 0);
else if (priv->direction == CLUTTER_TIMELINE_BACKWARD)
clutter_timeline_advance (timeline, priv->n_frames);
}
/**
@ -723,8 +771,20 @@ clutter_timeline_skip (ClutterTimeline *timeline,
priv->current_frame_num += n_frames;
if (priv->current_frame_num > priv->n_frames)
priv->current_frame_num = 1;
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
{
priv->current_frame_num += n_frames;
if (priv->current_frame_num > priv->n_frames)
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;
}
}
/**
@ -744,8 +804,7 @@ clutter_timeline_advance (ClutterTimeline *timeline,
priv = timeline->priv;
if (frame_num < priv->n_frames)
priv->current_frame_num = frame_num;
priv->current_frame_num = CLAMP (frame_num, 0, priv->n_frames);
}
/**
@ -800,12 +859,9 @@ clutter_timeline_set_n_frames (ClutterTimeline *timeline,
if (priv->n_frames != n_frames)
{
g_object_ref (timeline);
priv->n_frames = n_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),
"loop", clutter_timeline_get_loop (timeline),
"delay", clutter_timeline_get_delay (timeline),
"direction", clutter_timeline_get_direction (timeline),
NULL);
return copy;
@ -1091,6 +1148,60 @@ clutter_timeline_get_progressx (ClutterTimeline *timeline)
priv = timeline->priv;
return CLUTTER_FIXED_DIV (CLUTTER_INT_TO_FIXED (priv->current_frame_num),
CLUTTER_INT_TO_FIXED (priv->n_frames));
if (priv->direction == CLUTTER_TIMELINE_FORWARD)
return CLUTTER_FIXED_DIV (CLUTTER_INT_TO_FIXED (priv->current_frame_num),
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), \
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 _ClutterTimelineClass ClutterTimelineClass;
typedef struct _ClutterTimelinePrivate ClutterTimelinePrivate;
@ -89,38 +103,41 @@ struct _ClutterTimelineClass
GType clutter_timeline_get_type (void) G_GNUC_CONST;
ClutterTimeline *clutter_timeline_new (guint n_frames,
guint fps);
ClutterTimeline *clutter_timeline_new_for_duration (guint msecs);
ClutterTimeline *clutter_timeline_clone (ClutterTimeline *timeline);
ClutterTimeline *clutter_timeline_new (guint n_frames,
guint fps);
ClutterTimeline *clutter_timeline_new_for_duration (guint msecs);
ClutterTimeline *clutter_timeline_clone (ClutterTimeline *timeline);
guint clutter_timeline_get_duration (ClutterTimeline *timeline);
void clutter_timeline_set_duration (ClutterTimeline *timeline,
guint msecs);
guint clutter_timeline_get_speed (ClutterTimeline *timeline);
void clutter_timeline_set_speed (ClutterTimeline *timeline,
guint fps);
void clutter_timeline_start (ClutterTimeline *timeline);
void clutter_timeline_pause (ClutterTimeline *timeline);
void clutter_timeline_stop (ClutterTimeline *timeline);
void clutter_timeline_set_loop (ClutterTimeline *timeline,
gboolean loop);
gboolean clutter_timeline_get_loop (ClutterTimeline *timeline);
void clutter_timeline_rewind (ClutterTimeline *timeline);
void clutter_timeline_skip (ClutterTimeline *timeline,
guint n_frames);
void clutter_timeline_advance (ClutterTimeline *timeline,
guint frame_num);
gint clutter_timeline_get_current_frame (ClutterTimeline *timeline);
gdouble clutter_timeline_get_progress (ClutterTimeline *timeline);
ClutterFixed clutter_timeline_get_progressx (ClutterTimeline *timeline);
void clutter_timeline_set_n_frames (ClutterTimeline *timeline,
guint n_frames);
guint clutter_timeline_get_n_frames (ClutterTimeline *timeline);
gboolean clutter_timeline_is_playing (ClutterTimeline *timeline);
void clutter_timeline_set_delay (ClutterTimeline *timeline,
guint msecs);
guint clutter_timeline_get_delay (ClutterTimeline *timeline);
guint clutter_timeline_get_duration (ClutterTimeline *timeline);
void clutter_timeline_set_duration (ClutterTimeline *timeline,
guint msecs);
guint clutter_timeline_get_speed (ClutterTimeline *timeline);
void clutter_timeline_set_speed (ClutterTimeline *timeline,
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_pause (ClutterTimeline *timeline);
void clutter_timeline_stop (ClutterTimeline *timeline);
void clutter_timeline_set_loop (ClutterTimeline *timeline,
gboolean loop);
gboolean clutter_timeline_get_loop (ClutterTimeline *timeline);
void clutter_timeline_rewind (ClutterTimeline *timeline);
void clutter_timeline_skip (ClutterTimeline *timeline,
guint n_frames);
void clutter_timeline_advance (ClutterTimeline *timeline,
guint frame_num);
gint clutter_timeline_get_current_frame (ClutterTimeline *timeline);
gdouble clutter_timeline_get_progress (ClutterTimeline *timeline);
ClutterFixed clutter_timeline_get_progressx (ClutterTimeline *timeline);
void clutter_timeline_set_n_frames (ClutterTimeline *timeline,
guint n_frames);
guint clutter_timeline_get_n_frames (ClutterTimeline *timeline);
gboolean clutter_timeline_is_playing (ClutterTimeline *timeline);
void clutter_timeline_set_delay (ClutterTimeline *timeline,
guint msecs);
guint clutter_timeline_get_delay (ClutterTimeline *timeline);
G_END_DECLS

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>
* clutter-sections.txt: Add new ClutterEffectTemplate constructor.

View File

@ -484,23 +484,36 @@ clutter_perspective_get_type
ClutterTimeline
ClutterTimelineClass
clutter_timeline_new
clutter_timeline_new_for_duration
clutter_timeline_clone
<SUBSECTION>
clutter_timeline_set_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_pause
clutter_timeline_stop
clutter_timeline_set_loop
clutter_timeline_get_loop
clutter_timeline_rewind
clutter_timeline_skip
clutter_timeline_advance
clutter_timeline_get_current_frame
clutter_timeline_set_n_frames
clutter_timeline_get_n_frames
clutter_timeline_get_progress
clutter_timeline_get_progressx
clutter_timeline_is_playing
clutter_timeline_set_delay
clutter_timeline_get_delay
<SUBSECTION Standard>
CLUTTER_TIMELINE
CLUTTER_IS_TIMELINE

View File

@ -48,8 +48,11 @@ main (int argc, char **argv)
clutter_init (&argc, &argv);
timeline_1 = clutter_timeline_new (10, 120);
timeline_2 = 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,
"new-frame", G_CALLBACK (timeline_1_new_frame_cb),