Skip to main content

clutter/auto/
timeline.rs

1// Scriptable
2use crate::{AnimationMode, Point, StepMode, TimelineDirection};
3use glib::{
4    object::{Cast, IsA},
5    signal::{connect_raw, SignalHandlerId},
6    translate::*,
7    GString,
8};
9use std::boxed::Box as Box_;
10use std::{fmt, mem, mem::transmute};
11
12// TODO: @implements Scriptable
13glib_wrapper! {
14    pub struct Timeline(Object<ffi::ClutterTimeline, ffi::ClutterTimelineClass, TimelineClass>);
15
16    match fn {
17        get_type => || ffi::clutter_timeline_get_type(),
18    }
19}
20
21impl Timeline {
22    /// Creates a new `Timeline` with a duration of `msecs`.
23    /// ## `msecs`
24    /// Duration of the timeline in milliseconds
25    ///
26    /// # Returns
27    ///
28    /// the newly created `Timeline` instance. Use
29    ///  `gobject::ObjectExt::unref` when done using it
30    pub fn new(msecs: u32) -> Timeline {
31        unsafe { from_glib_full(ffi::clutter_timeline_new(msecs)) }
32    }
33}
34
35pub const NONE_TIMELINE: Option<&Timeline> = None;
36
37/// Trait containing all `Timeline` methods.
38///
39/// # Implementors
40///
41/// [`Timeline`](struct.Timeline.html), [`Transition`](struct.Transition.html)
42pub trait TimelineExt: 'static {
43    /// Adds a named marker that will be hit when the timeline has reached
44    /// the specified `progress`.
45    ///
46    /// Markers are unique string identifiers for a given position on the
47    /// timeline. Once `self` reaches the given `progress` of its duration,
48    /// if will emit a ::marker-reached signal for each marker attached to
49    /// that particular point.
50    ///
51    /// A marker can be removed with `TimelineExt::remove_marker`. The
52    /// timeline can be advanced to a marker using
53    /// `TimelineExt::advance_to_marker`.
54    ///
55    /// See also: `TimelineExt::add_marker_at_time`
56    /// ## `marker_name`
57    /// the unique name for this marker
58    /// ## `progress`
59    /// the normalized value of the position of the martke
60    fn add_marker(&self, marker_name: &str, progress: f64);
61
62    /// Adds a named marker that will be hit when the timeline has been
63    /// running for `msecs` milliseconds.
64    ///
65    /// Markers are unique string identifiers for a given position on the
66    /// timeline. Once `self` reaches the given `msecs`, it will emit
67    /// a ::marker-reached signal for each marker attached to that position.
68    ///
69    /// A marker can be removed with `TimelineExt::remove_marker`. The
70    /// timeline can be advanced to a marker using
71    /// `TimelineExt::advance_to_marker`.
72    ///
73    /// See also: `TimelineExt::add_marker`
74    /// ## `marker_name`
75    /// the unique name for this marker
76    /// ## `msecs`
77    /// position of the marker in milliseconds
78    fn add_marker_at_time(&self, marker_name: &str, msecs: u32);
79
80    /// Advance timeline to the requested point. The point is given as a
81    /// time in milliseconds since the timeline started.
82    ///
83    /// The `self` will not emit the `Timeline::new-frame`
84    /// signal for the given time. The first ::new-frame signal after the call to
85    /// `TimelineExt::advance` will be emit the skipped markers.
86    /// ## `msecs`
87    /// Time to advance to
88    fn advance(&self, msecs: u32);
89
90    /// Advances `self` to the time of the given `marker_name`.
91    ///
92    /// Like `TimelineExt::advance`, this function will not
93    /// emit the `Timeline::new-frame` for the time where `marker_name`
94    /// is set, nor it will emit `Timeline::marker-reached` for
95    /// `marker_name`.
96    /// ## `marker_name`
97    /// the name of the marker
98    fn advance_to_marker(&self, marker_name: &str);
99
100    /// Retrieves the value set by `TimelineExt::set_auto_reverse`.
101    ///
102    /// # Returns
103    ///
104    /// `true` if the timeline should automatically reverse, and
105    ///  `false` otherwise
106    fn get_auto_reverse(&self) -> bool;
107
108    /// Retrieves the control points for the cubic bezier progress mode.
109    /// ## `c_1`
110    /// return location for the first control
111    ///  point of the cubic bezier, or `None`
112    /// ## `c_2`
113    /// return location for the second control
114    ///  point of the cubic bezier, or `None`
115    ///
116    /// # Returns
117    ///
118    /// `true` if the `self` is using a cubic bezier progress
119    ///  more, and `false` otherwise
120    fn get_cubic_bezier_progress(&self) -> Option<(Point, Point)>;
121
122    /// Retrieves the current repeat for a timeline.
123    ///
124    /// Repeats start at 0.
125    ///
126    /// # Returns
127    ///
128    /// the current repeat
129    fn get_current_repeat(&self) -> i32;
130
131    /// Retrieves the delay set using `TimelineExt::set_delay`.
132    ///
133    /// # Returns
134    ///
135    /// the delay in milliseconds.
136    fn get_delay(&self) -> u32;
137
138    /// Retrieves the amount of time elapsed since the last
139    /// ClutterTimeline::new-frame signal.
140    ///
141    /// This function is only useful inside handlers for the ::new-frame
142    /// signal, and its behaviour is undefined if the timeline is not
143    /// playing.
144    ///
145    /// # Returns
146    ///
147    /// the amount of time in milliseconds elapsed since the
148    /// last frame
149    fn get_delta(&self) -> u32;
150
151    /// Retrieves the direction of the timeline set with
152    /// `TimelineExt::set_direction`.
153    ///
154    /// # Returns
155    ///
156    /// the direction of the timeline
157    fn get_direction(&self) -> TimelineDirection;
158
159    /// Retrieves the duration of a `Timeline` in milliseconds.
160    /// See `TimelineExt::set_duration`.
161    ///
162    /// # Returns
163    ///
164    /// the duration of the timeline, in milliseconds.
165    fn get_duration(&self) -> u32;
166
167    /// Retrieves the full duration of the `self`, taking into account the
168    /// current value of the `Timeline:repeat-count` property.
169    ///
170    /// If the `Timeline:repeat-count` property is set to -1, this function
171    /// will return `G_MAXINT64`.
172    ///
173    /// The returned value is to be considered a hint, and it's only valid
174    /// as long as the `self` hasn't been changed.
175    ///
176    /// # Returns
177    ///
178    /// the full duration of the `Timeline`
179    fn get_duration_hint(&self) -> i64;
180
181    /// Request the current time position of the timeline.
182    ///
183    /// # Returns
184    ///
185    /// current elapsed time in milliseconds.
186    fn get_elapsed_time(&self) -> u32;
187
188    /// The position of the timeline in a normalized [-1, 2] interval.
189    ///
190    /// The return value of this function is determined by the progress
191    /// mode set using `TimelineExt::set_progress_mode`, or by the
192    /// progress function set using `TimelineExt::set_progress_func`.
193    ///
194    /// # Returns
195    ///
196    /// the normalized current position in the timeline.
197    fn get_progress(&self) -> f64;
198
199    /// Retrieves the progress mode set using `TimelineExt::set_progress_mode`
200    /// or `TimelineExt::set_progress_func`.
201    ///
202    /// # Returns
203    ///
204    /// a `AnimationMode`
205    fn get_progress_mode(&self) -> AnimationMode;
206
207    /// Retrieves the number set using `TimelineExt::set_repeat_count`.
208    ///
209    /// # Returns
210    ///
211    /// the number of repeats
212    fn get_repeat_count(&self) -> i32;
213
214    /// Retrieves the parameters of the step progress mode used by `self`.
215    /// ## `n_steps`
216    /// return location for the number of steps, or `None`
217    /// ## `step_mode`
218    /// return location for the value change policy,
219    ///  or `None`
220    ///
221    /// # Returns
222    ///
223    /// `true` if the `self` is using a step progress
224    ///  mode, and `false` otherwise
225    fn get_step_progress(&self) -> Option<(i32, StepMode)>;
226
227    /// Checks whether `self` has a marker set with the given name.
228    /// ## `marker_name`
229    /// the name of the marker
230    ///
231    /// # Returns
232    ///
233    /// `true` if the marker was found
234    fn has_marker(&self, marker_name: &str) -> bool;
235
236    /// Queries state of a `Timeline`.
237    ///
238    /// # Returns
239    ///
240    /// `true` if timeline is currently playing
241    fn is_playing(&self) -> bool;
242
243    /// Retrieves the list of markers at time `msecs`. If `msecs` is a
244    /// negative integer, all the markers attached to `self` will be
245    /// returned.
246    /// ## `msecs`
247    /// the time to check, or -1
248    /// ## `n_markers`
249    /// the number of markers returned
250    ///
251    /// # Returns
252    ///
253    ///
254    ///  a newly allocated, `None` terminated string array containing the names
255    ///  of the markers. Use `g_strfreev` when done.
256    fn list_markers(&self, msecs: i32) -> Vec<GString>;
257
258    /// Pauses the `Timeline` on current frame
259    fn pause(&self);
260
261    /// Removes `marker_name`, if found, from `self`.
262    /// ## `marker_name`
263    /// the name of the marker to remove
264    fn remove_marker(&self, marker_name: &str);
265
266    /// Rewinds `Timeline` to the first frame if its direction is
267    /// `TimelineDirection::Forward` and the last frame if it is
268    /// `TimelineDirection::Backward`.
269    fn rewind(&self);
270
271    /// Sets whether `self` should reverse the direction after the
272    /// emission of the `Timeline::completed` signal.
273    ///
274    /// Setting the `Timeline:auto-reverse` property to `true` is the
275    /// equivalent of connecting a callback to the `Timeline::completed`
276    /// signal and changing the direction of the timeline from that callback;
277    /// for instance, this code:
278    ///
279    ///
280    /// ```text
281    /// static void
282    /// reverse_timeline (ClutterTimeline *timeline)
283    /// {
284    ///   ClutterTimelineDirection dir = clutter_timeline_get_direction (timeline);
285    ///
286    ///   if (dir == CLUTTER_TIMELINE_FORWARD)
287    ///     dir = CLUTTER_TIMELINE_BACKWARD;
288    ///   else
289    ///     dir = CLUTTER_TIMELINE_FORWARD;
290    ///
291    ///   clutter_timeline_set_direction (timeline, dir);
292    /// }
293    /// ...
294    ///   timeline = clutter_timeline_new (1000);
295    ///   clutter_timeline_set_repeat_count (timeline, -1);
296    ///   g_signal_connect (timeline, "completed",
297    ///                     G_CALLBACK (reverse_timeline),
298    ///                     NULL);
299    /// ```
300    ///
301    /// can be effectively replaced by:
302    ///
303    ///
304    /// ```text
305    ///   timeline = clutter_timeline_new (1000);
306    ///   clutter_timeline_set_repeat_count (timeline, -1);
307    ///   clutter_timeline_set_auto_reverse (timeline);
308    /// ```
309    /// ## `reverse`
310    /// `true` if the `self` should reverse the direction
311    fn set_auto_reverse(&self, reverse: bool);
312
313    /// Sets the `Timeline:progress-mode` of `self`
314    /// to `AnimationMode::CubicBezier`, and sets the two control
315    /// points for the cubic bezier.
316    ///
317    /// The cubic bezier curve is between (0, 0) and (1, 1). The X coordinate
318    /// of the two control points must be in the [ 0, 1 ] range, while the
319    /// Y coordinate of the two control points can exceed this range.
320    /// ## `c_1`
321    /// the first control point for the cubic bezier
322    /// ## `c_2`
323    /// the second control point for the cubic bezier
324    fn set_cubic_bezier_progress(&self, c_1: &Point, c_2: &Point);
325
326    /// Sets the delay, in milliseconds, before `self` should start.
327    /// ## `msecs`
328    /// delay in milliseconds
329    fn set_delay(&self, msecs: u32);
330
331    /// Sets the direction of `self`, either `TimelineDirection::Forward` or
332    /// `TimelineDirection::Backward`.
333    /// ## `direction`
334    /// the direction of the timeline
335    fn set_direction(&self, direction: TimelineDirection);
336
337    /// Sets the duration of the timeline, in milliseconds. The speed
338    /// of the timeline depends on the ClutterTimeline:fps setting.
339    /// ## `msecs`
340    /// duration of the timeline in milliseconds
341    fn set_duration(&self, msecs: u32);
342
343    /// Sets a custom progress function for `self`. The progress function will
344    /// be called by `TimelineExt::get_progress` and will be used to compute
345    /// the progress value based on the elapsed time and the total duration of the
346    /// timeline.
347    ///
348    /// If `func` is not `None`, the `Timeline:progress-mode` property will
349    /// be set to `AnimationMode::CustomMode`.
350    ///
351    /// If `func` is `None`, any previously set progress function will be unset, and
352    /// the `Timeline:progress-mode` property will be set to `AnimationMode::Linear`.
353    /// ## `func`
354    /// a progress function, or `None`
355    /// ## `data`
356    /// data to pass to `func`
357    /// ## `notify`
358    /// a function to be called when the progress function is removed
359    ///  or the timeline is disposed
360    fn set_progress_func(&self, func: Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>);
361
362    /// Sets the progress function using a value from the `AnimationMode`
363    /// enumeration. The `mode` cannot be `AnimationMode::CustomMode` or bigger than
364    /// `AnimationMode::AnimationLast`.
365    /// ## `mode`
366    /// the progress mode, as a `AnimationMode`
367    fn set_progress_mode(&self, mode: AnimationMode);
368
369    /// Sets the number of times the `self` should repeat.
370    ///
371    /// If `count` is 0, the timeline never repeats.
372    ///
373    /// If `count` is -1, the timeline will always repeat until
374    /// it's stopped.
375    /// ## `count`
376    /// the number of times the timeline should repeat
377    fn set_repeat_count(&self, count: i32);
378
379    /// Sets the `Timeline:progress-mode` of the `self` to `AnimationMode::Steps`
380    /// and provides the parameters of the step function.
381    /// ## `n_steps`
382    /// the number of steps
383    /// ## `step_mode`
384    /// whether the change should happen at the start
385    ///  or at the end of the step
386    fn set_step_progress(&self, n_steps: i32, step_mode: StepMode);
387
388    /// Advance timeline by the requested time in milliseconds
389    /// ## `msecs`
390    /// Amount of time to skip
391    fn skip(&self, msecs: u32);
392
393    /// Starts the `Timeline` playing.
394    fn start(&self);
395
396    /// Stops the `Timeline` and moves to frame 0
397    fn stop(&self);
398
399    /// The `Timeline::completed` signal is emitted when the timeline's
400    /// elapsed time reaches the value of the `Timeline:duration`
401    /// property.
402    ///
403    /// This signal will be emitted even if the `Timeline` is set to be
404    /// repeating.
405    ///
406    /// If you want to get notification on whether the `Timeline` has
407    /// been stopped or has finished its run, including its eventual repeats,
408    /// you should use the `Timeline::stopped` signal instead.
409    fn connect_completed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
410
411    /// The ::marker-reached signal is emitted each time a timeline
412    /// reaches a marker set with
413    /// `TimelineExt::add_marker_at_time`. This signal is detailed
414    /// with the name of the marker as well, so it is possible to connect
415    /// a callback to the ::marker-reached signal for a specific marker
416    /// with:
417    ///
418    /// `<informalexample>``<programlisting>`
419    ///  clutter_timeline_add_marker_at_time (timeline, "foo", 500);
420    ///  clutter_timeline_add_marker_at_time (timeline, "bar", 750);
421    ///
422    ///  g_signal_connect (timeline, "marker-reached",
423    ///  G_CALLBACK (each_marker_reached), NULL);
424    ///  g_signal_connect (timeline, "marker-reached::foo",
425    ///  G_CALLBACK (foo_marker_reached), NULL);
426    ///  g_signal_connect (timeline, "marker-reached::bar",
427    ///  G_CALLBACK (bar_marker_reached), NULL);
428    /// `</programlisting>``</informalexample>`
429    ///
430    /// In the example, the first callback will be invoked for both
431    /// the "foo" and "bar" marker, while the second and third callbacks
432    /// will be invoked for the "foo" or "bar" markers, respectively.
433    /// ## `marker_name`
434    /// the name of the marker reached
435    /// ## `msecs`
436    /// the elapsed time
437    fn connect_marker_reached<F: Fn(&Self, &str, i32) + 'static>(&self, f: F) -> SignalHandlerId;
438
439    /// The ::new-frame signal is emitted for each timeline running
440    /// timeline before a new frame is drawn to give animations a chance
441    /// to update the scene.
442    /// ## `msecs`
443    /// the elapsed time between 0 and duration
444    fn connect_new_frame<F: Fn(&Self, i32) + 'static>(&self, f: F) -> SignalHandlerId;
445
446    /// The ::paused signal is emitted when `TimelineExt::pause` is invoked.
447    fn connect_paused<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
448
449    /// The ::started signal is emitted when the timeline starts its run.
450    /// This might be as soon as `TimelineExt::start` is invoked or
451    /// after the delay set in the ClutterTimeline:delay property has
452    /// expired.
453    fn connect_started<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
454
455    /// The `Timeline::stopped` signal is emitted when the timeline
456    /// has been stopped, either because `TimelineExt::stop` has been
457    /// called, or because it has been exhausted.
458    ///
459    /// This is different from the `Timeline::completed` signal,
460    /// which gets emitted after every repeat finishes.
461    ///
462    /// If the `Timeline` has is marked as infinitely repeating,
463    /// this signal will never be emitted.
464    /// ## `is_finished`
465    /// `true` if the signal was emitted at the end of the
466    ///  timeline.
467    fn connect_stopped<F: Fn(&Self, bool) + 'static>(&self, f: F) -> SignalHandlerId;
468
469    fn connect_property_auto_reverse_notify<F: Fn(&Self) + 'static>(&self, f: F)
470        -> SignalHandlerId;
471
472    fn connect_property_delay_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
473
474    fn connect_property_direction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
475
476    fn connect_property_duration_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
477
478    fn connect_property_progress_mode_notify<F: Fn(&Self) + 'static>(
479        &self,
480        f: F,
481    ) -> SignalHandlerId;
482
483    fn connect_property_repeat_count_notify<F: Fn(&Self) + 'static>(&self, f: F)
484        -> SignalHandlerId;
485}
486
487impl<O: IsA<Timeline>> TimelineExt for O {
488    fn add_marker(&self, marker_name: &str, progress: f64) {
489        unsafe {
490            ffi::clutter_timeline_add_marker(
491                self.as_ref().to_glib_none().0,
492                marker_name.to_glib_none().0,
493                progress,
494            );
495        }
496    }
497
498    fn add_marker_at_time(&self, marker_name: &str, msecs: u32) {
499        unsafe {
500            ffi::clutter_timeline_add_marker_at_time(
501                self.as_ref().to_glib_none().0,
502                marker_name.to_glib_none().0,
503                msecs,
504            );
505        }
506    }
507
508    fn advance(&self, msecs: u32) {
509        unsafe {
510            ffi::clutter_timeline_advance(self.as_ref().to_glib_none().0, msecs);
511        }
512    }
513
514    fn advance_to_marker(&self, marker_name: &str) {
515        unsafe {
516            ffi::clutter_timeline_advance_to_marker(
517                self.as_ref().to_glib_none().0,
518                marker_name.to_glib_none().0,
519            );
520        }
521    }
522
523    fn get_auto_reverse(&self) -> bool {
524        unsafe {
525            from_glib(ffi::clutter_timeline_get_auto_reverse(
526                self.as_ref().to_glib_none().0,
527            ))
528        }
529    }
530
531    fn get_cubic_bezier_progress(&self) -> Option<(Point, Point)> {
532        unsafe {
533            let mut c_1 = Point::uninitialized();
534            let mut c_2 = Point::uninitialized();
535            let ret = from_glib(ffi::clutter_timeline_get_cubic_bezier_progress(
536                self.as_ref().to_glib_none().0,
537                c_1.to_glib_none_mut().0,
538                c_2.to_glib_none_mut().0,
539            ));
540            if ret {
541                Some((c_1, c_2))
542            } else {
543                None
544            }
545        }
546    }
547
548    fn get_current_repeat(&self) -> i32 {
549        unsafe { ffi::clutter_timeline_get_current_repeat(self.as_ref().to_glib_none().0) }
550    }
551
552    fn get_delay(&self) -> u32 {
553        unsafe { ffi::clutter_timeline_get_delay(self.as_ref().to_glib_none().0) }
554    }
555
556    fn get_delta(&self) -> u32 {
557        unsafe { ffi::clutter_timeline_get_delta(self.as_ref().to_glib_none().0) }
558    }
559
560    fn get_direction(&self) -> TimelineDirection {
561        unsafe {
562            from_glib(ffi::clutter_timeline_get_direction(
563                self.as_ref().to_glib_none().0,
564            ))
565        }
566    }
567
568    fn get_duration(&self) -> u32 {
569        unsafe { ffi::clutter_timeline_get_duration(self.as_ref().to_glib_none().0) }
570    }
571
572    fn get_duration_hint(&self) -> i64 {
573        unsafe { ffi::clutter_timeline_get_duration_hint(self.as_ref().to_glib_none().0) }
574    }
575
576    fn get_elapsed_time(&self) -> u32 {
577        unsafe { ffi::clutter_timeline_get_elapsed_time(self.as_ref().to_glib_none().0) }
578    }
579
580    fn get_progress(&self) -> f64 {
581        unsafe { ffi::clutter_timeline_get_progress(self.as_ref().to_glib_none().0) }
582    }
583
584    fn get_progress_mode(&self) -> AnimationMode {
585        unsafe {
586            from_glib(ffi::clutter_timeline_get_progress_mode(
587                self.as_ref().to_glib_none().0,
588            ))
589        }
590    }
591
592    fn get_repeat_count(&self) -> i32 {
593        unsafe { ffi::clutter_timeline_get_repeat_count(self.as_ref().to_glib_none().0) }
594    }
595
596    fn get_step_progress(&self) -> Option<(i32, StepMode)> {
597        unsafe {
598            let mut n_steps = mem::MaybeUninit::uninit();
599            let mut step_mode = mem::MaybeUninit::uninit();
600            let ret = from_glib(ffi::clutter_timeline_get_step_progress(
601                self.as_ref().to_glib_none().0,
602                n_steps.as_mut_ptr(),
603                step_mode.as_mut_ptr(),
604            ));
605            let n_steps = n_steps.assume_init();
606            let step_mode = step_mode.assume_init();
607            if ret {
608                Some((n_steps, from_glib(step_mode)))
609            } else {
610                None
611            }
612        }
613    }
614
615    fn has_marker(&self, marker_name: &str) -> bool {
616        unsafe {
617            from_glib(ffi::clutter_timeline_has_marker(
618                self.as_ref().to_glib_none().0,
619                marker_name.to_glib_none().0,
620            ))
621        }
622    }
623
624    fn is_playing(&self) -> bool {
625        unsafe {
626            from_glib(ffi::clutter_timeline_is_playing(
627                self.as_ref().to_glib_none().0,
628            ))
629        }
630    }
631
632    fn list_markers(&self, msecs: i32) -> Vec<GString> {
633        unsafe {
634            let mut n_markers = mem::MaybeUninit::uninit();
635            let ret = FromGlibContainer::from_glib_full_num(
636                ffi::clutter_timeline_list_markers(
637                    self.as_ref().to_glib_none().0,
638                    msecs,
639                    n_markers.as_mut_ptr(),
640                ),
641                n_markers.assume_init() as usize,
642            );
643            ret
644        }
645    }
646
647    fn pause(&self) {
648        unsafe {
649            ffi::clutter_timeline_pause(self.as_ref().to_glib_none().0);
650        }
651    }
652
653    fn remove_marker(&self, marker_name: &str) {
654        unsafe {
655            ffi::clutter_timeline_remove_marker(
656                self.as_ref().to_glib_none().0,
657                marker_name.to_glib_none().0,
658            );
659        }
660    }
661
662    fn rewind(&self) {
663        unsafe {
664            ffi::clutter_timeline_rewind(self.as_ref().to_glib_none().0);
665        }
666    }
667
668    fn set_auto_reverse(&self, reverse: bool) {
669        unsafe {
670            ffi::clutter_timeline_set_auto_reverse(
671                self.as_ref().to_glib_none().0,
672                reverse.to_glib(),
673            );
674        }
675    }
676
677    fn set_cubic_bezier_progress(&self, c_1: &Point, c_2: &Point) {
678        unsafe {
679            ffi::clutter_timeline_set_cubic_bezier_progress(
680                self.as_ref().to_glib_none().0,
681                c_1.to_glib_none().0,
682                c_2.to_glib_none().0,
683            );
684        }
685    }
686
687    fn set_delay(&self, msecs: u32) {
688        unsafe {
689            ffi::clutter_timeline_set_delay(self.as_ref().to_glib_none().0, msecs);
690        }
691    }
692
693    fn set_direction(&self, direction: TimelineDirection) {
694        unsafe {
695            ffi::clutter_timeline_set_direction(
696                self.as_ref().to_glib_none().0,
697                direction.to_glib(),
698            );
699        }
700    }
701
702    fn set_duration(&self, msecs: u32) {
703        unsafe {
704            ffi::clutter_timeline_set_duration(self.as_ref().to_glib_none().0, msecs);
705        }
706    }
707
708    fn set_progress_func(&self, func: Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>) {
709        let func_data: Box_<Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>> =
710            Box_::new(func);
711        unsafe extern "C" fn func_func(
712            timeline: *mut ffi::ClutterTimeline,
713            elapsed: libc::c_double,
714            total: libc::c_double,
715            user_data: glib_sys::gpointer,
716        ) -> libc::c_double {
717            let timeline = from_glib_borrow(timeline);
718            let callback: &Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>> =
719                &*(user_data as *mut _);
720            let res = if let Some(ref callback) = *callback {
721                callback(&timeline, elapsed, total)
722            } else {
723                panic!("cannot get closure...")
724            };
725            res
726        }
727        let func = if func_data.is_some() {
728            Some(func_func as _)
729        } else {
730            None
731        };
732        unsafe extern "C" fn notify_func(data: glib_sys::gpointer) {
733            let _callback: Box_<Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>> =
734                Box_::from_raw(data as *mut _);
735        }
736        let destroy_call3 = Some(notify_func as _);
737        let super_callback0: Box_<Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>> =
738            func_data;
739        unsafe {
740            ffi::clutter_timeline_set_progress_func(
741                self.as_ref().to_glib_none().0,
742                func,
743                Box_::into_raw(super_callback0) as *mut _,
744                destroy_call3,
745            );
746        }
747    }
748
749    fn set_progress_mode(&self, mode: AnimationMode) {
750        unsafe {
751            ffi::clutter_timeline_set_progress_mode(self.as_ref().to_glib_none().0, mode.to_glib());
752        }
753    }
754
755    fn set_repeat_count(&self, count: i32) {
756        unsafe {
757            ffi::clutter_timeline_set_repeat_count(self.as_ref().to_glib_none().0, count);
758        }
759    }
760
761    fn set_step_progress(&self, n_steps: i32, step_mode: StepMode) {
762        unsafe {
763            ffi::clutter_timeline_set_step_progress(
764                self.as_ref().to_glib_none().0,
765                n_steps,
766                step_mode.to_glib(),
767            );
768        }
769    }
770
771    fn skip(&self, msecs: u32) {
772        unsafe {
773            ffi::clutter_timeline_skip(self.as_ref().to_glib_none().0, msecs);
774        }
775    }
776
777    fn start(&self) {
778        unsafe {
779            ffi::clutter_timeline_start(self.as_ref().to_glib_none().0);
780        }
781    }
782
783    fn stop(&self) {
784        unsafe {
785            ffi::clutter_timeline_stop(self.as_ref().to_glib_none().0);
786        }
787    }
788
789    fn connect_completed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
790        unsafe extern "C" fn completed_trampoline<P, F: Fn(&P) + 'static>(
791            this: *mut ffi::ClutterTimeline,
792            f: glib_sys::gpointer,
793        ) where
794            P: IsA<Timeline>,
795        {
796            let f: &F = &*(f as *const F);
797            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
798        }
799        unsafe {
800            let f: Box_<F> = Box_::new(f);
801            connect_raw(
802                self.as_ptr() as *mut _,
803                b"completed\0".as_ptr() as *const _,
804                Some(transmute::<_, unsafe extern "C" fn()>(
805                    completed_trampoline::<Self, F> as *const (),
806                )),
807                Box_::into_raw(f),
808            )
809        }
810    }
811
812    fn connect_marker_reached<F: Fn(&Self, &str, i32) + 'static>(&self, f: F) -> SignalHandlerId {
813        unsafe extern "C" fn marker_reached_trampoline<P, F: Fn(&P, &str, i32) + 'static>(
814            this: *mut ffi::ClutterTimeline,
815            marker_name: *mut libc::c_char,
816            msecs: libc::c_int,
817            f: glib_sys::gpointer,
818        ) where
819            P: IsA<Timeline>,
820        {
821            let f: &F = &*(f as *const F);
822            f(
823                &Timeline::from_glib_borrow(this).unsafe_cast_ref(),
824                &GString::from_glib_borrow(marker_name),
825                msecs,
826            )
827        }
828        unsafe {
829            let f: Box_<F> = Box_::new(f);
830            connect_raw(
831                self.as_ptr() as *mut _,
832                b"marker-reached\0".as_ptr() as *const _,
833                Some(transmute::<_, unsafe extern "C" fn()>(
834                    marker_reached_trampoline::<Self, F> as *const (),
835                )),
836                Box_::into_raw(f),
837            )
838        }
839    }
840
841    fn connect_new_frame<F: Fn(&Self, i32) + 'static>(&self, f: F) -> SignalHandlerId {
842        unsafe extern "C" fn new_frame_trampoline<P, F: Fn(&P, i32) + 'static>(
843            this: *mut ffi::ClutterTimeline,
844            msecs: libc::c_int,
845            f: glib_sys::gpointer,
846        ) where
847            P: IsA<Timeline>,
848        {
849            let f: &F = &*(f as *const F);
850            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref(), msecs)
851        }
852        unsafe {
853            let f: Box_<F> = Box_::new(f);
854            connect_raw(
855                self.as_ptr() as *mut _,
856                b"new-frame\0".as_ptr() as *const _,
857                Some(transmute::<_, unsafe extern "C" fn()>(
858                    new_frame_trampoline::<Self, F> as *const (),
859                )),
860                Box_::into_raw(f),
861            )
862        }
863    }
864
865    fn connect_paused<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
866        unsafe extern "C" fn paused_trampoline<P, F: Fn(&P) + 'static>(
867            this: *mut ffi::ClutterTimeline,
868            f: glib_sys::gpointer,
869        ) where
870            P: IsA<Timeline>,
871        {
872            let f: &F = &*(f as *const F);
873            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
874        }
875        unsafe {
876            let f: Box_<F> = Box_::new(f);
877            connect_raw(
878                self.as_ptr() as *mut _,
879                b"paused\0".as_ptr() as *const _,
880                Some(transmute::<_, unsafe extern "C" fn()>(
881                    paused_trampoline::<Self, F> as *const (),
882                )),
883                Box_::into_raw(f),
884            )
885        }
886    }
887
888    fn connect_started<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
889        unsafe extern "C" fn started_trampoline<P, F: Fn(&P) + 'static>(
890            this: *mut ffi::ClutterTimeline,
891            f: glib_sys::gpointer,
892        ) where
893            P: IsA<Timeline>,
894        {
895            let f: &F = &*(f as *const F);
896            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
897        }
898        unsafe {
899            let f: Box_<F> = Box_::new(f);
900            connect_raw(
901                self.as_ptr() as *mut _,
902                b"started\0".as_ptr() as *const _,
903                Some(transmute::<_, unsafe extern "C" fn()>(
904                    started_trampoline::<Self, F> as *const (),
905                )),
906                Box_::into_raw(f),
907            )
908        }
909    }
910
911    fn connect_stopped<F: Fn(&Self, bool) + 'static>(&self, f: F) -> SignalHandlerId {
912        unsafe extern "C" fn stopped_trampoline<P, F: Fn(&P, bool) + 'static>(
913            this: *mut ffi::ClutterTimeline,
914            is_finished: glib_sys::gboolean,
915            f: glib_sys::gpointer,
916        ) where
917            P: IsA<Timeline>,
918        {
919            let f: &F = &*(f as *const F);
920            f(
921                &Timeline::from_glib_borrow(this).unsafe_cast_ref(),
922                from_glib(is_finished),
923            )
924        }
925        unsafe {
926            let f: Box_<F> = Box_::new(f);
927            connect_raw(
928                self.as_ptr() as *mut _,
929                b"stopped\0".as_ptr() as *const _,
930                Some(transmute::<_, unsafe extern "C" fn()>(
931                    stopped_trampoline::<Self, F> as *const (),
932                )),
933                Box_::into_raw(f),
934            )
935        }
936    }
937
938    fn connect_property_auto_reverse_notify<F: Fn(&Self) + 'static>(
939        &self,
940        f: F,
941    ) -> SignalHandlerId {
942        unsafe extern "C" fn notify_auto_reverse_trampoline<P, F: Fn(&P) + 'static>(
943            this: *mut ffi::ClutterTimeline,
944            _param_spec: glib_sys::gpointer,
945            f: glib_sys::gpointer,
946        ) where
947            P: IsA<Timeline>,
948        {
949            let f: &F = &*(f as *const F);
950            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
951        }
952        unsafe {
953            let f: Box_<F> = Box_::new(f);
954            connect_raw(
955                self.as_ptr() as *mut _,
956                b"notify::auto-reverse\0".as_ptr() as *const _,
957                Some(transmute::<_, unsafe extern "C" fn()>(
958                    notify_auto_reverse_trampoline::<Self, F> as *const (),
959                )),
960                Box_::into_raw(f),
961            )
962        }
963    }
964
965    fn connect_property_delay_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
966        unsafe extern "C" fn notify_delay_trampoline<P, F: Fn(&P) + 'static>(
967            this: *mut ffi::ClutterTimeline,
968            _param_spec: glib_sys::gpointer,
969            f: glib_sys::gpointer,
970        ) where
971            P: IsA<Timeline>,
972        {
973            let f: &F = &*(f as *const F);
974            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
975        }
976        unsafe {
977            let f: Box_<F> = Box_::new(f);
978            connect_raw(
979                self.as_ptr() as *mut _,
980                b"notify::delay\0".as_ptr() as *const _,
981                Some(transmute::<_, unsafe extern "C" fn()>(
982                    notify_delay_trampoline::<Self, F> as *const (),
983                )),
984                Box_::into_raw(f),
985            )
986        }
987    }
988
989    fn connect_property_direction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
990        unsafe extern "C" fn notify_direction_trampoline<P, F: Fn(&P) + 'static>(
991            this: *mut ffi::ClutterTimeline,
992            _param_spec: glib_sys::gpointer,
993            f: glib_sys::gpointer,
994        ) where
995            P: IsA<Timeline>,
996        {
997            let f: &F = &*(f as *const F);
998            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
999        }
1000        unsafe {
1001            let f: Box_<F> = Box_::new(f);
1002            connect_raw(
1003                self.as_ptr() as *mut _,
1004                b"notify::direction\0".as_ptr() as *const _,
1005                Some(transmute::<_, unsafe extern "C" fn()>(
1006                    notify_direction_trampoline::<Self, F> as *const (),
1007                )),
1008                Box_::into_raw(f),
1009            )
1010        }
1011    }
1012
1013    fn connect_property_duration_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1014        unsafe extern "C" fn notify_duration_trampoline<P, F: Fn(&P) + 'static>(
1015            this: *mut ffi::ClutterTimeline,
1016            _param_spec: glib_sys::gpointer,
1017            f: glib_sys::gpointer,
1018        ) where
1019            P: IsA<Timeline>,
1020        {
1021            let f: &F = &*(f as *const F);
1022            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
1023        }
1024        unsafe {
1025            let f: Box_<F> = Box_::new(f);
1026            connect_raw(
1027                self.as_ptr() as *mut _,
1028                b"notify::duration\0".as_ptr() as *const _,
1029                Some(transmute::<_, unsafe extern "C" fn()>(
1030                    notify_duration_trampoline::<Self, F> as *const (),
1031                )),
1032                Box_::into_raw(f),
1033            )
1034        }
1035    }
1036
1037    fn connect_property_progress_mode_notify<F: Fn(&Self) + 'static>(
1038        &self,
1039        f: F,
1040    ) -> SignalHandlerId {
1041        unsafe extern "C" fn notify_progress_mode_trampoline<P, F: Fn(&P) + 'static>(
1042            this: *mut ffi::ClutterTimeline,
1043            _param_spec: glib_sys::gpointer,
1044            f: glib_sys::gpointer,
1045        ) where
1046            P: IsA<Timeline>,
1047        {
1048            let f: &F = &*(f as *const F);
1049            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
1050        }
1051        unsafe {
1052            let f: Box_<F> = Box_::new(f);
1053            connect_raw(
1054                self.as_ptr() as *mut _,
1055                b"notify::progress-mode\0".as_ptr() as *const _,
1056                Some(transmute::<_, unsafe extern "C" fn()>(
1057                    notify_progress_mode_trampoline::<Self, F> as *const (),
1058                )),
1059                Box_::into_raw(f),
1060            )
1061        }
1062    }
1063
1064    fn connect_property_repeat_count_notify<F: Fn(&Self) + 'static>(
1065        &self,
1066        f: F,
1067    ) -> SignalHandlerId {
1068        unsafe extern "C" fn notify_repeat_count_trampoline<P, F: Fn(&P) + 'static>(
1069            this: *mut ffi::ClutterTimeline,
1070            _param_spec: glib_sys::gpointer,
1071            f: glib_sys::gpointer,
1072        ) where
1073            P: IsA<Timeline>,
1074        {
1075            let f: &F = &*(f as *const F);
1076            f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
1077        }
1078        unsafe {
1079            let f: Box_<F> = Box_::new(f);
1080            connect_raw(
1081                self.as_ptr() as *mut _,
1082                b"notify::repeat-count\0".as_ptr() as *const _,
1083                Some(transmute::<_, unsafe extern "C" fn()>(
1084                    notify_repeat_count_trampoline::<Self, F> as *const (),
1085                )),
1086                Box_::into_raw(f),
1087            )
1088        }
1089    }
1090}
1091
1092impl fmt::Display for Timeline {
1093    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1094        write!(f, "Timeline")
1095    }
1096}