summaryrefslogtreecommitdiffstats
path: root/core/src/layout.rs
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector@hecrj.dev>2024-01-12 14:41:40 +0100
committerLibravatar GitHub <noreply@github.com>2024-01-12 14:41:40 +0100
commit50c310fd9f692eafb2350827636ffbd6d7b6c9b9 (patch)
tree0f1ab4182a0cce7469e01881c095e0c3988b3f9a /core/src/layout.rs
parent63e9adac56e9a4f21ec82137329d7c455fbf630b (diff)
parent11474bdc3e1a43e6c167d7b98f22d87933dbd2b6 (diff)
downloadiced-50c310fd9f692eafb2350827636ffbd6d7b6c9b9.tar.gz
iced-50c310fd9f692eafb2350827636ffbd6d7b6c9b9.tar.bz2
iced-50c310fd9f692eafb2350827636ffbd6d7b6c9b9.zip
Merge pull request #2192 from iced-rs/fix/layout-inconsistencies
Layout consistency
Diffstat (limited to 'core/src/layout.rs')
-rw-r--r--core/src/layout.rs106
1 files changed, 99 insertions, 7 deletions
diff --git a/core/src/layout.rs b/core/src/layout.rs
index caf315b6..95720aba 100644
--- a/core/src/layout.rs
+++ b/core/src/layout.rs
@@ -7,7 +7,7 @@ pub mod flex;
pub use limits::Limits;
pub use node::Node;
-use crate::{Point, Rectangle, Size, Vector};
+use crate::{Length, Padding, Point, Rectangle, Size, Vector};
/// The bounds of a [`Node`] and its children, using absolute coordinates.
#[derive(Debug, Clone, Copy)]
@@ -71,12 +71,12 @@ pub fn next_to_each_other(
left: impl FnOnce(&Limits) -> Node,
right: impl FnOnce(&Limits) -> Node,
) -> Node {
- let mut left_node = left(limits);
+ let left_node = left(limits);
let left_size = left_node.size();
let right_limits = limits.shrink(Size::new(left_size.width + spacing, 0.0));
- let mut right_node = right(&right_limits);
+ let right_node = right(&right_limits);
let right_size = right_node.size();
let (left_y, right_y) = if left_size.height > right_size.height {
@@ -85,14 +85,106 @@ pub fn next_to_each_other(
((right_size.height - left_size.height) / 2.0, 0.0)
};
- left_node.move_to(Point::new(0.0, left_y));
- right_node.move_to(Point::new(left_size.width + spacing, right_y));
-
Node::with_children(
Size::new(
left_size.width + spacing + right_size.width,
left_size.height.max(right_size.height),
),
- vec![left_node, right_node],
+ vec![
+ left_node.move_to(Point::new(0.0, left_y)),
+ right_node.move_to(Point::new(left_size.width + spacing, right_y)),
+ ],
+ )
+}
+
+/// Computes the resulting [`Node`] that fits the [`Limits`] given
+/// some width and height requirements and no intrinsic size.
+pub fn atomic(
+ limits: &Limits,
+ width: impl Into<Length>,
+ height: impl Into<Length>,
+) -> Node {
+ let width = width.into();
+ let height = height.into();
+
+ Node::new(limits.resolve(width, height, Size::ZERO))
+}
+
+/// Computes the resulting [`Node`] that fits the [`Limits`] given
+/// some width and height requirements and a closure that produces
+/// the intrinsic [`Size`] inside the given [`Limits`].
+pub fn sized(
+ limits: &Limits,
+ width: impl Into<Length>,
+ height: impl Into<Length>,
+ f: impl FnOnce(&Limits) -> Size,
+) -> Node {
+ let width = width.into();
+ let height = height.into();
+
+ let limits = limits.width(width).height(height);
+ let intrinsic_size = f(&limits);
+
+ Node::new(limits.resolve(width, height, intrinsic_size))
+}
+
+/// Computes the resulting [`Node`] that fits the [`Limits`] given
+/// some width and height requirements and a closure that produces
+/// the content [`Node`] inside the given [`Limits`].
+pub fn contained(
+ limits: &Limits,
+ width: impl Into<Length>,
+ height: impl Into<Length>,
+ f: impl FnOnce(&Limits) -> Node,
+) -> Node {
+ let width = width.into();
+ let height = height.into();
+
+ let limits = limits.width(width).height(height);
+ let content = f(&limits);
+
+ Node::with_children(
+ limits.resolve(width, height, content.size()),
+ vec![content],
+ )
+}
+
+/// Computes the [`Node`] that fits the [`Limits`] given some width, height, and
+/// [`Padding`] requirements and a closure that produces the content [`Node`]
+/// inside the given [`Limits`].
+pub fn padded(
+ limits: &Limits,
+ width: impl Into<Length>,
+ height: impl Into<Length>,
+ padding: impl Into<Padding>,
+ layout: impl FnOnce(&Limits) -> Node,
+) -> Node {
+ positioned(limits, width, height, padding, layout, |content, _| content)
+}
+
+/// Computes a [`padded`] [`Node`] with a positioning step.
+pub fn positioned(
+ limits: &Limits,
+ width: impl Into<Length>,
+ height: impl Into<Length>,
+ padding: impl Into<Padding>,
+ layout: impl FnOnce(&Limits) -> Node,
+ position: impl FnOnce(Node, Size) -> Node,
+) -> Node {
+ let width = width.into();
+ let height = height.into();
+ let padding = padding.into();
+
+ let limits = limits.width(width).height(height);
+ let content = layout(&limits.shrink(padding));
+ let padding = padding.fit(content.size(), limits.max());
+
+ let size = limits
+ .shrink(padding)
+ .resolve(width, height, content.size());
+
+ Node::with_children(
+ size.expand(padding),
+ vec![position(content.move_to((padding.left, padding.top)), size)],
)
}