iced_native/widget/
tree.rs1use crate::Widget;
3
4use std::any::{self, Any};
5use std::borrow::Borrow;
6use std::fmt;
7
8#[derive(Debug)]
12pub struct Tree {
13 pub tag: Tag,
15
16 pub state: State,
18
19 pub children: Vec<Tree>,
21}
22
23impl Tree {
24 pub fn empty() -> Self {
26 Self {
27 tag: Tag::stateless(),
28 state: State::None,
29 children: Vec::new(),
30 }
31 }
32
33 pub fn new<'a, Message, Renderer>(
35 widget: impl Borrow<dyn Widget<Message, Renderer> + 'a>,
36 ) -> Self
37 where
38 Renderer: crate::Renderer,
39 {
40 let widget = widget.borrow();
41
42 Self {
43 tag: widget.tag(),
44 state: widget.state(),
45 children: widget.children(),
46 }
47 }
48
49 pub fn diff<'a, Message, Renderer>(
58 &mut self,
59 new: impl Borrow<dyn Widget<Message, Renderer> + 'a>,
60 ) where
61 Renderer: crate::Renderer,
62 {
63 if self.tag == new.borrow().tag() {
64 new.borrow().diff(self)
65 } else {
66 *self = Self::new(new);
67 }
68 }
69
70 pub fn diff_children<'a, Message, Renderer>(
72 &mut self,
73 new_children: &[impl Borrow<dyn Widget<Message, Renderer> + 'a>],
74 ) where
75 Renderer: crate::Renderer,
76 {
77 self.diff_children_custom(
78 new_children,
79 |tree, widget| tree.diff(widget.borrow()),
80 |widget| Self::new(widget.borrow()),
81 )
82 }
83
84 pub fn diff_children_custom<T>(
87 &mut self,
88 new_children: &[T],
89 diff: impl Fn(&mut Tree, &T),
90 new_state: impl Fn(&T) -> Self,
91 ) {
92 if self.children.len() > new_children.len() {
93 self.children.truncate(new_children.len());
94 }
95
96 for (child_state, new) in
97 self.children.iter_mut().zip(new_children.iter())
98 {
99 diff(child_state, new);
100 }
101
102 if self.children.len() < new_children.len() {
103 self.children.extend(
104 new_children[self.children.len()..].iter().map(new_state),
105 );
106 }
107 }
108}
109
110#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
112pub struct Tag(any::TypeId);
113
114impl Tag {
115 pub fn of<T>() -> Self
117 where
118 T: 'static,
119 {
120 Self(any::TypeId::of::<T>())
121 }
122
123 pub fn stateless() -> Self {
125 Self::of::<()>()
126 }
127}
128
129pub enum State {
131 None,
133
134 Some(Box<dyn Any>),
136}
137
138impl State {
139 pub fn new<T>(state: T) -> Self
141 where
142 T: 'static,
143 {
144 State::Some(Box::new(state))
145 }
146
147 pub fn downcast_ref<T>(&self) -> &T
152 where
153 T: 'static,
154 {
155 match self {
156 State::None => panic!("Downcast on stateless state"),
157 State::Some(state) => {
158 state.downcast_ref().expect("Downcast widget state")
159 }
160 }
161 }
162
163 pub fn downcast_mut<T>(&mut self) -> &mut T
168 where
169 T: 'static,
170 {
171 match self {
172 State::None => panic!("Downcast on stateless state"),
173 State::Some(state) => {
174 state.downcast_mut().expect("Downcast widget state")
175 }
176 }
177 }
178}
179
180impl fmt::Debug for State {
181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 match self {
183 Self::None => write!(f, "State::None"),
184 Self::Some(_) => write!(f, "State::Some"),
185 }
186 }
187}