animate/legacy/
rotate_action.rs

1use crate::{Action, Actor, ActorMeta, GestureAction};
2use glib::{
3    object as gobject,
4    object::{Cast, IsA},
5    signal::{connect_raw, SignalHandlerId},
6    translate::*,
7};
8use std::boxed::Box as Box_;
9use std::{fmt, mem::transmute};
10
11glib_wrapper! {
12    pub struct RotateAction(Object<ffi::ClutterRotateAction, ffi::ClutterRotateActionClass, RotateActionClass>) @extends GestureAction, Action, ActorMeta, gobject::InitiallyUnowned;
13
14    match fn {
15        get_type => || ffi::clutter_rotate_action_get_type(),
16    }
17}
18
19impl RotateAction {
20    /// Creates a new `RotateAction` instance
21    ///
22    /// # Returns
23    ///
24    /// the newly created `RotateAction`
25    pub fn new() -> RotateAction {
26        unsafe { Action::from_glib_none(ffi::clutter_rotate_action_new()).unsafe_cast() }
27    }
28}
29
30impl Default for RotateAction {
31    fn default() -> Self {
32        Self::new()
33    }
34}
35
36/// Trait containing all `RotateAction` methods.
37///
38/// # Implementors
39///
40/// [`RotateAction`](struct.RotateAction.html)
41pub trait RotateActionExt: 'static {
42    /// The ::rotate signal is emitted when a rotate gesture is
43    /// recognized on the attached actor and when the gesture is
44    /// cancelled (in this case with an angle value of 0).
45    /// ## `actor`
46    /// the `Actor` attached to the `action`
47    /// ## `angle`
48    /// the difference of angle of rotation between the initial
49    /// rotation and the current rotation
50    ///
51    /// # Returns
52    ///
53    /// `true` if the rotation should continue, and `false` if
54    ///  the rotation should be cancelled.
55    fn connect_rotate<F: Fn(&Self, &Actor, f64) -> bool + 'static>(&self, f: F) -> SignalHandlerId;
56}
57
58impl<O: IsA<RotateAction>> RotateActionExt for O {
59    fn connect_rotate<F: Fn(&Self, &Actor, f64) -> bool + 'static>(&self, f: F) -> SignalHandlerId {
60        unsafe extern "C" fn rotate_trampoline<P, F: Fn(&P, &Actor, f64) -> bool + 'static>(
61            this: *mut ffi::ClutterRotateAction,
62            actor: *mut ffi::ClutterActor,
63            angle: libc::c_double,
64            f: glib_sys::gpointer,
65        ) -> glib_sys::gboolean
66        where
67            P: IsA<RotateAction>,
68        {
69            let f: &F = &*(f as *const F);
70            f(
71                &RotateAction::from_glib_borrow(this).unsafe_cast_ref(),
72                &from_glib_borrow(actor),
73                angle,
74            )
75            .to_glib()
76        }
77        unsafe {
78            let f: Box_<F> = Box_::new(f);
79            connect_raw(
80                self.as_ptr() as *mut _,
81                b"rotate\0".as_ptr() as *const _,
82                Some(transmute::<_, unsafe extern "C" fn()>(
83                    rotate_trampoline::<Self, F> as *const (),
84                )),
85                Box_::into_raw(f),
86            )
87        }
88    }
89}
90
91impl fmt::Display for RotateAction {
92    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93        write!(f, "RotateAction")
94    }
95}