summaryrefslogtreecommitdiffstats
path: root/virtual/src/widget/tree.rs
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-02-10 21:54:13 +0700
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-02-10 21:54:13 +0700
commit5225e0e304bf5b407977e549c48ce9dea26b8c40 (patch)
tree8358ef6152f743e87a9d83d8deb3aa47e877cd88 /virtual/src/widget/tree.rs
parent8f0839e786f8d521f7319dd0e188d43284f526b7 (diff)
downloadiced-5225e0e304bf5b407977e549c48ce9dea26b8c40.tar.gz
iced-5225e0e304bf5b407977e549c48ce9dea26b8c40.tar.bz2
iced-5225e0e304bf5b407977e549c48ce9dea26b8c40.zip
Draft virtual `Button`, `Column`, and `Text`
... as well as a very naive diffing strategy!
Diffstat (limited to 'virtual/src/widget/tree.rs')
-rw-r--r--virtual/src/widget/tree.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/virtual/src/widget/tree.rs b/virtual/src/widget/tree.rs
new file mode 100644
index 00000000..75f50a2f
--- /dev/null
+++ b/virtual/src/widget/tree.rs
@@ -0,0 +1,58 @@
+use crate::widget::Element;
+
+use std::any::Any;
+use std::marker::PhantomData;
+
+pub struct Tree<Message, Renderer> {
+ pub state: Box<dyn Any>,
+ pub children: Vec<Tree<Message, Renderer>>,
+ types_: PhantomData<(Message, Renderer)>,
+}
+
+impl<Message, Renderer> Tree<Message, Renderer> {
+ pub fn new(element: &Element<Message, Renderer>) -> Self {
+ Self {
+ state: element.as_widget().state(),
+ children: element
+ .as_widget()
+ .children()
+ .iter()
+ .map(Self::new)
+ .collect(),
+ types_: PhantomData,
+ }
+ }
+
+ pub fn diff(
+ &mut self,
+ current: &Element<Message, Renderer>,
+ new: &Element<Message, Renderer>,
+ ) {
+ if current.as_widget().tag() == new.as_widget().tag() {
+ let current_children = current.as_widget().children();
+ let new_children = new.as_widget().children();
+
+ if current_children.len() > new_children.len() {
+ self.children.truncate(new_children.len());
+ }
+
+ for (child_state, (current, new)) in self
+ .children
+ .iter_mut()
+ .zip(current_children.iter().zip(new_children.iter()))
+ {
+ child_state.diff(current, new);
+ }
+
+ if current_children.len() < new_children.len() {
+ self.children.extend(
+ new_children[current_children.len()..]
+ .iter()
+ .map(Self::new),
+ );
+ }
+ } else {
+ *self = Self::new(new);
+ }
+ }
+}