1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
use glib::{
    object::{Cast, IsA},
    translate::*,
};
use std::{fmt, mem};
// Scriptable
use crate::{AnimationMode, PropertyTransition, Timeline, Transition};

// TODO: , @implements Scriptable
glib_wrapper! {
    pub struct KeyframeTransition(Object<ffi::ClutterKeyframeTransition, ffi::ClutterKeyframeTransitionClass, KeyframeTransitionClass>) @extends PropertyTransition, Transition, Timeline;

    match fn {
        get_type => || ffi::clutter_keyframe_transition_get_type(),
    }
}

impl KeyframeTransition {
    /// Creates a new `KeyframeTransition` for `property_name`.
    /// ## `property_name`
    /// the property to animate
    ///
    /// # Returns
    ///
    /// the newly allocated
    ///  `KeyframeTransition` instance. Use `gobject::ObjectExt::unref` when
    ///  done to free its resources.
    pub fn new(property_name: &str) -> KeyframeTransition {
        unsafe {
            Transition::from_glib_full(ffi::clutter_keyframe_transition_new(
                property_name.to_glib_none().0,
            ))
            .unsafe_cast()
        }
    }
}

/// Trait containing all `KeyframeTransition` methods.
///
/// # Implementors
///
/// [`KeyframeTransition`](struct.KeyframeTransition.html)
pub trait KeyframeTransitionExt: 'static {
    /// Removes all key frames from `self`.
    fn clear(&self);

    /// Retrieves the details of the key frame at `index_` inside `self`.
    ///
    /// The `self` must already have key frames set, and `index_` must be
    /// smaller than the number of key frames.
    /// ## `index_`
    /// the index of the key frame
    /// ## `key`
    /// return location for the key, or `None`
    /// ## `mode`
    /// return location for the easing mode, or `None`
    /// ## `value`
    /// a `gobject::Value` initialized with the type of
    ///  the values
    fn get_key_frame(&self, index_: u32) -> (f64, AnimationMode, glib::Value);

    /// Retrieves the number of key frames inside `self`.
    ///
    /// # Returns
    ///
    /// the number of key frames
    fn get_n_key_frames(&self) -> u32;

    //fn set(&self, gtype: glib::types::Type, n_key_frames: u32, : /*Unknown conversion*//*Unimplemented*/Fundamental: VarArgs);

    /// Sets the details of the key frame at `index_` inside `self`.
    ///
    /// The `self` must already have a key frame at `index_`, and `index_`
    /// must be smaller than the number of key frames inside `self`.
    /// ## `index_`
    /// the index of the key frame
    /// ## `key`
    /// the key of the key frame
    /// ## `mode`
    /// the easing mode of the key frame
    /// ## `value`
    /// a `gobject::Value` containing the value of the key frame
    fn set_key_frame(&self, index_: u32, key: f64, mode: AnimationMode, value: &glib::Value);

    /// Sets the keys for each key frame inside `self`.
    ///
    /// If `self` does not hold any key frame, `n_key_frames` key frames
    /// will be created; if `self` already has key frames, `key_frames` must
    /// have at least as many elements as the number of key frames.
    /// ## `n_key_frames`
    /// the number of values
    /// ## `key_frames`
    /// an array of keys between 0.0
    ///  and 1.0, one for each key frame
    fn set_key_frames(&self, key_frames: &[f64]);

    //fn set_modes(&self, modes: /*Unimplemented*/&CArray TypeId { ns_id: 1, id: 28 });

    /// Sets the values for each key frame inside `self`.
    ///
    /// If `self` does not hold any key frame, `n_values` key frames will
    /// be created; if `self` already has key frames, `values` must have
    /// at least as many elements as the number of key frames.
    /// ## `n_values`
    /// the number of values
    /// ## `values`
    /// an array of values, one for each
    ///  key frame
    fn set_values(&self, values: &[&glib::Value]);
}

impl<O: IsA<KeyframeTransition>> KeyframeTransitionExt for O {
    fn clear(&self) {
        unsafe {
            ffi::clutter_keyframe_transition_clear(self.as_ref().to_glib_none().0);
        }
    }

    fn get_key_frame(&self, index_: u32) -> (f64, AnimationMode, glib::Value) {
        unsafe {
            let mut key = mem::MaybeUninit::uninit();
            let mut mode = mem::MaybeUninit::uninit();
            let mut value = glib::Value::uninitialized();
            ffi::clutter_keyframe_transition_get_key_frame(
                self.as_ref().to_glib_none().0,
                index_,
                key.as_mut_ptr(),
                mode.as_mut_ptr(),
                value.to_glib_none_mut().0,
            );
            let key = key.assume_init();
            let mode = mode.assume_init();
            (key, from_glib(mode), value)
        }
    }

    fn get_n_key_frames(&self) -> u32 {
        unsafe { ffi::clutter_keyframe_transition_get_n_key_frames(self.as_ref().to_glib_none().0) }
    }

    //fn set(&self, gtype: glib::types::Type, n_key_frames: u32, : /*Unknown conversion*//*Unimplemented*/Fundamental: VarArgs) {
    //    unsafe { TODO: call clutter_sys:clutter_keyframe_transition_set() }
    //}

    fn set_key_frame(&self, index_: u32, key: f64, mode: AnimationMode, value: &glib::Value) {
        unsafe {
            ffi::clutter_keyframe_transition_set_key_frame(
                self.as_ref().to_glib_none().0,
                index_,
                key,
                mode.to_glib(),
                value.to_glib_none().0,
            );
        }
    }

    fn set_key_frames(&self, key_frames: &[f64]) {
        let n_key_frames = key_frames.len() as u32;
        unsafe {
            ffi::clutter_keyframe_transition_set_key_frames(
                self.as_ref().to_glib_none().0,
                n_key_frames,
                key_frames.to_glib_none().0,
            );
        }
    }

    //fn set_modes(&self, modes: /*Unimplemented*/&CArray TypeId { ns_id: 1, id: 28 }) {
    //    unsafe { TODO: call clutter_sys:clutter_keyframe_transition_set_modes() }
    //}

    fn set_values(&self, values: &[&glib::Value]) {
        let n_values = values.len() as u32;
        unsafe {
            ffi::clutter_keyframe_transition_set_values(
                self.as_ref().to_glib_none().0,
                n_values,
                values.to_glib_none().0,
            );
        }
    }
}

impl fmt::Display for KeyframeTransition {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "KeyframeTransition")
    }
}