summaryrefslogtreecommitdiffstats
path: root/native/src/widget
diff options
context:
space:
mode:
Diffstat (limited to 'native/src/widget')
-rw-r--r--native/src/widget/button.rs17
-rw-r--r--native/src/widget/checkbox.rs16
-rw-r--r--native/src/widget/column.rs58
-rw-r--r--native/src/widget/container.rs90
-rw-r--r--native/src/widget/image.rs13
-rw-r--r--native/src/widget/radio.rs20
-rw-r--r--native/src/widget/row.rs58
-rw-r--r--native/src/widget/scrollable.rs38
-rw-r--r--native/src/widget/slider.rs20
-rw-r--r--native/src/widget/text.rs16
-rw-r--r--native/src/widget/text_input.rs33
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(