maycoon_widgets/
animator.rs1use maycoon_core::app::context::AppContext;
2use maycoon_core::app::info::AppInfo;
3use maycoon_core::app::update::Update;
4use maycoon_core::layout::{LayoutNode, StyleNode};
5use maycoon_core::vgi::Scene;
6use maycoon_core::widget::Widget;
7use maycoon_theme::id::WidgetId;
8use maycoon_theme::theme::Theme;
9use std::time::{Duration, Instant};
10
11pub struct Animator<W: Widget, A: Fn(&mut W, f32) -> Update> {
15 start: Instant,
16 duration: Duration,
17 widget: W,
18 animation: A,
19}
20
21impl<W: Widget, A: Fn(&mut W, f32) -> Update> Animator<W, A> {
22 #[inline(always)]
27 pub fn new(duration: Duration, widget: W, animation: A) -> Self {
28 Self {
29 start: Instant::now(),
30 duration,
31 widget,
32 animation,
33 }
34 }
35}
36
37impl<W: Widget, A: Fn(&mut W, f32) -> Update> Widget for Animator<W, A> {
38 #[inline(always)]
39 fn render(
40 &mut self,
41 scene: &mut dyn Scene,
42 theme: &mut dyn Theme,
43 layout_node: &LayoutNode,
44 info: &AppInfo,
45 context: AppContext,
46 ) {
47 self.widget.render(scene, theme, layout_node, info, context);
48 }
49
50 #[inline(always)]
51 fn layout_style(&self) -> StyleNode {
52 self.widget.layout_style()
53 }
54
55 fn update(&mut self, layout: &LayoutNode, context: AppContext, info: &AppInfo) -> Update {
56 let elapsed = self.start.elapsed();
57
58 let mut update = self.widget.update(layout, context, info);
59
60 if elapsed < self.duration {
61 let f = elapsed.as_secs_f32() / self.duration.as_secs_f32();
62
63 update.insert((self.animation)(&mut self.widget, f));
64 }
65
66 update
67 }
68
69 #[inline(always)]
70 fn widget_id(&self) -> WidgetId {
71 WidgetId::new("maycoon-widgets", "Animator")
72 }
73}