summaryrefslogtreecommitdiffstats
path: root/native/src/widget/tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'native/src/widget/tree.rs')
-rw-r--r--native/src/widget/tree.rs187
1 files changed, 0 insertions, 187 deletions
diff --git a/native/src/widget/tree.rs b/native/src/widget/tree.rs
deleted file mode 100644
index 0af40c33..00000000
--- a/native/src/widget/tree.rs
+++ /dev/null
@@ -1,187 +0,0 @@
-//! Store internal widget state in a state tree to ensure continuity.
-use crate::Widget;
-
-use std::any::{self, Any};
-use std::borrow::Borrow;
-use std::fmt;
-
-/// A persistent state widget tree.
-///
-/// A [`Tree`] is normally associated with a specific widget in the widget tree.
-#[derive(Debug)]
-pub struct Tree {
- /// The tag of the [`Tree`].
- pub tag: Tag,
-
- /// The [`State`] of the [`Tree`].
- pub state: State,
-
- /// The children of the root widget of the [`Tree`].
- pub children: Vec<Tree>,
-}
-
-impl Tree {
- /// Creates an empty, stateless [`Tree`] with no children.
- pub fn empty() -> Self {
- Self {
- tag: Tag::stateless(),
- state: State::None,
- children: Vec::new(),
- }
- }
-
- /// Creates a new [`Tree`] for the provided [`Widget`].
- pub fn new<'a, Message, Renderer>(
- widget: impl Borrow<dyn Widget<Message, Renderer> + 'a>,
- ) -> Self
- where
- Renderer: crate::Renderer,
- {
- let widget = widget.borrow();
-
- Self {
- tag: widget.tag(),
- state: widget.state(),
- children: widget.children(),
- }
- }
-
- /// Reconciliates the current tree with the provided [`Widget`].
- ///
- /// If the tag of the [`Widget`] matches the tag of the [`Tree`], then the
- /// [`Widget`] proceeds with the reconciliation (i.e. [`Widget::diff`] is called).
- ///
- /// Otherwise, the whole [`Tree`] is recreated.
- ///
- /// [`Widget::diff`]: crate::Widget::diff
- pub fn diff<'a, Message, Renderer>(
- &mut self,
- new: impl Borrow<dyn Widget<Message, Renderer> + 'a>,
- ) where
- Renderer: crate::Renderer,
- {
- if self.tag == new.borrow().tag() {
- new.borrow().diff(self)
- } else {
- *self = Self::new(new);
- }
- }
-
- /// Reconciliates the children of the tree with the provided list of widgets.
- pub fn diff_children<'a, Message, Renderer>(
- &mut self,
- new_children: &[impl Borrow<dyn Widget<Message, Renderer> + 'a>],
- ) where
- Renderer: crate::Renderer,
- {
- self.diff_children_custom(
- new_children,
- |tree, widget| tree.diff(widget.borrow()),
- |widget| Self::new(widget.borrow()),
- )
- }
-
- /// Reconciliates the children of the tree with the provided list of widgets using custom
- /// logic both for diffing and creating new widget state.
- pub fn diff_children_custom<T>(
- &mut self,
- new_children: &[T],
- diff: impl Fn(&mut Tree, &T),
- new_state: impl Fn(&T) -> Self,
- ) {
- if self.children.len() > new_children.len() {
- self.children.truncate(new_children.len());
- }
-
- for (child_state, new) in
- self.children.iter_mut().zip(new_children.iter())
- {
- diff(child_state, new);
- }
-
- if self.children.len() < new_children.len() {
- self.children.extend(
- new_children[self.children.len()..].iter().map(new_state),
- );
- }
- }
-}
-
-/// The identifier of some widget state.
-#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
-pub struct Tag(any::TypeId);
-
-impl Tag {
- /// Creates a [`Tag`] for a state of type `T`.
- pub fn of<T>() -> Self
- where
- T: 'static,
- {
- Self(any::TypeId::of::<T>())
- }
-
- /// Creates a [`Tag`] for a stateless widget.
- pub fn stateless() -> Self {
- Self::of::<()>()
- }
-}
-
-/// The internal [`State`] of a widget.
-pub enum State {
- /// No meaningful internal state.
- None,
-
- /// Some meaningful internal state.
- Some(Box<dyn Any>),
-}
-
-impl State {
- /// Creates a new [`State`].
- pub fn new<T>(state: T) -> Self
- where
- T: 'static,
- {
- State::Some(Box::new(state))
- }
-
- /// Downcasts the [`State`] to `T` and returns a reference to it.
- ///
- /// # Panics
- /// This method will panic if the downcast fails or the [`State`] is [`State::None`].
- pub fn downcast_ref<T>(&self) -> &T
- where
- T: 'static,
- {
- match self {
- State::None => panic!("Downcast on stateless state"),
- State::Some(state) => {
- state.downcast_ref().expect("Downcast widget state")
- }
- }
- }
-
- /// Downcasts the [`State`] to `T` and returns a mutable reference to it.
- ///
- /// # Panics
- /// This method will panic if the downcast fails or the [`State`] is [`State::None`].
- pub fn downcast_mut<T>(&mut self) -> &mut T
- where
- T: 'static,
- {
- match self {
- State::None => panic!("Downcast on stateless state"),
- State::Some(state) => {
- state.downcast_mut().expect("Downcast widget state")
- }
- }
- }
-}
-
-impl fmt::Debug for State {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Self::None => write!(f, "State::None"),
- Self::Some(_) => write!(f, "State::Some"),
- }
- }
-}