use crate::{AnimationMode, InternalPoint, StepMode, TimelineDirection};
use glib::{
object::{Cast, IsA},
signal::{connect_raw, SignalHandlerId},
translate::*,
GString,
};
use std::boxed::Box as Box_;
use std::{fmt, mem, mem::transmute};
glib_wrapper! {
pub struct Timeline(Object<ffi::ClutterTimeline, ffi::ClutterTimelineClass, TimelineClass>);
match fn {
get_type => || ffi::clutter_timeline_get_type(),
}
}
impl Timeline {
pub fn new(msecs: u32) -> Timeline {
unsafe { from_glib_full(ffi::clutter_timeline_new(msecs)) }
}
}
pub trait TimelineExt: 'static {
fn add_marker(&self, marker_name: &str, progress: f64);
fn add_marker_at_time(&self, marker_name: &str, msecs: u32);
fn advance(&self, msecs: u32);
fn advance_to_marker(&self, marker_name: &str);
fn get_auto_reverse(&self) -> bool;
fn get_cubic_bezier_progress(&self) -> Option<(InternalPoint, InternalPoint)>;
fn get_current_repeat(&self) -> i32;
fn get_delay(&self) -> u32;
fn get_delta(&self) -> u32;
fn get_direction(&self) -> TimelineDirection;
fn get_duration(&self) -> u32;
fn get_duration_hint(&self) -> i64;
fn get_elapsed_time(&self) -> u32;
fn get_progress(&self) -> f64;
fn get_progress_mode(&self) -> AnimationMode;
fn get_repeat_count(&self) -> i32;
fn get_step_progress(&self) -> Option<(i32, StepMode)>;
fn has_marker(&self, marker_name: &str) -> bool;
fn is_playing(&self) -> bool;
fn list_markers(&self, msecs: i32) -> Vec<GString>;
fn pause(&self);
fn remove_marker(&self, marker_name: &str);
fn rewind(&self);
fn set_auto_reverse(&self, reverse: bool);
fn set_cubic_bezier_progress(&self, c_1: &InternalPoint, c_2: &InternalPoint);
fn set_delay(&self, msecs: u32);
fn set_direction(&self, direction: TimelineDirection);
fn set_duration(&self, msecs: u32);
fn set_progress_func(&self, func: Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>);
fn set_progress_mode(&self, mode: AnimationMode);
fn set_repeat_count(&self, count: i32);
fn set_step_progress(&self, n_steps: i32, step_mode: StepMode);
fn skip(&self, msecs: u32);
fn start(&self);
fn stop(&self);
fn connect_completed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_marker_reached<F: Fn(&Self, &str, i32) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_new_frame<F: Fn(&Self, i32) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_paused<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_started<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_stopped<F: Fn(&Self, bool) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_property_auto_reverse_notify<F: Fn(&Self) + 'static>(&self, f: F)
-> SignalHandlerId;
fn connect_property_delay_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_property_direction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_property_duration_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_property_progress_mode_notify<F: Fn(&Self) + 'static>(
&self,
f: F,
) -> SignalHandlerId;
fn connect_property_repeat_count_notify<F: Fn(&Self) + 'static>(&self, f: F)
-> SignalHandlerId;
}
impl<O: IsA<Timeline>> TimelineExt for O {
fn add_marker(&self, marker_name: &str, progress: f64) {
unsafe {
ffi::clutter_timeline_add_marker(
self.as_ref().to_glib_none().0,
marker_name.to_glib_none().0,
progress,
);
}
}
fn add_marker_at_time(&self, marker_name: &str, msecs: u32) {
unsafe {
ffi::clutter_timeline_add_marker_at_time(
self.as_ref().to_glib_none().0,
marker_name.to_glib_none().0,
msecs,
);
}
}
fn advance(&self, msecs: u32) {
unsafe {
ffi::clutter_timeline_advance(self.as_ref().to_glib_none().0, msecs);
}
}
fn advance_to_marker(&self, marker_name: &str) {
unsafe {
ffi::clutter_timeline_advance_to_marker(
self.as_ref().to_glib_none().0,
marker_name.to_glib_none().0,
);
}
}
fn get_auto_reverse(&self) -> bool {
unsafe {
from_glib(ffi::clutter_timeline_get_auto_reverse(
self.as_ref().to_glib_none().0,
))
}
}
fn get_cubic_bezier_progress(&self) -> Option<(InternalPoint, InternalPoint)> {
unsafe {
let mut c_1 = InternalPoint::uninitialized();
let mut c_2 = InternalPoint::uninitialized();
let ret = from_glib(ffi::clutter_timeline_get_cubic_bezier_progress(
self.as_ref().to_glib_none().0,
c_1.to_glib_none_mut().0,
c_2.to_glib_none_mut().0,
));
if ret {
Some((c_1, c_2))
} else {
None
}
}
}
fn get_current_repeat(&self) -> i32 {
unsafe { ffi::clutter_timeline_get_current_repeat(self.as_ref().to_glib_none().0) }
}
fn get_delay(&self) -> u32 {
unsafe { ffi::clutter_timeline_get_delay(self.as_ref().to_glib_none().0) }
}
fn get_delta(&self) -> u32 {
unsafe { ffi::clutter_timeline_get_delta(self.as_ref().to_glib_none().0) }
}
fn get_direction(&self) -> TimelineDirection {
unsafe {
from_glib(ffi::clutter_timeline_get_direction(
self.as_ref().to_glib_none().0,
))
}
}
fn get_duration(&self) -> u32 {
unsafe { ffi::clutter_timeline_get_duration(self.as_ref().to_glib_none().0) }
}
fn get_duration_hint(&self) -> i64 {
unsafe { ffi::clutter_timeline_get_duration_hint(self.as_ref().to_glib_none().0) }
}
fn get_elapsed_time(&self) -> u32 {
unsafe { ffi::clutter_timeline_get_elapsed_time(self.as_ref().to_glib_none().0) }
}
fn get_progress(&self) -> f64 {
unsafe { ffi::clutter_timeline_get_progress(self.as_ref().to_glib_none().0) }
}
fn get_progress_mode(&self) -> AnimationMode {
unsafe {
from_glib(ffi::clutter_timeline_get_progress_mode(
self.as_ref().to_glib_none().0,
))
}
}
fn get_repeat_count(&self) -> i32 {
unsafe { ffi::clutter_timeline_get_repeat_count(self.as_ref().to_glib_none().0) }
}
fn get_step_progress(&self) -> Option<(i32, StepMode)> {
unsafe {
let mut n_steps = mem::MaybeUninit::uninit();
let mut step_mode = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::clutter_timeline_get_step_progress(
self.as_ref().to_glib_none().0,
n_steps.as_mut_ptr(),
step_mode.as_mut_ptr(),
));
let n_steps = n_steps.assume_init();
let step_mode = step_mode.assume_init();
if ret {
Some((n_steps, from_glib(step_mode)))
} else {
None
}
}
}
fn has_marker(&self, marker_name: &str) -> bool {
unsafe {
from_glib(ffi::clutter_timeline_has_marker(
self.as_ref().to_glib_none().0,
marker_name.to_glib_none().0,
))
}
}
fn is_playing(&self) -> bool {
unsafe {
from_glib(ffi::clutter_timeline_is_playing(
self.as_ref().to_glib_none().0,
))
}
}
fn list_markers(&self, msecs: i32) -> Vec<GString> {
unsafe {
let mut n_markers = mem::MaybeUninit::uninit();
let ret = FromGlibContainer::from_glib_full_num(
ffi::clutter_timeline_list_markers(
self.as_ref().to_glib_none().0,
msecs,
n_markers.as_mut_ptr(),
),
n_markers.assume_init() as usize,
);
ret
}
}
fn pause(&self) {
unsafe {
ffi::clutter_timeline_pause(self.as_ref().to_glib_none().0);
}
}
fn remove_marker(&self, marker_name: &str) {
unsafe {
ffi::clutter_timeline_remove_marker(
self.as_ref().to_glib_none().0,
marker_name.to_glib_none().0,
);
}
}
fn rewind(&self) {
unsafe {
ffi::clutter_timeline_rewind(self.as_ref().to_glib_none().0);
}
}
fn set_auto_reverse(&self, reverse: bool) {
unsafe {
ffi::clutter_timeline_set_auto_reverse(
self.as_ref().to_glib_none().0,
reverse.to_glib(),
);
}
}
fn set_cubic_bezier_progress(&self, c_1: &InternalPoint, c_2: &InternalPoint) {
unsafe {
ffi::clutter_timeline_set_cubic_bezier_progress(
self.as_ref().to_glib_none().0,
c_1.to_glib_none().0,
c_2.to_glib_none().0,
);
}
}
fn set_delay(&self, msecs: u32) {
unsafe {
ffi::clutter_timeline_set_delay(self.as_ref().to_glib_none().0, msecs);
}
}
fn set_direction(&self, direction: TimelineDirection) {
unsafe {
ffi::clutter_timeline_set_direction(
self.as_ref().to_glib_none().0,
direction.to_glib(),
);
}
}
fn set_duration(&self, msecs: u32) {
unsafe {
ffi::clutter_timeline_set_duration(self.as_ref().to_glib_none().0, msecs);
}
}
fn set_progress_func(&self, func: Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>) {
let func_data: Box_<Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>> =
Box_::new(func);
unsafe extern "C" fn func_func(
timeline: *mut ffi::ClutterTimeline,
elapsed: libc::c_double,
total: libc::c_double,
user_data: glib_sys::gpointer,
) -> libc::c_double {
let timeline = from_glib_borrow(timeline);
let callback: &Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>> =
&*(user_data as *mut _);
let res = if let Some(ref callback) = *callback {
callback(&timeline, elapsed, total)
} else {
panic!("cannot get closure...")
};
res
}
let func = if func_data.is_some() {
Some(func_func as _)
} else {
None
};
unsafe extern "C" fn notify_func(data: glib_sys::gpointer) {
let _callback: Box_<Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>> =
Box_::from_raw(data as *mut _);
}
let destroy_call3 = Some(notify_func as _);
let super_callback0: Box_<Option<Box_<dyn Fn(&Timeline, f64, f64) -> f64 + 'static>>> =
func_data;
unsafe {
ffi::clutter_timeline_set_progress_func(
self.as_ref().to_glib_none().0,
func,
Box_::into_raw(super_callback0) as *mut _,
destroy_call3,
);
}
}
fn set_progress_mode(&self, mode: AnimationMode) {
unsafe {
ffi::clutter_timeline_set_progress_mode(self.as_ref().to_glib_none().0, mode.to_glib());
}
}
fn set_repeat_count(&self, count: i32) {
unsafe {
ffi::clutter_timeline_set_repeat_count(self.as_ref().to_glib_none().0, count);
}
}
fn set_step_progress(&self, n_steps: i32, step_mode: StepMode) {
unsafe {
ffi::clutter_timeline_set_step_progress(
self.as_ref().to_glib_none().0,
n_steps,
step_mode.to_glib(),
);
}
}
fn skip(&self, msecs: u32) {
unsafe {
ffi::clutter_timeline_skip(self.as_ref().to_glib_none().0, msecs);
}
}
fn start(&self) {
unsafe {
ffi::clutter_timeline_start(self.as_ref().to_glib_none().0);
}
}
fn stop(&self) {
unsafe {
ffi::clutter_timeline_stop(self.as_ref().to_glib_none().0);
}
}
fn connect_completed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn completed_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"completed\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
completed_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_marker_reached<F: Fn(&Self, &str, i32) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn marker_reached_trampoline<P, F: Fn(&P, &str, i32) + 'static>(
this: *mut ffi::ClutterTimeline,
marker_name: *mut libc::c_char,
msecs: libc::c_int,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(
&Timeline::from_glib_borrow(this).unsafe_cast_ref(),
&GString::from_glib_borrow(marker_name),
msecs,
)
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"marker-reached\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
marker_reached_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_new_frame<F: Fn(&Self, i32) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn new_frame_trampoline<P, F: Fn(&P, i32) + 'static>(
this: *mut ffi::ClutterTimeline,
msecs: libc::c_int,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref(), msecs)
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"new-frame\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
new_frame_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_paused<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn paused_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"paused\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
paused_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_started<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn started_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"started\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
started_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_stopped<F: Fn(&Self, bool) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn stopped_trampoline<P, F: Fn(&P, bool) + 'static>(
this: *mut ffi::ClutterTimeline,
is_finished: glib_sys::gboolean,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(
&Timeline::from_glib_borrow(this).unsafe_cast_ref(),
from_glib(is_finished),
)
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"stopped\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
stopped_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_property_auto_reverse_notify<F: Fn(&Self) + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_auto_reverse_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
_param_spec: glib_sys::gpointer,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::auto-reverse\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_auto_reverse_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_property_delay_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_delay_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
_param_spec: glib_sys::gpointer,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::delay\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_delay_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_property_direction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_direction_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
_param_spec: glib_sys::gpointer,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::direction\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_direction_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_property_duration_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_duration_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
_param_spec: glib_sys::gpointer,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::duration\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_duration_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_property_progress_mode_notify<F: Fn(&Self) + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_progress_mode_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
_param_spec: glib_sys::gpointer,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::progress-mode\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_progress_mode_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_property_repeat_count_notify<F: Fn(&Self) + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_repeat_count_trampoline<P, F: Fn(&P) + 'static>(
this: *mut ffi::ClutterTimeline,
_param_spec: glib_sys::gpointer,
f: glib_sys::gpointer,
) where
P: IsA<Timeline>,
{
let f: &F = &*(f as *const F);
f(&Timeline::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::repeat-count\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_repeat_count_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
}
impl fmt::Display for Timeline {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Timeline")
}
}