ferroui_base/animation/transitions/
brush_transition.rs1use crate::animation::animators::{GradientBrushAnimator, ISolidColorBrushAnimator};
2use crate::animation::{AnimatorTransitionObservable, Transition, TransitionBase, TransitionObservableBase};
3use crate::ferro_transition_class;
4use crate::media::IBrush;
5use crate::reactive::IObservable;
6use std::rc::Rc;
7
8ferro_transition_class!(
9 BrushTransition: Option<Rc<dyn IBrush>>
13);
14
15type Brush = Option<Rc<dyn IBrush>>;
16
17impl Transition<Brush> for BrushTransition {
18 fn do_transition(
19 this: &Self,
20 progress: Rc<dyn IObservable<f64>>,
21 old_value: Brush,
22 new_value: Brush,
23 ) -> Rc<dyn IObservable<Brush>> {
24 let easing = this.easing();
25 let incompatible = |progress, old_value: Brush, new_value: Brush| -> Rc<dyn IObservable<Brush>> {
26 TransitionObservableBase::new(progress, this.easing(), move |progress| {
27 if progress >= 0.5 {
28 new_value.clone()
29 } else {
30 old_value.clone()
31 }
32 })
33 };
34
35 let (Some(old_brush), Some(new_brush)) = (&old_value, &new_value) else {
36 return incompatible(progress, old_value, new_value);
37 };
38
39 if old_brush.as_gradient_brush().is_some() {
40 if new_brush.as_gradient_brush().is_some() {
41 return AnimatorTransitionObservable::create(
42 GradientBrushAnimator::interpolate_core,
43 progress,
44 easing,
45 old_value,
46 new_value,
47 );
48 } else if let Some(new_solid_color_brush_to_convert) = new_brush.as_solid_color_brush() {
49 let converted_solid_color_brush = GradientBrushAnimator::convert_solid_color_brush_to_gradient(
50 &**old_brush,
51 new_solid_color_brush_to_convert,
52 );
53 return AnimatorTransitionObservable::create(
54 GradientBrushAnimator::interpolate_core,
55 progress,
56 easing,
57 old_value,
58 Some(converted_solid_color_brush),
59 );
60 }
61 } else if let (Some(_), Some(old_solid_color_brush_to_convert)) =
62 (new_brush.as_gradient_brush(), old_brush.as_solid_color_brush())
63 {
64 let converted_solid_color_brush = GradientBrushAnimator::convert_solid_color_brush_to_gradient(
65 &**new_brush,
66 old_solid_color_brush_to_convert,
67 );
68 return AnimatorTransitionObservable::create(
69 GradientBrushAnimator::interpolate_core,
70 progress,
71 easing,
72 Some(converted_solid_color_brush),
73 new_value,
74 );
75 }
76
77 if old_brush.as_solid_color_brush().is_some() && new_brush.as_solid_color_brush().is_some() {
78 return AnimatorTransitionObservable::create(
79 ISolidColorBrushAnimator::interpolate_core,
80 progress,
81 easing,
82 old_value,
83 new_value,
84 );
85 }
86
87 incompatible(progress, old_value, new_value)
88 }
89}