Add delay property to ClutterTimeline

This patch adds a "delay" property to the timeline object. If set,
it will delay the start of the timeline of a number of milliseconds.
If the timeline is looping, the delay will be applied just the first
time and not for every loop.
This commit is contained in:
Emmanuele Bassi 2007-06-07 10:26:18 +00:00
parent c90a252581
commit b11aca44e3
4 changed files with 212 additions and 56 deletions

View File

@ -49,9 +49,12 @@ G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT);
struct _ClutterTimelinePrivate struct _ClutterTimelinePrivate
{ {
guint timeout_id; guint timeout_id;
guint delay_id;
guint fps; guint fps;
guint n_frames; guint n_frames;
guint current_frame_num; guint current_frame_num;
guint delay;
gulong last_frame_msecs; gulong last_frame_msecs;
gulong start_frame_secs; gulong start_frame_secs;
@ -65,7 +68,8 @@ enum
PROP_FPS, PROP_FPS,
PROP_NUM_FRAMES, PROP_NUM_FRAMES,
PROP_LOOP PROP_LOOP,
PROP_DELAY
}; };
enum enum
@ -97,14 +101,17 @@ clutter_timeline_set_property (GObject *object,
switch (prop_id) switch (prop_id)
{ {
case PROP_FPS: case PROP_FPS:
clutter_timeline_set_speed (timeline, g_value_get_int (value)); clutter_timeline_set_speed (timeline, g_value_get_uint (value));
break; break;
case PROP_NUM_FRAMES: case PROP_NUM_FRAMES:
priv->n_frames = g_value_get_int (value); priv->n_frames = g_value_get_uint (value);
break; break;
case PROP_LOOP: case PROP_LOOP:
priv->loop = g_value_get_boolean (value); priv->loop = g_value_get_boolean (value);
break; break;
case PROP_DELAY:
priv->delay = g_value_get_uint (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;
@ -126,14 +133,17 @@ clutter_timeline_get_property (GObject *object,
switch (prop_id) switch (prop_id)
{ {
case PROP_FPS: case PROP_FPS:
g_value_set_int (value, priv->fps); g_value_set_uint (value, priv->fps);
break; break;
case PROP_NUM_FRAMES: case PROP_NUM_FRAMES:
g_value_set_int (value, priv->n_frames); g_value_set_uint (value, priv->n_frames);
break; break;
case PROP_LOOP: case PROP_LOOP:
g_value_set_boolean (value, priv->loop); g_value_set_boolean (value, priv->loop);
break; break;
case PROP_DELAY:
g_value_set_uint (value, priv->delay);
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;
@ -154,13 +164,16 @@ clutter_timeline_dispose (GObject *object)
priv = self->priv; priv = self->priv;
if (priv != NULL) if (priv->delay_id)
{ {
if (priv->timeout_id) g_source_remove (priv->delay_id);
{ priv->delay_id = 0;
g_source_remove (priv->timeout_id); }
priv->timeout_id = 0;
} if (priv->timeout_id)
{
g_source_remove (priv->timeout_id);
priv->timeout_id = 0;
} }
G_OBJECT_CLASS (clutter_timeline_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_timeline_parent_class)->dispose (object);
@ -181,33 +194,61 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
g_type_class_add_private (klass, sizeof (ClutterTimelinePrivate)); g_type_class_add_private (klass, sizeof (ClutterTimelinePrivate));
g_object_class_install_property /**
(object_class, PROP_FPS, * ClutterTimeline:fps:
g_param_spec_int ("fps", *
"Frames Per Second", * Timeline frames per second. Because of the nature of the main
"Timeline frames per second", * loop used by Clutter this is to be considered a best approximation.
0, */
1000, g_object_class_install_property (object_class,
50, PROP_FPS,
G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE)); g_param_spec_uint ("fps",
"Frames Per Second",
g_object_class_install_property "Timeline frames per second",
(object_class, PROP_NUM_FRAMES, 0, 1000,
g_param_spec_int ("num-frames", 50,
"Total number of frames", G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
"Timelines total number of frames", /**
0, * ClutterTimeline:num-frames:
G_MAXINT, *
0, * Total number of frames for the timeline.
CLUTTER_PARAM_READWRITE)); */
g_object_class_install_property (object_class,
g_object_class_install_property PROP_NUM_FRAMES,
(object_class, PROP_LOOP, g_param_spec_uint ("num-frames",
g_param_spec_boolean ("loop", "Total number of frames",
"Loop", "Timelines total number of frames",
"Should the timeline automatically restart", 0, G_MAXUINT,
FALSE, 0,
G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE)); G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
/**
* ClutterTimeline:loop:
*
* Whether the timeline should automatically rewind and restart.
*/
g_object_class_install_property (object_class,
PROP_LOOP,
g_param_spec_boolean ("loop",
"Loop",
"Should the timeline automatically restart",
FALSE,
G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
/**
* ClutterTimeline:delay:
*
* A delay, in milliseconds, that should be observed by the
* timeline before actually starting.
*
* Since: 0.4
*/
g_object_class_install_property (object_class,
PROP_DELAY,
g_param_spec_uint ("delay",
"Delay",
"Delay before start",
0, G_MAXUINT,
0,
G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
/** /**
* ClutterTimeline::new-frame: * ClutterTimeline::new-frame:
@ -255,15 +296,15 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
static void static void
clutter_timeline_init (ClutterTimeline *self) clutter_timeline_init (ClutterTimeline *self)
{ {
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
CLUTTER_TYPE_TIMELINE, CLUTTER_TYPE_TIMELINE,
ClutterTimelinePrivate); ClutterTimelinePrivate);
} }
static gboolean static gboolean
timeline_timeout_func (gpointer data) timeline_timeout_func (gpointer data)
{ {
ClutterTimeline *timeline = CLUTTER_TIMELINE(data); ClutterTimeline *timeline = data;
ClutterTimelinePrivate *priv; ClutterTimelinePrivate *priv;
GTimeVal timeval; GTimeVal timeval;
gint n_frames; gint n_frames;
@ -344,6 +385,25 @@ timeline_timeout_func (gpointer data)
return TRUE; return TRUE;
} }
static gboolean
delay_timeout_func (gpointer data)
{
ClutterTimeline *timeline = data;
ClutterTimelinePrivate *priv = timeline->priv;
priv->delay_id = 0;
priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT + 20,
FPS_TO_INTERVAL (priv->fps),
timeline_timeout_func,
timeline,
NULL);
g_signal_emit (timeline, timeline_signals[STARTED], 0);
return FALSE;
}
/** /**
* clutter_timeline_start: * clutter_timeline_start:
* @timeline: A #ClutterTimeline * @timeline: A #ClutterTimeline
@ -359,14 +419,26 @@ clutter_timeline_start (ClutterTimeline *timeline)
priv = timeline->priv; priv = timeline->priv;
if (!priv->timeout_id) if (priv->delay_id || priv->timeout_id)
priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT + 20, return;
FPS_TO_INTERVAL (priv->fps),
timeline_timeout_func, if (priv->delay)
{
priv->delay_id = g_timeout_add_full (G_PRIORITY_DEFAULT + 20,
priv->delay,
delay_timeout_func,
timeline, timeline,
NULL); NULL);
}
g_signal_emit (timeline, timeline_signals[STARTED], 0); else
{
priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT + 20,
FPS_TO_INTERVAL (priv->fps),
timeline_timeout_func,
timeline,
NULL);
g_signal_emit (timeline, timeline_signals[STARTED], 0);
}
} }
/** /**
@ -378,13 +450,26 @@ clutter_timeline_start (ClutterTimeline *timeline)
void void
clutter_timeline_pause (ClutterTimeline *timeline) clutter_timeline_pause (ClutterTimeline *timeline)
{ {
ClutterTimelinePrivate *priv;
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
if (timeline->priv->timeout_id) priv = timeline->priv;
g_source_remove (timeline->priv->timeout_id);
timeline->priv->timeout_id = 0; if (priv->delay_id)
timeline->priv->last_frame_msecs = 0; {
g_source_remove (priv->delay_id);
priv->delay_id = 0;
}
if (priv->timeout_id)
{
g_source_remove (priv->timeout_id);
priv->timeout_id = 0;
}
priv->timeout_id = 0;
priv->last_frame_msecs = 0;
g_signal_emit (timeline, timeline_signals[PAUSED], 0); g_signal_emit (timeline, timeline_signals[PAUSED], 0);
} }
@ -417,12 +502,9 @@ clutter_timeline_set_loop (ClutterTimeline *timeline,
if (timeline->priv->loop != loop) if (timeline->priv->loop != loop)
{ {
g_object_ref (timeline);
timeline->priv->loop = loop; timeline->priv->loop = loop;
g_object_notify (G_OBJECT (timeline), "loop"); g_object_notify (G_OBJECT (timeline), "loop");
g_object_unref (timeline);
} }
} }
@ -654,6 +736,7 @@ clutter_timeline_clone (ClutterTimeline *timeline)
"fps", clutter_timeline_get_speed (timeline), "fps", clutter_timeline_get_speed (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),
NULL); NULL);
return copy; return copy;
@ -677,3 +760,48 @@ clutter_timeline_new (guint n_frames,
"num-frames", n_frames, "num-frames", n_frames,
NULL); NULL);
} }
/**
* clutter_timeline_get_delay:
* @timeline: a #ClutterTimeline
*
* Retrieves the delay set using clutter_timeline_set_delay().
*
* Return value: the delay in milliseconds.
*
* Since: 0.4
*/
guint
clutter_timeline_get_delay (ClutterTimeline *timeline)
{
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0);
return timeline->priv->delay;
}
/**
* clutter_timeline_set_delay:
* @timeline: a #ClutterTimeline
* @msecs: delay in milliseconds
*
* Sets the delay, in milliseconds, before @timeline should start.
*
* Since: 0.4
*/
void
clutter_timeline_set_delay (ClutterTimeline *timeline,
guint msecs)
{
ClutterTimelinePrivate *priv;
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
g_return_if_fail (msecs > 0);
priv = timeline->priv;
if (priv->delay != msecs)
{
priv->delay = msecs;
g_object_notify (G_OBJECT (timeline), "delay");
}
}

View File

@ -108,6 +108,9 @@ void clutter_timeline_set_n_frames (ClutterTimeline *timeline,
guint n_frames); guint n_frames);
guint clutter_timeline_get_n_frames (ClutterTimeline *timeline); guint clutter_timeline_get_n_frames (ClutterTimeline *timeline);
gboolean clutter_timeline_is_playing (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 G_END_DECLS

View File

@ -399,6 +399,8 @@ clutter_timeline_get_current_frame
clutter_timeline_set_n_frames clutter_timeline_set_n_frames
clutter_timeline_get_n_frames clutter_timeline_get_n_frames
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

@ -52,6 +52,11 @@ The #ClutterTimeline has been started.
@cluttertimeline: the object which received the signal. @cluttertimeline: the object which received the signal.
<!-- ##### ARG ClutterTimeline:delay ##### -->
<para>
</para>
<!-- ##### ARG ClutterTimeline:fps ##### --> <!-- ##### ARG ClutterTimeline:fps ##### -->
<para> <para>
@ -93,7 +98,7 @@ The #ClutterTimeline has been started.
@Returns: @Returns:
<!-- ##### FUNCTION clutter_timeline_copy ##### --> <!-- ##### FUNCTION clutter_timeline_clone ##### -->
<para> <para>
</para> </para>
@ -224,3 +229,21 @@ The #ClutterTimeline has been started.
@Returns: @Returns:
<!-- ##### FUNCTION clutter_timeline_set_delay ##### -->
<para>
</para>
@timeline:
@msecs:
<!-- ##### FUNCTION clutter_timeline_get_delay ##### -->
<para>
</para>
@timeline:
@Returns: