summaryrefslogtreecommitdiffstats
path: root/pure
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-02-16 15:44:50 +0700
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-02-16 15:44:50 +0700
commit35e9b75e415ef3b9124051696b60628ef56afe47 (patch)
treedc81a8bfa59634072d2e439d32bdf263dd4f610a /pure
parentcff891833be68c0e2d4919d4475daf23da821f9b (diff)
downloadiced-35e9b75e415ef3b9124051696b60628ef56afe47.tar.gz
iced-35e9b75e415ef3b9124051696b60628ef56afe47.tar.bz2
iced-35e9b75e415ef3b9124051696b60628ef56afe47.zip
Introduce `Tag` and `State` opaque types in `iced_pure::widget::tree`
Diffstat (limited to 'pure')
-rw-r--r--pure/src/widget.rs20
-rw-r--r--pure/src/widget/button.rs21
-rw-r--r--pure/src/widget/checkbox.rs16
-rw-r--r--pure/src/widget/column.rs13
-rw-r--r--pure/src/widget/container.rs13
-rw-r--r--pure/src/widget/element.rs17
-rw-r--r--pure/src/widget/image.rs15
-rw-r--r--pure/src/widget/radio.rs16
-rw-r--r--pure/src/widget/row.rs14
-rw-r--r--pure/src/widget/scrollable.rs20
-rw-r--r--pure/src/widget/slider.rs16
-rw-r--r--pure/src/widget/space.rs16
-rw-r--r--pure/src/widget/text.rs16
-rw-r--r--pure/src/widget/text_input.rs19
-rw-r--r--pure/src/widget/toggler.rs14
-rw-r--r--pure/src/widget/tree.rs52
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")
+ }
+ }
}
}