1use core::cell::{Ref, RefCell, RefMut};
2
3use alloc::{rc::Rc, vec::Vec};
4
5use crate::{el::El, event::Event, layout::Viewport, render::Renderer, widget::Widget};
6
7#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
8pub enum Value<T> {
9 Static(RefCell<T>),
10 Dynamic(Rc<RefCell<T>>),
11}
12
13impl<T> Value<T> {
14 pub fn new(value: T) -> Self {
15 Self::Static(RefCell::new(value))
16 }
17
18 pub fn dynamic(value: T) -> Self {
19 Self::Dynamic(Rc::new(RefCell::new(value)))
20 }
21
22 #[inline]
23 pub fn get(&self) -> Ref<'_, T> {
24 match self {
25 Value::Static(value) => value.borrow(),
26 Value::Dynamic(value) => value.borrow(),
27 }
28 }
29
30 #[inline]
31 pub fn get_mut(&self) -> RefMut<'_, T> {
32 match self {
33 Value::Static(value) => value.borrow_mut(),
34 Value::Dynamic(value) => value.borrow_mut(),
35 }
36 }
37}
38
39impl<T> From<T> for Value<T> {
40 fn from(value: T) -> Self {
41 Self::new(value)
42 }
43}
44
45impl<T, Message, R, E, S> Widget<Message, R, E, S> for Value<T>
46where
47 R: Renderer,
48 E: Event,
49 T: Widget<Message, R, E, S>,
50{
51 fn id(&self) -> Option<crate::el::ElId> {
52 self.get().id()
53 }
54
55 fn tree_ids(&self) -> Vec<crate::el::ElId> {
56 self.get().tree_ids()
57 }
58
59 fn size(&self) -> crate::size::Size<crate::size::Length> {
60 self.get().size()
61 }
62
63 fn layout(
64 &self,
65 ctx: &mut crate::ui::UiCtx<Message>,
66 state: &mut crate::state::StateNode,
67 styler: &S,
68 limits: &crate::layout::Limits,
69 viewport: &Viewport,
70 ) -> crate::layout::LayoutNode {
71 self.get().layout(ctx, state, styler, limits, viewport)
72 }
73
74 fn draw(
75 &self,
76 ctx: &mut crate::ui::UiCtx<Message>,
77 state: &mut crate::state::StateNode,
78 renderer: &mut R,
79 styler: &S,
80 layout: crate::layout::Layout,
81 ) {
82 self.get().draw(ctx, state, renderer, styler, layout)
83 }
84}
85
86impl<'a, T, Message, R, E, S> From<Value<T>> for El<'a, Message, R, E, S>
87where
88 T: Widget<Message, R, E, S> + Clone + 'a,
89 Message: Clone + 'a,
90 R: Renderer + 'a,
91 E: Event + 'a,
92{
93 fn from(value: Value<T>) -> Self {
94 El::new(value)
95 }
96}