diff options
Diffstat (limited to 'native/src/widget')
-rw-r--r-- | native/src/widget/button.rs | 17 | ||||
-rw-r--r-- | native/src/widget/checkbox.rs | 16 | ||||
-rw-r--r-- | native/src/widget/column.rs | 58 | ||||
-rw-r--r-- | native/src/widget/container.rs | 90 | ||||
-rw-r--r-- | native/src/widget/image.rs | 13 | ||||
-rw-r--r-- | native/src/widget/radio.rs | 20 | ||||
-rw-r--r-- | native/src/widget/row.rs | 58 | ||||
-rw-r--r-- | native/src/widget/scrollable.rs | 38 | ||||
-rw-r--r-- | native/src/widget/slider.rs | 20 | ||||
-rw-r--r-- | native/src/widget/text.rs | 16 | ||||
-rw-r--r-- | native/src/widget/text_input.rs | 33 |
11 files changed, 248 insertions, 131 deletions
diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 31dd6fcc..15beaeba 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -7,7 +7,7 @@ //! [`Class`]: enum.Class.html use crate::input::{mouse, ButtonState}; -use crate::{Element, Event, Hasher, Layout, Node, Point, Widget}; +use crate::{layout, Element, Event, Hasher, Layout, Point, Widget}; use std::hash::Hash; pub use iced_core::button::State; @@ -21,8 +21,12 @@ where Renderer: self::Renderer, Message: Clone + std::fmt::Debug, { - fn node(&self, renderer: &Renderer) -> Node { - renderer.node(&self) + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + renderer.layout(&self, limits) } fn on_event( @@ -74,7 +78,6 @@ where fn hash_layout(&self, state: &mut Hasher) { self.width.hash(state); - self.align_self.hash(state); self.content.hash_layout(state); } } @@ -91,7 +94,11 @@ pub trait Renderer: crate::Renderer + Sized { /// /// [`Node`]: ../../struct.Node.html /// [`Button`]: struct.Button.html - fn node<Message>(&self, button: &Button<'_, Message, Self>) -> Node; + fn layout<Message>( + &self, + button: &Button<'_, Message, Self>, + limits: &layout::Limits, + ) -> layout::Node; /// Draws a [`Button`]. /// diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index b8053238..a7040e02 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -2,7 +2,7 @@ use std::hash::Hash; use crate::input::{mouse, ButtonState}; -use crate::{Element, Event, Hasher, Layout, Node, Point, Widget}; +use crate::{layout, Element, Event, Hasher, Layout, Point, Widget}; pub use iced_core::Checkbox; @@ -10,8 +10,12 @@ impl<Message, Renderer> Widget<Message, Renderer> for Checkbox<Message> where Renderer: self::Renderer, { - fn node(&self, renderer: &Renderer) -> Node { - renderer.node(&self) + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + renderer.layout(&self, limits) } fn on_event( @@ -63,7 +67,11 @@ pub trait Renderer: crate::Renderer { /// /// [`Node`]: ../../struct.Node.html /// [`Checkbox`]: struct.Checkbox.html - fn node<Message>(&self, checkbox: &Checkbox<Message>) -> Node; + fn layout<Message>( + &self, + checkbox: &Checkbox<Message>, + limits: &layout::Limits, + ) -> layout::Node; /// Draws a [`Checkbox`]. /// diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs index 086d05ef..7e7156a0 100644 --- a/native/src/widget/column.rs +++ b/native/src/widget/column.rs @@ -1,6 +1,6 @@ use std::hash::Hash; -use crate::{Element, Event, Hasher, Layout, Node, Point, Style, Widget}; +use crate::{layout, Element, Event, Hasher, Layout, Length, Point, Widget}; /// A container that distributes its contents vertically. pub type Column<'a, Message, Renderer> = @@ -11,42 +11,30 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: self::Renderer, { - fn node(&self, renderer: &Renderer) -> Node { - let mut children: Vec<Node> = self - .children - .iter() - .map(|child| { - let mut node = child.widget.node(renderer); - - let mut style = node.0.style(); - style.margin.bottom = - stretch::style::Dimension::Points(f32::from(self.spacing)); - - node.0.set_style(style); - node - }) - .collect(); - - if let Some(node) = children.last_mut() { - let mut style = node.0.style(); - style.margin.bottom = stretch::style::Dimension::Undefined; - - node.0.set_style(style); - } + fn width(&self) -> Length { + self.width + } - let mut style = Style::default() - .width(self.width) - .height(self.height) + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + let limits = limits .max_width(self.max_width) .max_height(self.max_height) - .padding(self.padding) - .align_self(self.align_self) - .align_items(self.align_items) - .justify_content(self.justify_content); - - style.0.flex_direction = stretch::style::FlexDirection::Column; - - Node::with_children(style, children) + .width(self.width) + .height(self.height); + + layout::flex::resolve( + layout::flex::Axis::Vertical, + renderer, + &limits, + self.padding as f32, + self.spacing as f32, + self.align_items, + &self.children, + ) } fn on_event( @@ -85,9 +73,7 @@ where self.height.hash(state); self.max_width.hash(state); self.max_height.hash(state); - self.align_self.hash(state); self.align_items.hash(state); - self.justify_content.hash(state); self.spacing.hash(state); for child in &self.children { diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs new file mode 100644 index 00000000..c616db2a --- /dev/null +++ b/native/src/widget/container.rs @@ -0,0 +1,90 @@ +use std::hash::Hash; + +use crate::{layout, Element, Event, Hasher, Layout, Length, Point, Widget}; + +/// A container that distributes its contents vertically. +pub type Container<'a, Message, Renderer> = + iced_core::Container<Element<'a, Message, Renderer>>; + +impl<'a, Message, Renderer> Widget<Message, Renderer> + for Container<'a, Message, Renderer> +where + Renderer: crate::Renderer, +{ + fn width(&self) -> Length { + self.width + } + + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + let limits = limits + .loose() + .max_width(self.max_width) + .max_height(self.max_height) + .width(self.width) + .height(self.height); + + let mut content = self.content.layout(renderer, &limits); + let size = limits.resolve(content.size()); + + content.align(self.horizontal_alignment, self.vertical_alignment, size); + + layout::Node::with_children(size, vec![content]) + } + + fn on_event( + &mut self, + event: Event, + layout: Layout<'_>, + cursor_position: Point, + messages: &mut Vec<Message>, + renderer: &Renderer, + ) { + self.content.widget.on_event( + event, + layout.children().next().unwrap(), + cursor_position, + messages, + renderer, + ) + } + + fn draw( + &self, + renderer: &mut Renderer, + layout: Layout<'_>, + cursor_position: Point, + ) -> Renderer::Output { + self.content.draw( + renderer, + layout.children().next().unwrap(), + cursor_position, + ) + } + + fn hash_layout(&self, state: &mut Hasher) { + 0.hash(state); + self.width.hash(state); + self.height.hash(state); + self.max_width.hash(state); + self.max_height.hash(state); + + self.content.hash_layout(state); + } +} + +impl<'a, Message, Renderer> From<Container<'a, Message, Renderer>> + for Element<'a, Message, Renderer> +where + Renderer: 'a + crate::Renderer, + Message: 'static, +{ + fn from( + column: Container<'a, Message, Renderer>, + ) -> Element<'a, Message, Renderer> { + Element::new(column) + } +} diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs index 6255a7b5..b2541b87 100644 --- a/native/src/widget/image.rs +++ b/native/src/widget/image.rs @@ -1,6 +1,6 @@ //! Display images in your user interface. -use crate::{Element, Hasher, Layout, Node, Point, Widget}; +use crate::{layout, Element, Hasher, Layout, Point, Widget}; use std::hash::Hash; @@ -10,8 +10,12 @@ impl<Message, Renderer> Widget<Message, Renderer> for Image where Renderer: self::Renderer, { - fn node(&self, renderer: &Renderer) -> Node { - renderer.node(&self) + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + renderer.layout(&self, limits) } fn draw( @@ -26,7 +30,6 @@ where fn hash_layout(&self, state: &mut Hasher) { self.width.hash(state); self.height.hash(state); - self.align_self.hash(state); } } @@ -44,7 +47,7 @@ pub trait Renderer: crate::Renderer { /// /// [`Node`]: ../../struct.Node.html /// [`Image`]: struct.Image.html - fn node(&self, image: &Image) -> Node; + fn layout(&self, image: &Image, limits: &layout::Limits) -> layout::Node; /// Draws an [`Image`]. /// diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs index 626e6ffc..b68919e5 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -1,6 +1,6 @@ //! Create choices using radio buttons. use crate::input::{mouse, ButtonState}; -use crate::{Element, Event, Hasher, Layout, Node, Point, Widget}; +use crate::{layout, Element, Event, Hasher, Layout, Length, Point, Widget}; use std::hash::Hash; @@ -11,8 +11,16 @@ where Renderer: self::Renderer, Message: Clone + std::fmt::Debug, { - fn node(&self, renderer: &Renderer) -> Node { - renderer.node(&self) + fn width(&self) -> Length { + Length::Fill + } + + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + renderer.layout(&self, limits) } fn on_event( @@ -62,7 +70,11 @@ pub trait Renderer: crate::Renderer { /// /// [`Node`]: ../../struct.Node.html /// [`Radio`]: struct.Radio.html - fn node<Message>(&self, radio: &Radio<Message>) -> Node; + fn layout<Message>( + &self, + radio: &Radio<Message>, + limits: &layout::Limits, + ) -> layout::Node; /// Draws a [`Radio`] button. /// diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs index 7dbfb92a..132479fd 100644 --- a/native/src/widget/row.rs +++ b/native/src/widget/row.rs @@ -1,6 +1,6 @@ use std::hash::Hash; -use crate::{Element, Event, Hasher, Layout, Node, Point, Style, Widget}; +use crate::{layout, Element, Event, Hasher, Layout, Length, Point, Widget}; /// A container that distributes its contents horizontally. pub type Row<'a, Message, Renderer> = @@ -11,42 +11,30 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: self::Renderer, { - fn node(&self, renderer: &Renderer) -> Node { - let mut children: Vec<Node> = self - .children - .iter() - .map(|child| { - let mut node = child.widget.node(renderer); - - let mut style = node.0.style(); - style.margin.end = - stretch::style::Dimension::Points(f32::from(self.spacing)); - - node.0.set_style(style); - node - }) - .collect(); - - if let Some(node) = children.last_mut() { - let mut style = node.0.style(); - style.margin.end = stretch::style::Dimension::Undefined; - - node.0.set_style(style); - } + fn width(&self) -> Length { + self.width + } - let mut style = Style::default() - .width(self.width) - .height(self.height) + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + let limits = limits .max_width(self.max_width) .max_height(self.max_height) - .padding(self.padding) - .align_self(self.align_self) - .align_items(self.align_items) - .justify_content(self.justify_content); - - style.0.flex_direction = stretch::style::FlexDirection::Row; - - Node::with_children(style, children) + .width(self.width) + .height(self.height); + + layout::flex::resolve( + layout::flex::Axis::Horizontal, + renderer, + &limits, + self.padding as f32, + self.spacing as f32, + self.align_items, + &self.children, + ) } fn on_event( @@ -85,9 +73,7 @@ where self.height.hash(state); self.max_width.hash(state); self.max_height.hash(state); - self.align_self.hash(state); self.align_items.hash(state); - self.justify_content.hash(state); self.spacing.hash(state); self.spacing.hash(state); diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index de4c749c..091dac47 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -1,11 +1,13 @@ use crate::{ column, input::{mouse, ButtonState}, - Element, Event, Hasher, Layout, Node, Point, Rectangle, Style, Widget, + layout, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size, + Widget, }; pub use iced_core::scrollable::State; +use std::f32; use std::hash::Hash; /// A scrollable [`Column`]. @@ -19,26 +21,25 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> where Renderer: self::Renderer + column::Renderer, { - fn node(&self, renderer: &Renderer) -> Node { - let mut content = self.content.node(renderer); - - { - let mut style = content.0.style(); - style.flex_shrink = 0.0; - - content.0.set_style(style); - } - - let mut style = Style::default() - .width(self.content.width) - .max_width(self.content.max_width) - .height(self.height) + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + let limits = limits .max_height(self.max_height) - .align_self(self.align_self); + .width(Length::Fill) + .height(self.height); + + let child_limits = layout::Limits::new( + Size::new(limits.min().width, 0.0), + Size::new(limits.max().width, f32::INFINITY), + ); - style.0.flex_direction = stretch::style::FlexDirection::Column; + let content = self.content.layout(renderer, &child_limits); + let size = limits.resolve(content.size()); - Node::with_children(style, vec![content]) + layout::Node::with_children(size, vec![content]) } fn on_event( @@ -167,7 +168,6 @@ where self.height.hash(state); self.max_height.hash(state); - self.align_self.hash(state); self.content.hash_layout(state) } diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index be2b9b22..3a998c40 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -7,7 +7,7 @@ use std::hash::Hash; use crate::input::{mouse, ButtonState}; -use crate::{Element, Event, Hasher, Layout, Node, Point, Widget}; +use crate::{layout, Element, Event, Hasher, Layout, Length, Point, Widget}; pub use iced_core::slider::*; @@ -15,8 +15,16 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> for Slider<'a, Message> where Renderer: self::Renderer, { - fn node(&self, renderer: &Renderer) -> Node { - renderer.node(&self) + fn width(&self) -> Length { + self.width + } + + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + renderer.layout(&self, limits) } fn on_event( @@ -93,7 +101,11 @@ pub trait Renderer: crate::Renderer { /// /// [`Node`]: ../../struct.Node.html /// [`Radio`]: struct.Radio.html - fn node<Message>(&self, slider: &Slider<'_, Message>) -> Node; + fn layout<Message>( + &self, + slider: &Slider<'_, Message>, + limits: &layout::Limits, + ) -> layout::Node; /// Draws a [`Slider`]. /// diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs index e389e1d9..10d892a3 100644 --- a/native/src/widget/text.rs +++ b/native/src/widget/text.rs @@ -1,5 +1,5 @@ //! Write some text for your users to read. -use crate::{Element, Hasher, Layout, Node, Point, Widget}; +use crate::{layout, Element, Hasher, Layout, Length, Point, Widget}; use std::hash::Hash; @@ -9,8 +9,16 @@ impl<Message, Renderer> Widget<Message, Renderer> for Text where Renderer: self::Renderer, { - fn node(&self, renderer: &Renderer) -> Node { - renderer.node(&self) + fn width(&self) -> Length { + self.width + } + + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + renderer.layout(&self, limits) } fn draw( @@ -49,7 +57,7 @@ pub trait Renderer: crate::Renderer { /// [`Style`]: ../../struct.Style.html /// [`Text`]: struct.Text.html /// [`Node::with_measure`]: ../../struct.Node.html#method.with_measure - fn node(&self, text: &Text) -> Node; + fn layout(&self, text: &Text, limits: &layout::Limits) -> layout::Node; /// Draws a [`Text`] fragment. /// diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index d9837b61..7e81e257 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -1,6 +1,6 @@ use crate::{ input::{keyboard, mouse, ButtonState}, - Element, Event, Hasher, Layout, Length, Node, Point, Rectangle, Style, + layout, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; @@ -11,19 +11,24 @@ where Renderer: self::Renderer, Message: Clone + std::fmt::Debug, { - fn node(&self, renderer: &Renderer) -> Node { - let text_bounds = - Node::new(Style::default().width(Length::Fill).height( - Length::Units(self.size.unwrap_or(renderer.default_size())), - )); - - Node::with_children( - Style::default() - .width(self.width) - .max_width(self.width) - .padding(self.padding), - vec![text_bounds], - ) + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + let padding = self.padding as f32; + let text_size = self.size.unwrap_or(renderer.default_size()); + + let limits = limits + .pad(padding) + .width(self.width) + .height(Length::Units(text_size)); + + let mut text = layout::Node::new(limits.resolve(Size::ZERO)); + text.bounds.x = padding; + text.bounds.y = padding; + + layout::Node::with_children(text.size().pad(padding), vec![text]) } fn on_event( |