Introduce Tag and State opaque types in iced_pure::widget::tree
This commit is contained in:
parent
cff891833b
commit
35e9b75e41
16 changed files with 101 additions and 197 deletions
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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,22 +76,22 @@ 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 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,22 +65,22 @@ 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 children(&self) -> Vec<Tree> {
|
||||
self.widget.children()
|
||||
}
|
||||
|
||||
fn diff(&self, tree: &mut Tree) {
|
||||
self.widget.diff(tree)
|
||||
}
|
||||
|
||||
fn children_state(&self) -> Vec<Tree> {
|
||||
self.widget.children_state()
|
||||
}
|
||||
|
||||
fn width(&self) -> Length {
|
||||
self.widget.width()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,22 +90,22 @@ 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 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.content.as_widget().width()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 tag(&self) -> tree::Tag {
|
||||
tree::Tag::of::<text_input::State>()
|
||||
}
|
||||
|
||||
fn state(&self) -> Box<dyn Any> {
|
||||
Box::new(text_input::State::new())
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue