maycoon_core/
component.rs1use crate::app::info::AppInfo;
2use crate::app::update::Update;
3use crate::layout::{LayoutNode, StyleNode};
4use crate::state::State;
5use crate::widget::Widget;
6use maycoon_theme::id::WidgetId;
7use maycoon_theme::theme::Theme;
8use std::marker::PhantomData;
9use std::ops::{Deref, DerefMut};
10use vello::Scene;
11
12pub trait Component<S: State> {
22 fn get_widget(&mut self) -> &mut impl Widget<S>;
24
25 fn get_widget_id(&self) -> WidgetId;
27
28 fn build(self) -> ComponentAdapter<S, Self>
30 where
31 Self: Sized,
32 {
33 ComponentAdapter::new(self)
34 }
35}
36
37pub struct ComponentAdapter<S: State, C: Component<S>> {
41 inner: C,
42 phantom: PhantomData<S>,
43}
44
45impl<S: State, C: Component<S>> ComponentAdapter<S, C> {
46 pub fn new(inner: C) -> Self {
48 Self {
49 inner,
50 phantom: PhantomData,
51 }
52 }
53}
54
55impl<S: State, C: Component<S>> Deref for ComponentAdapter<S, C> {
56 type Target = C;
57
58 fn deref(&self) -> &Self::Target {
59 &self.inner
60 }
61}
62
63impl<S: State, C: Component<S>> DerefMut for ComponentAdapter<S, C> {
64 fn deref_mut(&mut self) -> &mut Self::Target {
65 &mut self.inner
66 }
67}
68
69impl<S: State, C: Component<S>> Widget<S> for ComponentAdapter<S, C> {
70 fn render(
71 &mut self,
72 scene: &mut Scene,
73 theme: &mut dyn Theme,
74 info: &AppInfo,
75 layout_node: &LayoutNode,
76 state: &S,
77 ) {
78 self.inner
79 .get_widget()
80 .render(scene, theme, info, layout_node, state)
81 }
82
83 fn layout_style(&mut self, state: &S) -> StyleNode {
84 self.inner.get_widget().layout_style(state)
85 }
86
87 fn update(&mut self, layout: &LayoutNode, state: &mut S, info: &AppInfo) -> Update {
88 self.inner.get_widget().update(layout, state, info)
89 }
90
91 fn widget_id(&self) -> WidgetId {
92 self.inner.get_widget_id()
93 }
94}