diff options
-rw-r--r-- | pure/src/widget.rs | 20 | ||||
-rw-r--r-- | pure/src/widget/button.rs | 21 | ||||
-rw-r--r-- | pure/src/widget/checkbox.rs | 16 | ||||
-rw-r--r-- | pure/src/widget/column.rs | 13 | ||||
-rw-r--r-- | pure/src/widget/container.rs | 13 | ||||
-rw-r--r-- | pure/src/widget/element.rs | 17 | ||||
-rw-r--r-- | pure/src/widget/image.rs | 15 | ||||
-rw-r--r-- | pure/src/widget/radio.rs | 16 | ||||
-rw-r--r-- | pure/src/widget/row.rs | 14 | ||||
-rw-r--r-- | pure/src/widget/scrollable.rs | 20 | ||||
-rw-r--r-- | pure/src/widget/slider.rs | 16 | ||||
-rw-r--r-- | pure/src/widget/space.rs | 16 | ||||
-rw-r--r-- | pure/src/widget/text.rs | 16 | ||||
-rw-r--r-- | pure/src/widget/text_input.rs | 19 | ||||
-rw-r--r-- | pure/src/widget/toggler.rs | 14 | ||||
-rw-r--r-- | pure/src/widget/tree.rs | 52 |
16 files changed, 101 insertions, 197 deletions
diff --git a/pure/src/widget.rs b/pure/src/widget.rs index 9112dd9a..03b668d3 100644 --- a/pure/src/widget.rs +++ b/pure/src/widget.rs @@ -37,15 +37,7 @@ use iced_native::mouse; use iced_native::renderer; use iced_native::{Clipboard, Hasher, Length, Point, Rectangle, Shell}; -use std::any::{self, Any}; - pub trait Widget<Message, Renderer> { - fn tag(&self) -> any::TypeId; - - fn state(&self) -> Box<dyn Any>; - - fn children_state(&self) -> Vec<Tree>; - fn width(&self) -> Length; fn height(&self) -> Length; @@ -68,6 +60,18 @@ pub trait Widget<Message, Renderer> { viewport: &Rectangle, ); + fn tag(&self) -> tree::Tag { + tree::Tag::stateless() + } + + fn state(&self) -> tree::State { + tree::State::None + } + + fn children(&self) -> Vec<Tree> { + Vec::new() + } + fn diff(&self, _tree: &mut Tree) {} fn mouse_interaction( diff --git a/pure/src/widget/button.rs b/pure/src/widget/button.rs index 6dc1016c..55cbf8b4 100644 --- a/pure/src/widget/button.rs +++ b/pure/src/widget/button.rs @@ -1,4 +1,5 @@ -use crate::widget::{Element, Tree, Widget}; +use crate::widget::tree::{self, Tree}; +use crate::widget::{Element, Widget}; use iced_native::event::{self, Event}; use iced_native::layout; @@ -10,8 +11,6 @@ use iced_native::{ }; use iced_style::button::StyleSheet; -use std::any::Any; - pub use button::State; pub struct Button<'a, Message, Renderer> { @@ -77,20 +76,20 @@ where Message: 'static + Clone, Renderer: 'static + iced_native::Renderer, { - fn tag(&self) -> std::any::TypeId { - std::any::TypeId::of::<State>() + fn tag(&self) -> tree::Tag { + tree::Tag::of::<State>() } - fn state(&self) -> Box<dyn Any> { - Box::new(State::new()) + fn state(&self) -> tree::State { + tree::State::new(State::new()) } - fn diff(&self, tree: &mut Tree) { - tree.diff_children(std::slice::from_ref(&self.content)) + fn children(&self) -> Vec<Tree> { + vec![Tree::new(&self.content)] } - fn children_state(&self) -> Vec<Tree> { - vec![Tree::new(&self.content)] + fn diff(&self, tree: &mut Tree) { + tree.diff_children(std::slice::from_ref(&self.content)) } fn width(&self) -> Length { diff --git a/pure/src/widget/checkbox.rs b/pure/src/widget/checkbox.rs index 5352fad3..8aa4e845 100644 --- a/pure/src/widget/checkbox.rs +++ b/pure/src/widget/checkbox.rs @@ -7,8 +7,6 @@ use iced_native::renderer; use iced_native::text; use iced_native::{Clipboard, Hasher, Length, Point, Rectangle, Shell}; -use std::any::{self, Any}; - pub use iced_native::widget::Checkbox; impl<'a, Message, Renderer> Widget<Message, Renderer> @@ -16,20 +14,6 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: text::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) - } - - fn diff(&self, _tree: &mut Tree) {} - - fn children_state(&self) -> Vec<Tree> { - Vec::new() - } - fn width(&self) -> Length { <Self as iced_native::Widget<Message, Renderer>>::width(self) } diff --git a/pure/src/widget/column.rs b/pure/src/widget/column.rs index a9d7246e..4ab3e00d 100644 --- a/pure/src/widget/column.rs +++ b/pure/src/widget/column.rs @@ -9,7 +9,6 @@ use iced_native::{ Alignment, Clipboard, Hasher, Length, Padding, Point, Rectangle, Shell, }; -use std::any::{self, Any}; use std::u32; pub struct Column<'a, Message, Renderer> { @@ -86,22 +85,14 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: iced_native::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) + fn children(&self) -> Vec<Tree> { + self.children.iter().map(Tree::new).collect() } fn diff(&self, tree: &mut Tree) { tree.diff_children(&self.children); } - fn children_state(&self) -> Vec<Tree> { - self.children.iter().map(Tree::new).collect() - } - fn width(&self) -> Length { self.width } diff --git a/pure/src/widget/container.rs b/pure/src/widget/container.rs index 85ea8039..f42b127d 100644 --- a/pure/src/widget/container.rs +++ b/pure/src/widget/container.rs @@ -11,7 +11,6 @@ use iced_native::{ Clipboard, Hasher, Layout, Length, Padding, Point, Rectangle, Shell, }; -use std::any::{self, Any}; use std::hash::Hash; use std::u32; @@ -124,22 +123,14 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: iced_native::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) + fn children(&self) -> Vec<Tree> { + vec![Tree::new(&self.content)] } fn diff(&self, tree: &mut Tree) { tree.diff_children(std::slice::from_ref(&self.content)) } - fn children_state(&self) -> Vec<Tree> { - vec![Tree::new(&self.content)] - } - fn width(&self) -> Length { self.width } diff --git a/pure/src/widget/element.rs b/pure/src/widget/element.rs index 2a137d40..d905b924 100644 --- a/pure/src/widget/element.rs +++ b/pure/src/widget/element.rs @@ -1,4 +1,5 @@ -use crate::widget::{Tree, Widget}; +use crate::widget::tree::{self, Tree}; +use crate::widget::Widget; use iced_native::event::{self, Event}; use iced_native::layout::{self, Layout}; @@ -6,8 +7,6 @@ use iced_native::mouse; use iced_native::renderer; use iced_native::{Clipboard, Hasher, Length, Point, Rectangle, Shell}; -use std::any::{self, Any}; - pub struct Element<'a, Message, Renderer> { widget: Box<dyn Widget<Message, Renderer> + 'a>, } @@ -66,20 +65,20 @@ where A: 'a, B: 'a, { - fn tag(&self) -> any::TypeId { + fn tag(&self) -> tree::Tag { self.widget.tag() } - fn state(&self) -> Box<dyn Any> { + fn state(&self) -> tree::State { self.widget.state() } - fn diff(&self, tree: &mut Tree) { - self.widget.diff(tree) + fn children(&self) -> Vec<Tree> { + self.widget.children() } - fn children_state(&self) -> Vec<Tree> { - self.widget.children_state() + fn diff(&self, tree: &mut Tree) { + self.widget.diff(tree) } fn width(&self) -> Length { diff --git a/pure/src/widget/image.rs b/pure/src/widget/image.rs index 51a24ed1..ce807813 100644 --- a/pure/src/widget/image.rs +++ b/pure/src/widget/image.rs @@ -6,7 +6,6 @@ use iced_native::renderer; use iced_native::widget::image; use iced_native::{Hasher, Length, Point, Rectangle}; -use std::any::{self, Any}; use std::hash::Hash; pub use image::Image; @@ -16,20 +15,6 @@ where Handle: Clone + Hash, Renderer: iced_native::image::Renderer<Handle = Handle>, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) - } - - fn children_state(&self) -> Vec<Tree> { - Vec::new() - } - - fn diff(&self, _tree: &mut Tree) {} - fn width(&self) -> Length { <Self as iced_native::Widget<Message, Renderer>>::width(self) } diff --git a/pure/src/widget/radio.rs b/pure/src/widget/radio.rs index 25fe5bdd..233297b3 100644 --- a/pure/src/widget/radio.rs +++ b/pure/src/widget/radio.rs @@ -7,8 +7,6 @@ use iced_native::renderer; use iced_native::text; use iced_native::{Clipboard, Hasher, Length, Point, Rectangle, Shell}; -use std::any::{self, Any}; - pub use iced_native::widget::Radio; impl<'a, Message, Renderer> Widget<Message, Renderer> @@ -17,20 +15,6 @@ where Message: Clone, Renderer: text::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) - } - - fn diff(&self, _tree: &mut Tree) {} - - fn children_state(&self) -> Vec<Tree> { - Vec::new() - } - fn width(&self) -> Length { <Self as iced_native::Widget<Message, Renderer>>::width(self) } diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs index ec7e144c..1f281446 100644 --- a/pure/src/widget/row.rs +++ b/pure/src/widget/row.rs @@ -9,8 +9,6 @@ use iced_native::{ Alignment, Clipboard, Hasher, Length, Padding, Point, Rectangle, Shell, }; -use std::any::{self, Any}; - pub struct Row<'a, Message, Renderer> { spacing: u16, padding: Padding, @@ -77,22 +75,14 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: iced_native::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) + fn children(&self) -> Vec<Tree> { + self.children.iter().map(Tree::new).collect() } fn diff(&self, tree: &mut Tree) { tree.diff_children(&self.children) } - fn children_state(&self) -> Vec<Tree> { - self.children.iter().map(Tree::new).collect() - } - fn width(&self) -> Length { self.width } diff --git a/pure/src/widget/scrollable.rs b/pure/src/widget/scrollable.rs index badc9fc2..c3289f9e 100644 --- a/pure/src/widget/scrollable.rs +++ b/pure/src/widget/scrollable.rs @@ -1,4 +1,4 @@ -use crate::widget::Tree; +use crate::widget::tree::{self, Tree}; use crate::{Element, Widget}; use iced_native::event::{self, Event}; @@ -10,8 +10,6 @@ use iced_native::{Clipboard, Hasher, Length, Point, Rectangle, Shell}; pub use iced_style::scrollable::StyleSheet; -use std::any::{self, Any}; - /// A widget that can vertically display an infinite amount of content with a /// scrollbar. #[allow(missing_debug_implementations)] @@ -92,20 +90,20 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: iced_native::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<scrollable::State>() + fn tag(&self) -> tree::Tag { + tree::Tag::of::<scrollable::State>() } - fn state(&self) -> Box<dyn Any> { - Box::new(scrollable::State::new()) + fn state(&self) -> tree::State { + tree::State::new(scrollable::State::new()) } - fn diff(&self, tree: &mut Tree) { - tree.diff_children(std::slice::from_ref(&self.content)) + fn children(&self) -> Vec<Tree> { + vec![Tree::new(&self.content)] } - fn children_state(&self) -> Vec<Tree> { - vec![Tree::new(&self.content)] + fn diff(&self, tree: &mut Tree) { + tree.diff_children(std::slice::from_ref(&self.content)) } fn width(&self) -> Length { diff --git a/pure/src/widget/slider.rs b/pure/src/widget/slider.rs index f659c2ed..691d3f18 100644 --- a/pure/src/widget/slider.rs +++ b/pure/src/widget/slider.rs @@ -1,7 +1,8 @@ //! Display an interactive selector of a single value from a range of values. //! //! A [`Slider`] has some local [`State`]. -use crate::{Element, Tree, Widget}; +use crate::widget::tree::{self, Tree}; +use crate::{Element, Widget}; use iced_native::event::{self, Event}; use iced_native::layout; @@ -12,7 +13,6 @@ use iced_native::{ Clipboard, Hasher, Layout, Length, Point, Rectangle, Shell, Size, }; -use std::any::{self, Any}; use std::ops::RangeInclusive; pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet}; @@ -143,16 +143,12 @@ where Message: Clone, Renderer: iced_native::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<slider::State>() + fn tag(&self) -> tree::Tag { + tree::Tag::of::<slider::State>() } - fn state(&self) -> Box<dyn Any> { - Box::new(slider::State::new()) - } - - fn children_state(&self) -> Vec<Tree> { - Vec::new() + fn state(&self) -> tree::State { + tree::State::new(slider::State::new()) } fn width(&self) -> Length { diff --git a/pure/src/widget/space.rs b/pure/src/widget/space.rs index 67d17c16..d7394398 100644 --- a/pure/src/widget/space.rs +++ b/pure/src/widget/space.rs @@ -7,8 +7,6 @@ use iced_native::renderer; use iced_native::text; use iced_native::{Clipboard, Hasher, Length, Point, Rectangle, Shell}; -use std::any::{self, Any}; - pub use iced_native::widget::Space; impl<'a, Message, Renderer> Widget<Message, Renderer> for Space @@ -16,20 +14,6 @@ where Message: Clone, Renderer: text::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) - } - - fn diff(&self, _tree: &mut Tree) {} - - fn children_state(&self) -> Vec<Tree> { - Vec::new() - } - fn width(&self) -> Length { <Self as iced_native::Widget<Message, Renderer>>::width(self) } diff --git a/pure/src/widget/text.rs b/pure/src/widget/text.rs index 8f157ea0..696d0ae1 100644 --- a/pure/src/widget/text.rs +++ b/pure/src/widget/text.rs @@ -5,28 +5,12 @@ use iced_native::renderer; use iced_native::text; use iced_native::{Hasher, Length, Point, Rectangle}; -use std::any::{self, Any}; - pub use iced_native::widget::Text; impl<Message, Renderer> Widget<Message, Renderer> for Text<Renderer> where Renderer: text::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) - } - - fn diff(&self, _tree: &mut Tree) {} - - fn children_state(&self) -> Vec<Tree> { - Vec::new() - } - fn width(&self) -> Length { <Self as iced_native::Widget<Message, Renderer>>::width(self) } diff --git a/pure/src/widget/text_input.rs b/pure/src/widget/text_input.rs index e18a2bf0..40ce140c 100644 --- a/pure/src/widget/text_input.rs +++ b/pure/src/widget/text_input.rs @@ -1,4 +1,5 @@ -use crate::widget::{Element, Tree, Widget}; +use crate::widget::tree::{self, Tree}; +use crate::widget::{Element, Widget}; use iced_native::event::{self, Event}; use iced_native::layout::{self, Layout}; @@ -12,8 +13,6 @@ use iced_native::{ pub use iced_style::text_input::StyleSheet; -use std::any::{self, Any}; - /// A field that can be filled with text. /// /// # Example @@ -138,18 +137,12 @@ where Message: Clone, Renderer: iced_native::text::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<text_input::State>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(text_input::State::new()) + fn tag(&self) -> tree::Tag { + tree::Tag::of::<text_input::State>() } - fn diff(&self, _tree: &mut Tree) {} - - fn children_state(&self) -> Vec<Tree> { - Vec::new() + fn state(&self) -> tree::State { + tree::State::new(text_input::State::new()) } fn width(&self) -> Length { diff --git a/pure/src/widget/toggler.rs b/pure/src/widget/toggler.rs index ec86fff0..08619866 100644 --- a/pure/src/widget/toggler.rs +++ b/pure/src/widget/toggler.rs @@ -8,8 +8,6 @@ use iced_native::renderer; use iced_native::text; use iced_native::{Clipboard, Hasher, Length, Point, Rectangle, Shell}; -use std::any::{self, Any}; - pub use iced_native::widget::toggler::{Style, StyleSheet, Toggler}; impl<'a, Message, Renderer> Widget<Message, Renderer> @@ -17,18 +15,6 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: text::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box<dyn Any> { - Box::new(()) - } - - fn children_state(&self) -> Vec<Tree> { - Vec::new() - } - fn width(&self) -> Length { <Self as iced_native::Widget<Message, Renderer>>::width(self) } diff --git a/pure/src/widget/tree.rs b/pure/src/widget/tree.rs index 3a5f4433..33f5693a 100644 --- a/pure/src/widget/tree.rs +++ b/pure/src/widget/tree.rs @@ -3,7 +3,7 @@ use crate::widget::Element; use std::any::{self, Any}; pub struct Tree { - pub tag: any::TypeId, + pub tag: Tag, pub state: State, pub children: Vec<Tree>, } @@ -11,8 +11,8 @@ pub struct Tree { impl Tree { pub fn empty() -> Self { Self { - tag: any::TypeId::of::<()>(), - state: State(Box::new(())), + tag: Tag::stateless(), + state: State::None, children: Vec::new(), } } @@ -22,8 +22,8 @@ impl Tree { ) -> Self { Self { tag: element.as_widget().tag(), - state: State(element.as_widget().state()), - children: element.as_widget().children_state(), + state: element.as_widget().state(), + children: element.as_widget().children(), } } @@ -60,20 +60,56 @@ impl Tree { } } -pub struct State(Box<dyn Any>); +#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)] +pub struct Tag(any::TypeId); + +impl Tag { + pub fn of<T>() -> Self + where + T: 'static, + { + Self(any::TypeId::of::<T>()) + } + + pub fn stateless() -> Self { + Self::of::<()>() + } +} + +pub enum State { + None, + Some(Box<dyn Any>), +} impl State { + pub fn new<T>(state: T) -> Self + where + T: 'static, + { + State::Some(Box::new(state)) + } + pub fn downcast_ref<T>(&self) -> &T where T: 'static, { - self.0.downcast_ref().expect("Downcast widget state") + match self { + State::None => panic!("Downcast on stateless state"), + State::Some(state) => { + state.downcast_ref().expect("Downcast widget state") + } + } } pub fn downcast_mut<T>(&mut self) -> &mut T where T: 'static, { - self.0.downcast_mut().expect("Downcast widget state") + match self { + State::None => panic!("Downcast on stateless state"), + State::Some(state) => { + state.downcast_mut().expect("Downcast widget state") + } + } } } |