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::vg::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> {
13 start: Instant,
14 duration: Duration,
15 widget: W,
16 animation: A,
17}
18
19impl<W: Widget, A: Fn(&mut W, f32) -> Update> Animator<W, A> {
20 pub fn new(duration: Duration, widget: W, animation: A) -> Self {
25 Self {
26 start: Instant::now(),
27 duration,
28 widget,
29 animation,
30 }
31 }
32}
33
34impl<W: Widget, A: Fn(&mut W, f32) -> Update> Widget for Animator<W, A> {
35 fn render(
36 &mut self,
37 scene: &mut Scene,
38 theme: &mut dyn Theme,
39 layout_node: &LayoutNode,
40 info: &AppInfo,
41 context: AppContext,
42 ) {
43 self.widget.render(scene, theme, layout_node, info, context);
44 }
45
46 fn layout_style(&self) -> StyleNode {
47 self.widget.layout_style()
48 }
49
50 fn update(&mut self, layout: &LayoutNode, context: AppContext, info: &AppInfo) -> Update {
51 let elapsed = self.start.elapsed();
52
53 let mut update = self.widget.update(layout, context, info);
54
55 if elapsed < self.duration {
56 let f = elapsed.as_secs_f32() / self.duration.as_secs_f32();
57
58 update.insert((self.animation)(&mut self.widget, f));
59 }
60
61 update
62 }
63
64 fn widget_id(&self) -> WidgetId {
65 WidgetId::new("maycoon-widgets", "Animator")
66 }
67}