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}