1use core::{borrow::Borrow, sync::atomic::AtomicU64};
2
3use alloc::boxed::Box;
4
5use crate::{
6 event::Event,
7 layout::{Layout, Viewport},
8 render::Renderer,
9 size::{Length, Size},
10 state::{self, StateNode},
11 style::Styler,
12 ui::UiCtx,
13 widget::Widget,
14};
15
16static NEXT_ID: AtomicU64 = AtomicU64::new(0);
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub enum ElId {
20 Unique(u64),
21 Custom(&'static str), }
23
24impl ElId {
25 pub fn new(name: &'static str) -> Self {
26 Self::Custom(name)
27 }
28
29 pub fn unique() -> Self {
30 Self::Unique(NEXT_ID.fetch_add(1, core::sync::atomic::Ordering::Relaxed))
31 }
32}
33
34impl From<&'static str> for ElId {
35 fn from(value: &'static str) -> Self {
36 Self::new(value)
37 }
38}
39
40pub struct El<'a, Message, R: Renderer, E: Event, S> {
41 widget: Box<dyn Widget<Message, R, E, S> + 'a>,
42}
43
44impl<'a, Message, R: Renderer, E: Event, S> Widget<Message, R, E, S> for El<'a, Message, R, E, S> {
45 fn id(&self) -> Option<ElId> {
46 self.widget.id()
47 }
48
49 fn tree_ids(&self) -> alloc::vec::Vec<ElId> {
50 self.widget.tree_ids()
51 }
52
53 fn size(&self) -> Size<Length> {
54 self.widget.size()
55 }
56
57 fn layout(
58 &self,
59 ctx: &mut UiCtx<Message>,
60 state_tree: &mut StateNode,
61 styler: &S,
62 limits: &crate::layout::Limits,
63 viewport: &Viewport,
64 ) -> crate::layout::LayoutNode {
65 self.widget.layout(ctx, state_tree, styler, limits, viewport)
66 }
67
68 fn draw(
69 &self,
70 ctx: &mut UiCtx<Message>,
71 state_tree: &mut StateNode,
72 renderer: &mut R,
73 styler: &S,
74 layout: Layout,
75 ) {
76 self.widget.draw(ctx, state_tree, renderer, styler, layout)
77 }
78
79 fn on_event(
80 &mut self,
81 ctx: &mut UiCtx<Message>,
82 event: E,
83 state: &mut StateNode,
84 ) -> crate::event::EventResponse<E> {
85 self.widget.on_event(ctx, event, state)
86 }
87
88 fn state_tag(&self) -> crate::state::StateTag {
89 self.widget.state_tag()
90 }
91
92 fn state(&self) -> state::State {
93 self.widget.state()
94 }
95
96 fn state_children(&self) -> alloc::vec::Vec<StateNode> {
97 self.widget.state_children()
98 }
99}
100
101impl<'a, Message, R: Renderer, E: Event, S> El<'a, Message, R, E, S> {
102 pub fn new(widget: impl Widget<Message, R, E, S> + 'a) -> Self {
103 Self { widget: Box::new(widget) }
104 }
105
106 pub fn widget(&self) -> &dyn Widget<Message, R, E, S> {
107 self.widget.as_ref()
108 }
109}
110
111impl<'a, Message, R: Renderer, E: Event, S> Borrow<dyn Widget<Message, R, E, S> + 'a>
112 for El<'a, Message, R, E, S>
113{
114 fn borrow(&self) -> &(dyn Widget<Message, R, E, S> + 'a) {
115 self.widget.borrow()
116 }
117}
118
119impl<'a, Message, R: Renderer, E: Event, S> Borrow<dyn Widget<Message, R, E, S> + 'a>
120 for &El<'a, Message, R, E, S>
121{
122 fn borrow(&self) -> &(dyn Widget<Message, R, E, S> + 'a) {
123 self.widget.borrow()
124 }
125}
126
127