Skip to main content

ferroui_base/animation/
i_animation.rs

1use crate::animation::{Animatable, Animation, AnimationTask, IClock};
2use crate::reactive::{IDisposable, IObservable};
3use crate::threading::CancellationToken;
4use crate::Ref;
5use std::rc::Rc;
6
7/// Interface for animation objects.
8pub trait IAnimation: 'static {
9    /// Applies the animation to the specified control: it runs while
10    /// `match_` is true. `on_complete` runs when it ends by itself.
11    /// `is_manually_started` tells an animation started by code from one
12    /// started by a style. Disposing the result removes the animation.
13    fn apply(
14        &self,
15        control: &Animatable,
16        clock: Option<Rc<dyn IClock>>,
17        match_: Rc<dyn IObservable<bool>>,
18        on_complete: Option<Rc<dyn Fn()>>,
19        is_manually_started: bool,
20    ) -> Rc<dyn IDisposable>;
21
22    /// Runs the animation on the specified control. The result completes
23    /// when the animation has ended or was cancelled.
24    fn run_async(
25        &self,
26        control: &Animatable,
27        clock: Option<Rc<dyn IClock>>,
28        cancellation_token: CancellationToken,
29    ) -> AnimationTask;
30
31    /// The identity of the animation, used for reference equality.
32    #[doc(hidden)]
33    fn reference_id(&self) -> *const () {
34        self as *const Self as *const ()
35    }
36
37    /// The object of the object model that implements the contract, if one
38    /// does: the equivalent of `is`/`as` on the interface. Cast the object to
39    /// the class looked for (`as_object()?.cast::<T>()`).
40    fn as_object(&self) -> Option<crate::Ref<crate::FerroObject>> {
41        None
42    }
43}
44
45/// Handles compare by identity (reference equality): two handles are equal
46/// when they refer to the same animation, whichever adapter they were made
47/// from.
48impl PartialEq for dyn IAnimation {
49    #[inline]
50    fn eq(&self, other: &Self) -> bool {
51        self.reference_id() == other.reference_id()
52    }
53}
54
55struct AnimationRef(Ref<Animation>);
56
57impl IAnimation for AnimationRef {
58    fn apply(
59        &self,
60        control: &Animatable,
61        clock: Option<Rc<dyn IClock>>,
62        match_: Rc<dyn IObservable<bool>>,
63        on_complete: Option<Rc<dyn Fn()>>,
64        is_manually_started: bool,
65    ) -> Rc<dyn IDisposable> {
66        self.0.apply(control, clock, match_, on_complete, is_manually_started)
67    }
68
69    fn run_async(
70        &self,
71        control: &Animatable,
72        clock: Option<Rc<dyn IClock>>,
73        cancellation_token: CancellationToken,
74    ) -> AnimationTask {
75        self.0.run_async_with_clock(control, clock, cancellation_token)
76    }
77
78    fn reference_id(&self) -> *const () {
79        &*self.0 as *const Animation as *const ()
80    }
81
82    fn as_object(&self) -> Option<Ref<crate::FerroObject>> {
83        Some(self.0.clone().upcast())
84    }
85}
86
87impl From<Ref<Animation>> for Rc<dyn IAnimation> {
88    fn from(value: Ref<Animation>) -> Self {
89        Rc::new(AnimationRef(value))
90    }
91}
92
93impl From<&Ref<Animation>> for Rc<dyn IAnimation> {
94    fn from(value: &Ref<Animation>) -> Self {
95        Rc::new(AnimationRef(value.clone()))
96    }
97}