diff options
Diffstat (limited to 'core/src/layout.rs')
-rw-r--r-- | core/src/layout.rs | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/core/src/layout.rs b/core/src/layout.rs index 277473fe..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)] @@ -96,3 +96,95 @@ pub fn next_to_each_other( ], ) } + +/// 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)], + ) +} |