## ClutterTimeline

ClutterTimeline — A class for time-based events

## Synopsis

                        ClutterTimeline;
                        ClutterTimelineClass;
    ClutterTimeline*    clutter_timeline_new                (guint n_frames,
                                                             guint fps);
    ClutterTimeline*    clutter_timeline_new_for_duration   (guint msecs);
    ClutterTimeline*    clutter_timeline_clone              (ClutterTimeline *timeline);

    void                clutter_timeline_set_speed          (ClutterTimeline *timeline,
                                                             guint fps);
    guint               clutter_timeline_get_speed          (ClutterTimeline *timeline);
    void                clutter_timeline_set_duration       (ClutterTimeline *timeline,
                                                             guint msecs);
    guint               clutter_timeline_get_duration       (ClutterTimeline *timeline);
    void                clutter_timeline_set_loop           (ClutterTimeline *timeline,
                                                             gboolean loop);
    gboolean            clutter_timeline_get_loop           (ClutterTimeline *timeline);
    void                clutter_timeline_set_n_frames       (ClutterTimeline *timeline,
                                                             guint n_frames);
    guint               clutter_timeline_get_n_frames       (ClutterTimeline *timeline);
    void                clutter_timeline_set_delay          (ClutterTimeline *timeline,
                                                             guint msecs);
    guint               clutter_timeline_get_delay          (ClutterTimeline *timeline);
    enum                ClutterTimelineDirection;
    void                clutter_timeline_set_direction      (ClutterTimeline *timeline,
                                                             ClutterTimelineDirection direction);
    ClutterTimelineDirection clutter_timeline_get_direction (ClutterTimeline *timeline);

    void                clutter_timeline_start              (ClutterTimeline *timeline);
    void                clutter_timeline_pause              (ClutterTimeline *timeline);
    void                clutter_timeline_stop               (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);
    guint               clutter_timeline_get_delta          (ClutterTimeline *timeline,
                                                             guint *msecs);
    gdouble             clutter_timeline_get_progress       (ClutterTimeline *timeline);
    ClutterFixed        clutter_timeline_get_progressx      (ClutterTimeline *timeline);
    gboolean            clutter_timeline_is_playing         (ClutterTimeline *timeline);

    void                clutter_timeline_add_marker_at_frame
                                                            (ClutterTimeline *timeline,
                                                             const gchar *marker_name,
                                                             guint frame_num);
    void                clutter_timeline_add_marker_at_time (ClutterTimeline *timeline,
                                                             const gchar *marker_name,
                                                             guint msecs);
    gboolean            clutter_timeline_has_marker         (ClutterTimeline *timeline,
                                                             const gchar *marker_name);
    gchar**             clutter_timeline_list_markers       (ClutterTimeline *timeline,
                                                             gint frame_num,
                                                             gsize *n_markers);
    void                clutter_timeline_remove_marker      (ClutterTimeline *timeline,
                                                             const gchar *marker_name);
    void                clutter_timeline_advance_to_marker  (ClutterTimeline *timeline,
                                                             const gchar *marker_name);

## Object Hierarchy

      GObject
       +----ClutterTimeline

## Properties

      "delay"                    guint                 : Read / Write
      "direction"                ClutterTimelineDirection  : Read / Write
      "duration"                 guint                 : Read / Write
      "fps"                      guint                 : Read / Write
      "loop"                     gboolean              : Read / Write
      "num-frames"               guint                 : Read / Write

## Signals

      "completed"                                      : Run Last
      "marker-reached"                                 : Run Last / No Recursion / Has Details / No Hooks
      "new-frame"                                      : Run Last
      "paused"                                         : Run Last
      "started"                                        : Run Last

## Description

ClutterTimeline is a base class for managing time based events such as animations.

Every timeline shares the same ClutterTimeoutPool to decrease the possibility of starving the main loop when using many timelines at the same time; this might cause problems if you are also using a library making heavy use of threads with no GLib main loop integration.

In that case you might disable the common timeline pool by setting the `CLUTTER_TIMELINE`=no-pool environment variable prior to launching your application.

One way to visualise a timeline is as a path with marks along its length. When creating a timeline of `n_frames` via `clutter_timeline_new()`, then the number of frames can be seen as the paths length, and each unit of length (each frame) is delimited by a mark.

For a non looping timeline there will be (n_frames + 1) marks along its length. For a looping timeline, the two ends are joined with one mark. Technically this mark represents two discrete frame numbers, but for a looping timeline the start and end frame numbers are considered equivalent.

When you create a timeline it starts with `clutter_timeline_get_current_frame()` == 0.

After starting a timeline, the first timeout is for current_frame_num == 1 (Notably it isn't 0 since there is a delay before the first timeout signals so re-asserting the starting frame (0) wouldn't make sense.) Notably, this implies that actors you intend to be affected by the timeline's progress, should be manually primed/positioned for frame 0 which will be displayed before the first timeout. (If you are not careful about this point you will likely see flashes of incorrect actor state in your program)

For a non looping timeline the last timeout would be for current_frame_num == `n_frames`

For a looping timeline the timeout for current_frame_num == `n_frames` would be followed by a timeout for current_frame_num == 1 (remember frame 0 is considered == frame (`n_frames`)).

There may be times when a system is not able to meet the frame rate requested for a timeline, and in this case the frame number will be interpolated at the next timeout event. The interpolation is calculated from the time that the timeline was started, not from the time of the last timeout, so a given timeline should basically elapse in the same - real world - time on any given system. An invariable here though is that current_frame_num == `n_frames` will always be signaled, but notably frame 1 can be interpolated past and so never signaled.

## Details

### ClutterTimeline

    typedef struct _ClutterTimeline ClutterTimeline;

### ClutterTimelineClass

    typedef struct {
      void (*started)        (ClutterTimeline *timeline);
      void (*completed)      (ClutterTimeline *timeline);
      void (*paused)         (ClutterTimeline *timeline);

      void (*new_frame)      (ClutterTimeline *timeline,
    		          gint             frame_num);

      void (*marker_reached) (ClutterTimeline *timeline,
                              const gchar     *marker_name,
                              gint             frame_num);
    } ClutterTimelineClass;

### clutter_timeline_new ()

    ClutterTimeline*    clutter_timeline_new                (guint n_frames,
                                                             guint fps);

Create a new ClutterTimeline instance.

`n_frames` : | the number of frames
`fps` : | the number of frames per second
Returns : | a new ClutterTimeline

### clutter_timeline_new_for_duration ()

    ClutterTimeline*    clutter_timeline_new_for_duration   (guint msecs);

Creates a new ClutterTimeline with a duration of `msecs` using the value of the ClutterTimeline:fps property to compute the equivalent number of frames.

`msecs` : | Duration of the timeline in milliseconds
Returns : | the newly created ClutterTimeline

Since 0.6

### clutter_timeline_clone ()

    ClutterTimeline*    clutter_timeline_clone              (ClutterTimeline *timeline);

Create a new ClutterTimeline instance which has property values matching that of supplied timeline. The cloned timeline will not be started and will not be positioned to the current position of `timeline`: you will have to start it with `clutter_timeline_start()`.

`timeline` : | ClutterTimeline to duplicate.
Returns : | a new ClutterTimeline, cloned from `timeline` Since 0.4

### clutter_timeline_set_speed ()

    void                clutter_timeline_set_speed          (ClutterTimeline *timeline,
                                                             guint fps);

Set the speed in frames per second of the timeline.

`timeline` : | A ClutterTimeline
`fps` : | New speed of timeline as frames per second

### clutter_timeline_get_speed ()

    guint               clutter_timeline_get_speed          (ClutterTimeline *timeline);

Gets the frames per second played by `timeline`

`timeline` : | a ClutterTimeline
Returns : | the number of frames per second.

### clutter_timeline_set_duration ()

    void                clutter_timeline_set_duration       (ClutterTimeline *timeline,
                                                             guint msecs);

Sets the duration of the timeline, in milliseconds. The speed of the timeline depends on the ClutterTimeline:fps setting.

`timeline` : | a ClutterTimeline
`msecs` : | duration of the timeline in milliseconds

Since 0.6

### clutter_timeline_get_duration ()

    guint               clutter_timeline_get_duration       (ClutterTimeline *timeline);

Retrieves the duration of a ClutterTimeline in milliseconds. See `clutter_timeline_set_duration()`.

`timeline` : | a ClutterTimeline
Returns : | the duration of the timeline, in milliseconds.

Since 0.6

### clutter_timeline_set_loop ()

    void                clutter_timeline_set_loop           (ClutterTimeline *timeline,
                                                             gboolean loop);

Sets whether `timeline` should loop.

`timeline` : | a ClutterTimeline
`loop` : | `TRUE` for enable looping

### clutter_timeline_get_loop ()

    gboolean            clutter_timeline_get_loop           (ClutterTimeline *timeline);

Gets whether `timeline` is looping

`timeline` : | a ClutterTimeline
Returns : | `TRUE` if the timeline is looping

### clutter_timeline_set_n_frames ()

    void                clutter_timeline_set_n_frames       (ClutterTimeline *timeline,
                                                             guint n_frames);

Sets the total number of frames for `timeline`

`timeline` : | a ClutterTimeline
`n_frames` : | the number of frames

### clutter_timeline_get_n_frames ()

    guint               clutter_timeline_get_n_frames       (ClutterTimeline *timeline);

Request the total number of frames for the ClutterTimeline.

`timeline` : | A ClutterTimeline
Returns : | Number of frames for this ClutterTimeline.

### clutter_timeline_set_delay ()

    void                clutter_timeline_set_delay          (ClutterTimeline *timeline,
                                                             guint msecs);

Sets the delay, in milliseconds, before `timeline` should start.

`timeline` : | a ClutterTimeline
`msecs` : | delay in milliseconds

Since 0.4

### clutter_timeline_get_delay ()

    guint               clutter_timeline_get_delay          (ClutterTimeline *timeline);

Retrieves the delay set using `clutter_timeline_set_delay()`.

`timeline` : | a ClutterTimeline
Returns : | the delay in milliseconds.

Since 0.4

### enum ClutterTimelineDirection

    typedef enum {
      CLUTTER_TIMELINE_FORWARD,
      CLUTTER_TIMELINE_BACKWARD
    } ClutterTimelineDirection;

The direction of a ClutterTimeline

`CLUTTER_TIMELINE_FORWARD` | forward direction for a timeline
`CLUTTER_TIMELINE_BACKWARD` | backward direction for a timeline

Since 0.6

### clutter_timeline_set_direction ()

    void                clutter_timeline_set_direction      (ClutterTimeline *timeline,
                                                             ClutterTimelineDirection direction);

Sets the direction of `timeline`, either `CLUTTER_TIMELINE_FORWARD` or `CLUTTER_TIMELINE_BACKWARD`.

`timeline` : | a ClutterTimeline
`direction` : | the direction of the timeline

Since 0.6

### clutter_timeline_get_direction ()

    ClutterTimelineDirection clutter_timeline_get_direction (ClutterTimeline *timeline);

Retrieves the direction of the timeline set with `clutter_timeline_set_direction()`.

`timeline` : | a ClutterTimeline
Returns : | the direction of the timeline

Since 0.6

### clutter_timeline_start ()

    void                clutter_timeline_start              (ClutterTimeline *timeline);

Starts the ClutterTimeline playing.

`timeline` : | A ClutterTimeline

### clutter_timeline_pause ()

    void                clutter_timeline_pause              (ClutterTimeline *timeline);

Pauses the ClutterTimeline on current frame

`timeline` : | A ClutterTimeline

### clutter_timeline_stop ()

    void                clutter_timeline_stop               (ClutterTimeline *timeline);

Stops the ClutterTimeline and moves to frame 0

`timeline` : | A ClutterTimeline

### clutter_timeline_rewind ()

    void                clutter_timeline_rewind             (ClutterTimeline *timeline);

Rewinds ClutterTimeline to the first frame if its direction is CLUTTER_TIMELINE_FORWARD and the last frame if it is CLUTTER_TIMELINE_BACKWARD.

`timeline` : | A ClutterTimeline

### clutter_timeline_skip ()

    void                clutter_timeline_skip               (ClutterTimeline *timeline,
                                                             guint n_frames);

Advance timeline by requested number of frames.

`timeline` : | A ClutterTimeline
`n_frames` : | Number of frames to skip

### clutter_timeline_advance ()

    void                clutter_timeline_advance            (ClutterTimeline *timeline,
                                                             guint frame_num);

Advance timeline to requested frame number

`timeline` : | A ClutterTimeline
`frame_num` : | Frame number to advance to

### clutter_timeline_get_current_frame ()

    gint                clutter_timeline_get_current_frame  (ClutterTimeline *timeline);

Request the current frame number of the timeline.

`timeline` : | A ClutterTimeline
Returns : | current frame number

### clutter_timeline_get_delta ()

    guint               clutter_timeline_get_delta          (ClutterTimeline *timeline,
                                                             guint *msecs);

Retrieves the number of frames and the amount of time elapsed since the last ClutterTimeline::new-frame signal.

This function is only useful inside handlers for the ::new-frame signal, and its behaviour is undefined if the timeline is not playing.

`timeline` : | a ClutterTimeline
`msecs` : | return location for the milliseconds elapsed since the last frame, or `NULL`
Returns : | the amount of frames elapsed since the last one

Since 0.6

### clutter_timeline_get_progress ()

    gdouble             clutter_timeline_get_progress       (ClutterTimeline *timeline);

The position of the timeline in a [0, 1] interval.

`timeline` : | a ClutterTimeline
Returns : | the position of the timeline.

Since 0.6

### clutter_timeline_get_progressx ()

    ClutterFixed        clutter_timeline_get_progressx      (ClutterTimeline *timeline);

Fixed point version of `clutter_timeline_get_progress()`.

`timeline` : | a ClutterTimeline
Returns : | the position of the timeline as a fixed point value

Since 0.6

### clutter_timeline_is_playing ()

    gboolean            clutter_timeline_is_playing         (ClutterTimeline *timeline);

Query state of a ClutterTimeline instance.

`timeline` : | A ClutterTimeline
Returns : | TRUE if timeline is currently playing, FALSE if not.

### clutter_timeline_add_marker_at_frame ()

    void                clutter_timeline_add_marker_at_frame
                                                            (ClutterTimeline *timeline,
                                                             const gchar *marker_name,
                                                             guint frame_num);

Adds a named marker at `frame_num`. Markers are unique string identifiers for a specific frame. Once `timeline` reaches `frame_num`, it will emit a ::marker-reached signal for each marker attached to that frame.

A marker can be removed with `clutter_timeline_remove_marker()`. The timeline can be advanced to a marker using `clutter_timeline_advance_to_marker()`.

`timeline` : | a ClutterTimeline
`marker_name` : | the unique name for this marker
`frame_num` : | the marker's frame

Since 0.8

### clutter_timeline_add_marker_at_time ()

    void                clutter_timeline_add_marker_at_time (ClutterTimeline *timeline,
                                                             const gchar *marker_name,
                                                             guint msecs);

Time-based variant of `clutter_timeline_add_marker_at_frame()`.

Adds a named marker at `msecs`.

`timeline` : | a ClutterTimeline
`marker_name` : | the unique name for this marker
`msecs` : | position of the marker in milliseconds

Since 0.8

### clutter_timeline_has_marker ()

    gboolean            clutter_timeline_has_marker         (ClutterTimeline *timeline,
                                                             const gchar *marker_name);

Checks whether `timeline` has a marker set with the given name.

`timeline` : | a ClutterTimeline
`marker_name` : | the name of the marker
Returns : | `TRUE` if the marker was found

Since 0.8

### clutter_timeline_list_markers ()

    gchar**             clutter_timeline_list_markers       (ClutterTimeline *timeline,
                                                             gint frame_num,
                                                             gsize *n_markers);

Retrieves the list of markers at `frame_num`. If `frame_num` is a negative integer, all the markers attached to `timeline` will be returned.

`timeline` : | a ClutterTimeline
`frame_num` : | the frame number to check, or -1
`n_markers` : | the number of markers returned
Returns : | a newly allocated, `NULL` terminated string array containing the names of the markers. Use `g_strfreev()` when done.

Since 0.8

### clutter_timeline_remove_marker ()

    void                clutter_timeline_remove_marker      (ClutterTimeline *timeline,
                                                             const gchar *marker_name);

Removes `marker_name`, if found, from `timeline`.

`timeline` : | a ClutterTimeline
`marker_name` : | the name of the marker to remove

Since 0.8

### clutter_timeline_advance_to_marker ()

    void                clutter_timeline_advance_to_marker  (ClutterTimeline *timeline,
                                                             const gchar *marker_name);

Advances `timeline` to the frame of the given `marker_name`.

`timeline` : | a ClutterTimeline
`marker_name` : | the name of the marker

Since 0.8

## Property Details

### The `"delay"` property

      "delay"                    guint                 : Read / Write

A delay, in milliseconds, that should be observed by the timeline before actually starting.

Default value: 0

Since 0.4

### The `"direction"` property

      "direction"                ClutterTimelineDirection  : Read / Write

The direction of the timeline, either `CLUTTER_TIMELINE_FORWARD` or `CLUTTER_TIMELINE_BACKWARD`.

Default value: CLUTTER_TIMELINE_FORWARD

Since 0.6

### The `"duration"` property

      "duration"                 guint                 : Read / Write

Duration of the timeline in milliseconds, depending on the ClutterTimeline:fps value.

Default value: 1000

Since 0.6

### The `"fps"` property

      "fps"                      guint                 : Read / Write

Timeline frames per second. Because of the nature of the main loop used by Clutter this is to be considered a best approximation.

Allowed values: >= 1

Default value: 60

### The `"loop"` property

      "loop"                     gboolean              : Read / Write

Whether the timeline should automatically rewind and restart.

Default value: FALSE

### The `"num-frames"` property

      "num-frames"               guint                 : Read / Write

Total number of frames for the timeline.

Allowed values: >= 1

Default value: 1

## Signal Details

### The `"completed"` signal

    void                user_function                      (ClutterTimeline *timeline,
                                                            gpointer         user_data)      : Run Last

The ::completed signal is emitted when the timeline reaches the number of frames specified by the ClutterTimeline:num-frames property.

`timeline` : | the ClutterTimeline which received the signal
`user_data` : | user data set when the signal handler was connected.

### The `"marker-reached"` signal

    void                user_function                      (ClutterTimeline *timeline,
                                                            gchar           *marker_name,
                                                            gint             frame_num,
                                                            gpointer         user_data)        : Run Last / No Recursion / Has Details / No Hooks

The ::marker-reached signal is emitted each time a timeline reaches a marker set with `clutter_timeline_add_marker_at_frame()` or `clutter_timeline_add_marker_at_time()`. This signal is detailed with the name of the marker as well, so it is possible to connect a callback to the ::marker-reached signal for a specific marker with:

      clutter_timeline_add_marker_at_frame (timeline, "foo", 24);
      clutter_timeline_add_marker_at_frame (timeline, "bar", 48);

      g_signal_connect (timeline, "marker-reached",
                        G_CALLBACK (each_marker_reached), NULL);
      g_signal_connect (timeline, "marker-reached::foo",
                        G_CALLBACK (foo_marker_reached), NULL);
      g_signal_connect (timeline, "marker-reached::bar",
                        G_CALLBACK (bar_marker_reached), NULL);

In the example, the first callback will be invoked for both the "foo" and "bar" marker, while the second and third callbacks will be invoked for the "foo" or "bar" markers, respectively.

`timeline` : | the ClutterTimeline which received the signal
`marker_name` : | the name of the marker reached
`frame_num` : | the frame number
`user_data` : | user data set when the signal handler was connected.

Since 0.8

### The `"new-frame"` signal

    void                user_function                      (ClutterTimeline *timeline,
                                                            gint             frame_num,
                                                            gpointer         user_data)      : Run Last

The ::new-frame signal is emitted each time a new frame in the timeline is reached.

`timeline` : | the timeline which received the signal
`frame_num` : | the number of the new frame between 0 and ClutterTimeline:num-frames
`user_data` : | user data set when the signal handler was connected.

### The `"paused"` signal

    void                user_function                      (ClutterTimeline *timeline,
                                                            gpointer         user_data)      : Run Last

The ::paused signal is emitted when `clutter_timeline_pause()` is invoked.

`timeline` : | the ClutterTimeline which received the signal
`user_data` : | user data set when the signal handler was connected.

### The `"started"` signal

    void                user_function                      (ClutterTimeline *timeline,
                                                            gpointer         user_data)      : Run Last

The ::started signal is emitted when the timeline starts its run. This might be as soon as `clutter_timeline_start()` is invoked or after the delay set in the ClutterTimeline:delay property has expired.

`timeline` : | the ClutterTimeline which received the signal
`user_data` : | user data set when the signal handler was connected.