From af122265f6663e429a3732ecdbbf2356688702b5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 11 Feb 2022 23:39:41 +0700 Subject: Implement `Row` in `iced_pure` --- pure/src/widget/row.rs | 223 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 pure/src/widget/row.rs (limited to 'pure/src/widget/row.rs') diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs new file mode 100644 index 00000000..2581b38a --- /dev/null +++ b/pure/src/widget/row.rs @@ -0,0 +1,223 @@ +use crate::flex; +use crate::widget::{Element, Tree, Widget}; + +use iced_native::event::{self, Event}; +use iced_native::layout::{self, Layout}; +use iced_native::mouse; +use iced_native::renderer; +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, + width: Length, + height: Length, + align_items: Alignment, + children: Vec>, +} + +impl<'a, Message, Renderer> Row<'a, Message, Renderer> { + pub fn new() -> Self { + Self::with_children(Vec::new()) + } + + pub fn with_children( + children: Vec>, + ) -> Self { + Row { + spacing: 0, + padding: Padding::ZERO, + width: Length::Shrink, + height: Length::Shrink, + align_items: Alignment::Start, + children, + } + } + + pub fn spacing(mut self, units: u16) -> Self { + self.spacing = units; + self + } + + pub fn padding>(mut self, padding: P) -> Self { + self.padding = padding.into(); + self + } + + pub fn width(mut self, width: Length) -> Self { + self.width = width; + self + } + + pub fn height(mut self, height: Length) -> Self { + self.height = height; + self + } + + pub fn align_items(mut self, align: Alignment) -> Self { + self.align_items = align; + self + } + + pub fn push( + mut self, + child: impl Into>, + ) -> Self { + self.children.push(child.into()); + self + } +} + +impl<'a, Message, Renderer> Widget + for Row<'a, Message, Renderer> +where + Renderer: iced_native::Renderer, +{ + fn tag(&self) -> any::TypeId { + struct Marker; + any::TypeId::of::() + } + + fn state(&self) -> Box { + Box::new(()) + } + + fn children(&self) -> &[Element] { + &self.children + } + + fn width(&self) -> Length { + self.width + } + + fn height(&self) -> Length { + self.height + } + + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + let limits = limits.width(self.width).height(self.height); + + flex::resolve( + flex::Axis::Horizontal, + renderer, + &limits, + self.padding, + self.spacing as f32, + self.align_items, + &self.children, + ) + } + + fn on_event( + &mut self, + tree: &mut Tree, + event: Event, + layout: Layout<'_>, + cursor_position: Point, + renderer: &Renderer, + clipboard: &mut dyn Clipboard, + shell: &mut Shell<'_, Message>, + ) -> event::Status { + self.children + .iter_mut() + .zip(&mut tree.children) + .zip(layout.children()) + .map(|((child, state), layout)| { + child.as_widget_mut().on_event( + state, + event.clone(), + layout, + cursor_position, + renderer, + clipboard, + shell, + ) + }) + .fold(event::Status::Ignored, event::Status::merge) + } + + fn mouse_interaction( + &self, + tree: &Tree, + layout: Layout<'_>, + cursor_position: Point, + viewport: &Rectangle, + renderer: &Renderer, + ) -> mouse::Interaction { + self.children + .iter() + .zip(&tree.children) + .zip(layout.children()) + .map(|((child, state), layout)| { + child.as_widget().mouse_interaction( + state, + layout, + cursor_position, + viewport, + renderer, + ) + }) + .max() + .unwrap_or_default() + } + + fn draw( + &self, + tree: &Tree, + renderer: &mut Renderer, + style: &renderer::Style, + layout: Layout<'_>, + cursor_position: Point, + viewport: &Rectangle, + ) { + for ((child, state), layout) in self + .children + .iter() + .zip(&tree.children) + .zip(layout.children()) + { + child.as_widget().draw( + state, + renderer, + style, + layout, + cursor_position, + viewport, + ); + } + } + + fn hash_layout(&self, state: &mut Hasher) { + use std::hash::Hash; + + self.tag().hash(state); + self.width.hash(state); + self.height.hash(state); + self.align_items.hash(state); + self.spacing.hash(state); + self.padding.hash(state); + + for child in &self.children { + child.as_widget().hash_layout(state); + } + } +} + +impl<'a, Message, Renderer> Into> + for Row<'a, Message, Renderer> +where + Message: 'static, + Renderer: iced_native::Renderer + 'static, +{ + fn into(self) -> Element<'a, Message, Renderer> { + Element::new(self) + } +} -- cgit From 8b27083cdaa2ef7b749e0fd2c1a94b5606ed1c3d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 11 Feb 2022 23:40:24 +0700 Subject: Use `TypeId` of `()` for `Column` and `Row` tags in `iced_pure` --- pure/src/widget/row.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'pure/src/widget/row.rs') diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs index 2581b38a..147a0850 100644 --- a/pure/src/widget/row.rs +++ b/pure/src/widget/row.rs @@ -78,8 +78,7 @@ where Renderer: iced_native::Renderer, { fn tag(&self) -> any::TypeId { - struct Marker; - any::TypeId::of::() + any::TypeId::of::<()>() } fn state(&self) -> Box { -- cgit From bd22cc0bc0f7551d29cf2acd22520f4a906f253c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 12 Feb 2022 17:21:28 +0700 Subject: Implement pure version of `todos` example :tada: The `Widget` trait in `iced_pure` needed to change a bit to make the implementation of `Element::map` possible. Specifically, the `children` method has been split into `diff` and `children_state`. --- pure/src/widget/row.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'pure/src/widget/row.rs') diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs index 147a0850..ec7e144c 100644 --- a/pure/src/widget/row.rs +++ b/pure/src/widget/row.rs @@ -85,8 +85,12 @@ where Box::new(()) } - fn children(&self) -> &[Element] { - &self.children + fn diff(&self, tree: &mut Tree) { + tree.diff_children(&self.children) + } + + fn children_state(&self) -> Vec { + self.children.iter().map(Tree::new).collect() } fn width(&self) -> Length { -- cgit From 35e9b75e415ef3b9124051696b60628ef56afe47 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 16 Feb 2022 15:44:50 +0700 Subject: Introduce `Tag` and `State` opaque types in `iced_pure::widget::tree` --- pure/src/widget/row.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'pure/src/widget/row.rs') 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 where Renderer: iced_native::Renderer, { - fn tag(&self) -> any::TypeId { - any::TypeId::of::<()>() - } - - fn state(&self) -> Box { - Box::new(()) + fn children(&self) -> Vec { + self.children.iter().map(Tree::new).collect() } fn diff(&self, tree: &mut Tree) { tree.diff_children(&self.children) } - fn children_state(&self) -> Vec { - self.children.iter().map(Tree::new).collect() - } - fn width(&self) -> Length { self.width } -- cgit From 019af8ddbf96680ffcee2b3407819e90575760cb Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 16 Feb 2022 17:07:25 +0700 Subject: Add `overlay` support in `iced_pure` and port `PickList` :tada: --- pure/src/widget/row.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'pure/src/widget/row.rs') diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs index 1f281446..29128589 100644 --- a/pure/src/widget/row.rs +++ b/pure/src/widget/row.rs @@ -1,4 +1,5 @@ use crate::flex; +use crate::overlay; use crate::widget::{Element, Tree, Widget}; use iced_native::event::{self, Event}; @@ -202,6 +203,15 @@ where child.as_widget().hash_layout(state); } } + + fn overlay<'b>( + &'b mut self, + tree: &'b mut Tree, + layout: Layout<'_>, + renderer: &Renderer, + ) -> Option> { + overlay::from_children(&mut self.children, tree, layout, renderer) + } } impl<'a, Message, Renderer> Into> -- cgit From da45b6c1627935bff5334d213096c4e78972af46 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 17 Feb 2022 19:08:54 +0700 Subject: Implement `pure::Component` in `iced_lazy` --- pure/src/widget/row.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pure/src/widget/row.rs') diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs index 29128589..1c574d51 100644 --- a/pure/src/widget/row.rs +++ b/pure/src/widget/row.rs @@ -205,12 +205,12 @@ where } fn overlay<'b>( - &'b mut self, + &'b self, tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, ) -> Option> { - overlay::from_children(&mut self.children, tree, layout, renderer) + overlay::from_children(&self.children, tree, layout, renderer) } } -- cgit From d7100fd2597da82d97eaf196d50573ea64f3f8ff Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 16 Mar 2022 17:37:19 +0700 Subject: Export widget modules in `iced_pure` ... and fix collisions with the new `helpers` --- pure/src/widget/row.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'pure/src/widget/row.rs') diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs index fa0efa68..d7f90540 100644 --- a/pure/src/widget/row.rs +++ b/pure/src/widget/row.rs @@ -1,6 +1,7 @@ use crate::flex; use crate::overlay; -use crate::widget::{Element, Tree, Widget}; +use crate::widget::Tree; +use crate::{Element, Widget}; use iced_native::event::{self, Event}; use iced_native::layout::{self, Layout}; -- cgit