diff options
author | 2023-03-16 20:23:25 +0100 | |
---|---|---|
committer | 2024-01-04 06:51:21 +0100 | |
commit | 0655a20ad119e2e9790afcc45039fd4ac0e7d432 (patch) | |
tree | 0ce316e386e5b47b6ca80fe16f0a384ef05ff4e8 | |
parent | 68c0484b5cf6f572e4cb0bf72c22c1a93dbb654e (diff) | |
download | iced-0655a20ad119e2e9790afcc45039fd4ac0e7d432.tar.gz iced-0655a20ad119e2e9790afcc45039fd4ac0e7d432.tar.bz2 iced-0655a20ad119e2e9790afcc45039fd4ac0e7d432.zip |
Make `Shrink` have priority over `Fill` in layout
46 files changed, 265 insertions, 274 deletions
diff --git a/core/src/layout.rs b/core/src/layout.rs index caf315b6..277473fe 100644 --- a/core/src/layout.rs +++ b/core/src/layout.rs @@ -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,14 @@ 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)), + ], ) } diff --git a/core/src/layout/flex.rs b/core/src/layout/flex.rs index c02b63d8..738dc81d 100644 --- a/core/src/layout/flex.rs +++ b/core/src/layout/flex.rs @@ -20,7 +20,7 @@ use crate::Element; use crate::layout::{Limits, Node}; use crate::widget; -use crate::{Alignment, Padding, Point, Size}; +use crate::{Alignment, Length, Padding, Point, Size}; /// The main axis of a flex layout. #[derive(Debug)] @@ -63,6 +63,8 @@ pub fn resolve<Message, Renderer>( axis: Axis, renderer: &Renderer, limits: &Limits, + width: Length, + height: Length, padding: Padding, spacing: f32, align_items: Alignment, @@ -72,12 +74,12 @@ pub fn resolve<Message, Renderer>( where Renderer: crate::Renderer, { - let limits = limits.pad(padding); + let limits = limits.width(width).height(height).shrink(padding); let total_spacing = spacing * items.len().saturating_sub(1) as f32; let max_cross = axis.cross(limits.max()); let mut fill_sum = 0; - let mut cross = axis.cross(limits.min()).max(axis.cross(limits.fill())); + let mut cross = 0.0f32; let mut available = axis.main(limits.max()) - total_spacing; let mut nodes: Vec<Node> = Vec::with_capacity(items.len()); @@ -109,7 +111,16 @@ where } } - let remaining = available.max(0.0); + let remaining = match axis { + Axis::Horizontal => match width { + Length::Shrink => 0.0, + _ => available.max(0.0), + }, + Axis::Vertical => match height { + Length::Shrink => 0.0, + _ => available.max(0.0), + }, + }; for (i, (child, tree)) in items.iter().zip(trees).enumerate() { let fill_factor = match axis { @@ -154,18 +165,18 @@ where let (x, y) = axis.pack(main, pad.1); - node.move_to(Point::new(x, y)); + node.move_to_mut(Point::new(x, y)); match axis { Axis::Horizontal => { - node.align( + node.align_mut( Alignment::Start, align_items, Size::new(0.0, cross), ); } Axis::Vertical => { - node.align( + node.align_mut( align_items, Alignment::Start, Size::new(cross, 0.0), @@ -179,7 +190,7 @@ where } let (width, height) = axis.pack(main - pad.0, cross); - let size = limits.resolve(Size::new(width, height)); + let size = limits.resolve(Size::new(width, height), width, height); - Node::with_children(size.pad(padding), nodes) + Node::with_children(size.expand(padding), nodes) } diff --git a/core/src/layout/limits.rs b/core/src/layout/limits.rs index 39a3d98b..eef4c4c9 100644 --- a/core/src/layout/limits.rs +++ b/core/src/layout/limits.rs @@ -1,12 +1,11 @@ #![allow(clippy::manual_clamp)] -use crate::{Length, Padding, Size}; +use crate::{Length, Size}; /// A set of size constraints for layouting. #[derive(Debug, Clone, Copy, PartialEq)] pub struct Limits { min: Size, max: Size, - fill: Size, } impl Limits { @@ -14,16 +13,11 @@ impl Limits { pub const NONE: Limits = Limits { min: Size::ZERO, max: Size::INFINITY, - fill: Size::INFINITY, }; /// Creates new [`Limits`] with the given minimum and maximum [`Size`]. pub const fn new(min: Size, max: Size) -> Limits { - Limits { - min, - max, - fill: Size::INFINITY, - } + Limits { min, max } } /// Returns the minimum [`Size`] of the [`Limits`]. @@ -36,26 +30,15 @@ impl Limits { self.max } - /// Returns the fill [`Size`] of the [`Limits`]. - pub fn fill(&self) -> Size { - self.fill - } - /// Applies a width constraint to the current [`Limits`]. pub fn width(mut self, width: impl Into<Length>) -> Limits { match width.into() { - Length::Shrink => { - self.fill.width = self.min.width; - } - Length::Fill | Length::FillPortion(_) => { - self.fill.width = self.fill.width.min(self.max.width); - } + Length::Shrink | Length::Fill | Length::FillPortion(_) => {} Length::Fixed(amount) => { let new_width = amount.min(self.max.width).max(self.min.width); self.min.width = new_width; self.max.width = new_width; - self.fill.width = new_width; } } @@ -65,19 +48,13 @@ impl Limits { /// Applies a height constraint to the current [`Limits`]. pub fn height(mut self, height: impl Into<Length>) -> Limits { match height.into() { - Length::Shrink => { - self.fill.height = self.min.height; - } - Length::Fill | Length::FillPortion(_) => { - self.fill.height = self.fill.height.min(self.max.height); - } + Length::Shrink | Length::Fill | Length::FillPortion(_) => {} Length::Fixed(amount) => { let new_height = amount.min(self.max.height).max(self.min.height); self.min.height = new_height; self.max.height = new_height; - self.fill.height = new_height; } } @@ -112,13 +89,10 @@ impl Limits { self } - /// Shrinks the current [`Limits`] to account for the given padding. - pub fn pad(&self, padding: Padding) -> Limits { - self.shrink(Size::new(padding.horizontal(), padding.vertical())) - } - /// Shrinks the current [`Limits`] by the given [`Size`]. - pub fn shrink(&self, size: Size) -> Limits { + pub fn shrink(&self, size: impl Into<Size>) -> Limits { + let size = size.into(); + let min = Size::new( (self.min().width - size.width).max(0.0), (self.min().height - size.height).max(0.0), @@ -129,12 +103,7 @@ impl Limits { (self.max().height - size.height).max(0.0), ); - let fill = Size::new( - (self.fill.width - size.width).max(0.0), - (self.fill.height - size.height).max(0.0), - ); - - Limits { min, max, fill } + Limits { min, max } } /// Removes the minimum width constraint for the current [`Limits`]. @@ -142,22 +111,38 @@ impl Limits { Limits { min: Size::ZERO, max: self.max, - fill: self.fill, } } /// Computes the resulting [`Size`] that fits the [`Limits`] given the /// intrinsic size of some content. - pub fn resolve(&self, intrinsic_size: Size) -> Size { - Size::new( - intrinsic_size - .width - .min(self.max.width) - .max(self.fill.width), - intrinsic_size + pub fn resolve( + &self, + intrinsic_size: Size, + width: impl Into<Length>, + height: impl Into<Length>, + ) -> Size { + let width = match width.into() { + Length::Fill | Length::FillPortion(_) => self.max.width, + Length::Fixed(amount) => { + amount.min(self.max.width).max(self.min.width) + } + Length::Shrink => { + intrinsic_size.width.min(self.max.width).max(self.min.width) + } + }; + + let height = match height.into() { + Length::Fill | Length::FillPortion(_) => self.max.height, + Length::Fixed(amount) => { + amount.min(self.max.height).max(self.min.height) + } + Length::Shrink => intrinsic_size .height .min(self.max.height) - .max(self.fill.height), - ) + .max(self.min.height), + }; + + Size::new(width, height) } } diff --git a/core/src/layout/node.rs b/core/src/layout/node.rs index 2b44a7d5..00087431 100644 --- a/core/src/layout/node.rs +++ b/core/src/layout/node.rs @@ -1,4 +1,4 @@ -use crate::{Alignment, Point, Rectangle, Size, Vector}; +use crate::{Alignment, Padding, Point, Rectangle, Size, Vector}; /// The bounds of an element and its children. #[derive(Debug, Clone, Default)] @@ -26,6 +26,14 @@ impl Node { } } + /// Creates a new [`Node`] that wraps a single child with some [`Padding`]. + pub fn container(child: Self, padding: Padding) -> Self { + Self::with_children( + child.bounds.size().expand(padding), + vec![child.move_to(Point::new(padding.left, padding.top))], + ) + } + /// Returns the [`Size`] of the [`Node`]. pub fn size(&self) -> Size { Size::new(self.bounds.width, self.bounds.height) @@ -43,6 +51,17 @@ impl Node { /// Aligns the [`Node`] in the given space. pub fn align( + mut self, + horizontal_alignment: Alignment, + vertical_alignment: Alignment, + space: Size, + ) -> Self { + self.align_mut(horizontal_alignment, vertical_alignment, space); + self + } + + /// Mutable reference version of [`align`]. + pub fn align_mut( &mut self, horizontal_alignment: Alignment, vertical_alignment: Alignment, @@ -70,7 +89,13 @@ impl Node { } /// Moves the [`Node`] to the given position. - pub fn move_to(&mut self, position: Point) { + pub fn move_to(mut self, position: Point) -> Self { + self.move_to_mut(position); + self + } + + /// Mutable reference version of [`move_to`]. + pub fn move_to_mut(&mut self, position: Point) { self.bounds.x = position.x; self.bounds.y = position.y; } diff --git a/core/src/padding.rs b/core/src/padding.rs index 0b1bba13..a63f6e29 100644 --- a/core/src/padding.rs +++ b/core/src/padding.rs @@ -154,3 +154,9 @@ impl From<[f32; 4]> for Padding { } } } + +impl From<Padding> for Size { + fn from(padding: Padding) -> Self { + Self::new(padding.horizontal(), padding.vertical()) + } +} diff --git a/core/src/size.rs b/core/src/size.rs index 7ef2f602..90e50d13 100644 --- a/core/src/size.rs +++ b/core/src/size.rs @@ -1,4 +1,4 @@ -use crate::{Padding, Vector}; +use crate::Vector; /// An amount of space in 2 dimensions. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -26,15 +26,7 @@ impl Size { /// A [`Size`] with infinite width and height. pub const INFINITY: Size = Size::new(f32::INFINITY, f32::INFINITY); - /// Increments the [`Size`] to account for the given padding. - pub fn pad(&self, padding: Padding) -> Self { - Size { - width: self.width + padding.horizontal(), - height: self.height + padding.vertical(), - } - } - - /// Returns the minimum of each component of this size and another + /// Returns the minimum of each component of this size and another. pub fn min(self, other: Self) -> Self { Size { width: self.width.min(other.width), @@ -42,13 +34,23 @@ impl Size { } } - /// Returns the maximum of each component of this size and another + /// Returns the maximum of each component of this size and another. pub fn max(self, other: Self) -> Self { Size { width: self.width.max(other.width), height: self.height.max(other.height), } } + + /// Expands this [`Size`] by the given amount. + pub fn expand(self, other: impl Into<Size>) -> Self { + let other = other.into(); + + Size { + width: self.width + other.width, + height: self.height + other.height, + } + } } impl From<[f32; 2]> for Size { diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index e020b030..e47e4178 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -224,7 +224,7 @@ where shaping, }); - let size = limits.resolve(paragraph.min_bounds()); + let size = limits.resolve(paragraph.min_bounds(), width, height); layout::Node::new(size) } diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index 96840143..56f7afd5 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -146,7 +146,8 @@ impl Application for GameOfLife { .view() .map(move |message| Message::Grid(message, version)), controls, - ]; + ] + .height(Length::Fill); container(content) .width(Length::Fill) @@ -178,7 +179,6 @@ fn view_controls<'a>( slider(1.0..=1000.0, speed as f32, Message::SpeedChanged), text(format!("x{speed}")).size(16), ] - .width(Length::Fill) .align_items(Alignment::Center) .spacing(10); diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs index 8ab3b493..50227f1c 100644 --- a/examples/geometry/src/main.rs +++ b/examples/geometry/src/main.rs @@ -30,7 +30,7 @@ mod rainbow { _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let size = limits.width(Length::Fill).resolve(Size::ZERO); + let size = limits.resolve(Size::ZERO, Length::Fill, Length::Shrink); layout::Node::new(Size::new(size.width, size.width)) } diff --git a/examples/integration/src/controls.rs b/examples/integration/src/controls.rs index 4714c397..89a595c1 100644 --- a/examples/integration/src/controls.rs +++ b/examples/integration/src/controls.rs @@ -81,32 +81,25 @@ impl Program for Controls { ); Row::new() - .width(Length::Fill) .height(Length::Fill) .align_items(Alignment::End) .push( - Column::new() - .width(Length::Fill) - .align_items(Alignment::End) - .push( - Column::new() - .padding(10) - .spacing(10) - .push( - Text::new("Background color") - .style(Color::WHITE), - ) - .push(sliders) - .push( - Text::new(format!("{background_color:?}")) - .size(14) - .style(Color::WHITE), - ) - .push( - text_input("Placeholder", text) - .on_input(Message::TextChanged), - ), - ), + Column::new().align_items(Alignment::End).push( + Column::new() + .padding(10) + .spacing(10) + .push(Text::new("Background color").style(Color::WHITE)) + .push(sliders) + .push( + Text::new(format!("{background_color:?}")) + .size(14) + .style(Color::WHITE), + ) + .push( + text_input("Placeholder", text) + .on_input(Message::TextChanged), + ), + ), ) .into() } diff --git a/examples/loading_spinners/src/circular.rs b/examples/loading_spinners/src/circular.rs index dca8046a..a92a5dd1 100644 --- a/examples/loading_spinners/src/circular.rs +++ b/examples/loading_spinners/src/circular.rs @@ -259,7 +259,7 @@ where limits: &layout::Limits, ) -> layout::Node { let limits = limits.width(self.size).height(self.size); - let size = limits.resolve(Size::ZERO); + let size = limits.resolve(Size::ZERO, self.size, self.size); layout::Node::new(size) } diff --git a/examples/loading_spinners/src/linear.rs b/examples/loading_spinners/src/linear.rs index db10bfba..da4f1ea1 100644 --- a/examples/loading_spinners/src/linear.rs +++ b/examples/loading_spinners/src/linear.rs @@ -180,7 +180,7 @@ where limits: &layout::Limits, ) -> layout::Node { let limits = limits.width(self.width).height(self.height); - let size = limits.resolve(Size::ZERO); + let size = limits.resolve(Size::ZERO, self.width, self.height); layout::Node::new(size) } diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index acb14372..85ccf8b4 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -420,17 +420,14 @@ mod modal { .width(Length::Fill) .height(Length::Fill); - let mut child = self + let child = self .content .as_widget() - .layout(self.tree, renderer, &limits); + .layout(self.tree, renderer, &limits) + .align(Alignment::Center, Alignment::Center, limits.max()); - child.align(Alignment::Center, Alignment::Center, limits.max()); - - let mut node = layout::Node::with_children(self.size, vec![child]); - node.move_to(position); - - node + layout::Node::with_children(self.size, vec![child]) + .move_to(position) } fn on_event( diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index aa3149bb..96bb8e4e 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -297,7 +297,6 @@ fn view_content<'a>( text(format!("{}x{}", size.width, size.height)).size(24), controls, ] - .width(Length::Fill) .spacing(10) .align_items(Alignment::Center); diff --git a/examples/pick_list/src/main.rs b/examples/pick_list/src/main.rs index 21200621..bfd642f5 100644 --- a/examples/pick_list/src/main.rs +++ b/examples/pick_list/src/main.rs @@ -48,7 +48,6 @@ impl Sandbox for Example { pick_list, vertical_space(600), ] - .width(Length::Fill) .align_items(Alignment::Center) .spacing(10); diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index d82ea841..1042e7a4 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -147,35 +147,30 @@ impl Application for ScrollableDemo { text("Scroller width:"), scroller_width_slider, ] - .spacing(10) - .width(Length::Fill); + .spacing(10); - let scroll_orientation_controls = column(vec![ - text("Scrollbar direction:").into(), + let scroll_orientation_controls = column![ + text("Scrollbar direction:"), radio( "Vertical", Direction::Vertical, Some(self.scrollable_direction), Message::SwitchDirection, - ) - .into(), + ), radio( "Horizontal", Direction::Horizontal, Some(self.scrollable_direction), Message::SwitchDirection, - ) - .into(), + ), radio( "Both!", Direction::Multi, Some(self.scrollable_direction), Message::SwitchDirection, - ) - .into(), - ]) - .spacing(10) - .width(Length::Fill); + ), + ] + .spacing(10); let scroll_alignment_controls = column(vec![ text("Scrollable alignment:").into(), @@ -194,16 +189,14 @@ impl Application for ScrollableDemo { ) .into(), ]) - .spacing(10) - .width(Length::Fill); + .spacing(10); let scroll_controls = row![ scroll_slider_controls, scroll_orientation_controls, scroll_alignment_controls ] - .spacing(20) - .width(Length::Fill); + .spacing(20); let scroll_to_end_button = || { button("Scroll to end") @@ -229,7 +222,6 @@ impl Application for ScrollableDemo { text("End!"), scroll_to_beginning_button(), ] - .width(Length::Fill) .align_items(Alignment::Center) .padding([40, 0, 40, 0]) .spacing(40), @@ -341,7 +333,6 @@ impl Application for ScrollableDemo { let content: Element<Message> = column![scroll_controls, scrollable_content, progress_bars] - .width(Length::Fill) .height(Length::Fill) .align_items(Alignment::Center) .spacing(10) diff --git a/examples/sierpinski_triangle/src/main.rs b/examples/sierpinski_triangle/src/main.rs index ef935c33..01a114bb 100644 --- a/examples/sierpinski_triangle/src/main.rs +++ b/examples/sierpinski_triangle/src/main.rs @@ -79,12 +79,10 @@ impl Application for SierpinskiEmulator { row![ text(format!("Iteration: {:?}", self.graph.iteration)), slider(0..=10000, self.graph.iteration, Message::IterationSet) - .width(Length::Fill) ] .padding(10) .spacing(20), ] - .width(Length::Fill) .align_items(iced::Alignment::Center) .into() } diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 51538ec2..f14f6a8f 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -104,10 +104,11 @@ impl Sandbox for Styling { let progress_bar = progress_bar(0.0..=100.0, self.slider_value); - let scrollable = scrollable( - column!["Scroll me!", vertical_space(800), "You did it!"] - .width(Length::Fill), - ) + let scrollable = scrollable(column![ + "Scroll me!", + vertical_space(800), + "You did it!" + ]) .width(Length::Fill) .height(100); diff --git a/examples/svg/src/main.rs b/examples/svg/src/main.rs index 4dc92416..3bf4960f 100644 --- a/examples/svg/src/main.rs +++ b/examples/svg/src/main.rs @@ -63,7 +63,6 @@ impl Sandbox for Tiger { container(apply_color_filter).width(Length::Fill).center_x() ] .spacing(20) - .width(Length::Fill) .height(Length::Fill), ) .width(Length::Fill) diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 31b6f191..711d8223 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -106,9 +106,7 @@ impl Application for App { fn view<'a>(&'a self) -> Element<'a, Message> { let subtitle = |title, content: Element<'a, Message>| { - column![text(title).size(14), content] - .width(Length::Fill) - .spacing(5) + column![text(title).size(14), content].spacing(5) }; let mut add_toast = button("Add Toast"); @@ -153,14 +151,11 @@ impl Application for App { Message::Timeout ) .step(1.0) - .width(Length::Fill) ] .spacing(5) .into() ), - column![add_toast] - .width(Length::Fill) - .align_items(Alignment::End) + column![add_toast].align_items(Alignment::End) ] .spacing(10) .max_width(200), @@ -513,14 +508,14 @@ mod toast { position: Point, _translation: Vector, ) -> layout::Node { - let limits = layout::Limits::new(Size::ZERO, bounds) - .width(Length::Fill) - .height(Length::Fill); + let limits = layout::Limits::new(Size::ZERO, bounds); layout::flex::resolve( layout::flex::Axis::Vertical, renderer, &limits, + Length::Fill, + Length::Fill, 10.into(), 10.0, Alignment::End, diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 7003d8ae..b9ee1e61 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -692,11 +692,7 @@ fn ferris<'a>( } fn button<'a, Message: Clone>(label: &str) -> Button<'a, Message> { - iced::widget::button( - text(label).horizontal_alignment(alignment::Horizontal::Center), - ) - .padding(12) - .width(100) + iced::widget::button(text(label)).padding([12, 24]) } fn color_slider<'a>( diff --git a/examples/websocket/src/main.rs b/examples/websocket/src/main.rs index 920189f5..5fdf6657 100644 --- a/examples/websocket/src/main.rs +++ b/examples/websocket/src/main.rs @@ -116,7 +116,6 @@ impl Application for WebSocket { .map(Element::from) .collect(), ) - .width(Length::Fill) .spacing(10), ) .id(MESSAGE_LOG.clone()) @@ -149,7 +148,6 @@ impl Application for WebSocket { }; column![message_log, new_message_input] - .width(Length::Fill) .height(Length::Fill) .padding(20) .spacing(10) diff --git a/widget/src/button.rs b/widget/src/button.rs index 384a3156..ba68caa5 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -433,13 +433,18 @@ pub fn layout( ) -> layout::Node { let limits = limits.width(width).height(height); - let mut content = layout_content(&limits.pad(padding)); + let content = layout_content(&limits.shrink(padding)); let padding = padding.fit(content.size(), limits.max()); - let size = limits.pad(padding).resolve(content.size()).pad(padding); - content.move_to(Point::new(padding.left, padding.top)); + let size = limits + .shrink(padding) + .resolve(content.size(), width, height) + .expand(padding); - layout::Node::with_children(size, vec![content]) + layout::Node::with_children( + size, + vec![content.move_to(Point::new(padding.left, padding.top))], + ) } /// Returns the [`mouse::Interaction`] of a [`Button`]. diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs index 390f4d92..9e33c113 100644 --- a/widget/src/canvas.rs +++ b/widget/src/canvas.rs @@ -133,8 +133,7 @@ where _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits.width(self.width).height(self.height); - let size = limits.resolve(Size::ZERO); + let size = limits.resolve(Size::ZERO, self.width, self.height); layout::Node::new(size) } diff --git a/widget/src/column.rs b/widget/src/column.rs index abb522be..526509bb 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -35,7 +35,7 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> { Column { spacing: 0.0, padding: Padding::ZERO, - width: Length::Shrink, + width: Length::Fill, height: Length::Shrink, max_width: f32::INFINITY, align_items: Alignment::Start, @@ -126,15 +126,14 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits - .max_width(self.max_width) - .width(self.width) - .height(self.height); + let limits = limits.max_width(self.max_width); layout::flex::resolve( layout::flex::Axis::Vertical, renderer, &limits, + self.width, + self.height, self.padding, self.spacing, self.align_items, diff --git a/widget/src/container.rs b/widget/src/container.rs index 5dd7705b..b41a6023 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -312,24 +312,27 @@ pub fn layout( layout_content: impl FnOnce(&layout::Limits) -> layout::Node, ) -> layout::Node { let limits = limits - .loose() - .max_width(max_width) - .max_height(max_height) .width(width) - .height(height); + .height(height) + .max_width(max_width) + .max_height(max_height); - let mut content = layout_content(&limits.pad(padding).loose()); + let content = layout_content(&limits.shrink(padding).loose()); let padding = padding.fit(content.size(), limits.max()); - let size = limits.pad(padding).resolve(content.size()); - - content.move_to(Point::new(padding.left, padding.top)); - content.align( - Alignment::from(horizontal_alignment), - Alignment::from(vertical_alignment), - size, - ); - - layout::Node::with_children(size.pad(padding), vec![content]) + let size = limits + .shrink(padding) + .resolve(content.size(), width, height); + + layout::Node::with_children( + size.expand(padding), + vec![content + .move_to(Point::new(padding.left, padding.top)) + .align( + Alignment::from(horizontal_alignment), + Alignment::from(vertical_alignment), + size, + )], + ) } /// Draws the background of a [`Container`] given its [`Appearance`] and its `bounds`. diff --git a/widget/src/image.rs b/widget/src/image.rs index 67699102..b5f1e907 100644 --- a/widget/src/image.rs +++ b/widget/src/image.rs @@ -99,7 +99,7 @@ where }; // The size to be available to the widget prior to `Shrink`ing - let raw_size = limits.width(width).height(height).resolve(image_size); + let raw_size = limits.resolve(image_size, width, height); // The uncropped size of the image when fit to the bounds above let full_size = content_fit.fit(image_size, raw_size); diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index 68015ba8..23c4fe86 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -113,10 +113,11 @@ where ) -> layout::Node { let Size { width, height } = renderer.dimensions(&self.handle); - let mut size = limits - .width(self.width) - .height(self.height) - .resolve(Size::new(width as f32, height as f32)); + let mut size = limits.resolve( + Size::new(width as f32, height as f32), + self.width, + self.height, + ); let expansion_size = if height > width { self.width diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index 0ef82407..1b53b43a 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -196,6 +196,8 @@ where layout::flex::Axis::Vertical, renderer, &limits, + self.width, + self.height, self.padding, self.spacing, self.align_items, diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index e45b44ae..ef39a952 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -254,15 +254,14 @@ where ) .width(self.width); - let mut node = self.container.layout(self.state, renderer, &limits); + let node = self.container.layout(self.state, renderer, &limits); + let size = node.size(); node.move_to(if space_below > space_above { position + Vector::new(0.0, self.target_height) } else { - position - Vector::new(0.0, node.size().height) - }); - - node + position - Vector::new(0.0, size.height) + }) } fn on_event( @@ -359,7 +358,6 @@ where ) -> layout::Node { use std::f32; - let limits = limits.width(Length::Fill).height(Length::Shrink); let text_size = self.text_size.unwrap_or_else(|| renderer.default_size()); @@ -372,7 +370,7 @@ where * self.options.len() as f32, ); - limits.resolve(intrinsic) + limits.resolve(intrinsic, Length::Fill, Length::Shrink) }; layout::Node::new(size) diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 7057fe59..3d799fd3 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -490,8 +490,7 @@ pub fn layout<Renderer, T>( &layout::Limits, ) -> layout::Node, ) -> layout::Node { - let limits = limits.width(width).height(height); - let size = limits.resolve(Size::ZERO); + let size = limits.resolve(Size::ZERO, width, height); let regions = node.pane_regions(spacing, size); let children = contents @@ -500,16 +499,14 @@ pub fn layout<Renderer, T>( let region = regions.get(&pane)?; let size = Size::new(region.width, region.height); - let mut node = layout_content( + let node = layout_content( content, tree, renderer, &layout::Limits::new(size, size), ); - node.move_to(Point::new(region.x, region.y)); - - Some(node) + Some(node.move_to(Point::new(region.x, region.y))) }) .collect(); diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index 826ea663..ee00f186 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -165,7 +165,7 @@ where let title_bar_size = title_bar_layout.size(); - let mut body_layout = self.body.as_widget().layout( + let body_layout = self.body.as_widget().layout( &mut tree.children[0], renderer, &layout::Limits::new( @@ -177,11 +177,12 @@ where ), ); - body_layout.move_to(Point::new(0.0, title_bar_size.height)); - layout::Node::with_children( max_size, - vec![title_bar_layout, body_layout], + vec![ + title_bar_layout, + body_layout.move_to(Point::new(0.0, title_bar_size.height)), + ], ) } else { self.body.as_widget().layout( diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index f4dbb6b1..eb21b743 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -217,7 +217,7 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits.pad(self.padding); + let limits = limits.shrink(self.padding); let max_size = limits.max(); let title_layout = self.content.as_widget().layout( @@ -228,8 +228,8 @@ where let title_size = title_layout.size(); - let mut node = if let Some(controls) = &self.controls { - let mut controls_layout = controls.as_widget().layout( + let node = if let Some(controls) = &self.controls { + let controls_layout = controls.as_widget().layout( &mut tree.children[1], renderer, &layout::Limits::new(Size::ZERO, max_size), @@ -240,11 +240,13 @@ where let height = title_size.height.max(controls_size.height); - controls_layout.move_to(Point::new(space_before_controls, 0.0)); - layout::Node::with_children( Size::new(max_size.width, height), - vec![title_layout, controls_layout], + vec![ + title_layout, + controls_layout + .move_to(Point::new(space_before_controls, 0.0)), + ], ) } else { layout::Node::with_children( @@ -253,9 +255,7 @@ where ) }; - node.move_to(Point::new(self.padding.left, self.padding.top)); - - layout::Node::with_children(node.size().pad(self.padding), vec![node]) + layout::Node::container(node, self.padding) } pub(crate) fn operate( diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 022ca8d9..13110725 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -393,7 +393,7 @@ where { use std::f32; - let limits = limits.width(width).height(Length::Shrink).pad(padding); + let limits = limits.width(width).height(Length::Shrink); let font = font.unwrap_or_else(|| renderer.default_font()); let text_size = text_size.unwrap_or_else(|| renderer.default_size()); @@ -451,7 +451,10 @@ where f32::from(text_line_height.to_absolute(text_size)), ); - limits.resolve(intrinsic).pad(padding) + limits + .shrink(padding) + .resolve(intrinsic, width, Length::Shrink) + .expand(padding) }; layout::Node::new(size) diff --git a/widget/src/progress_bar.rs b/widget/src/progress_bar.rs index 07de72d5..b84ab2dd 100644 --- a/widget/src/progress_bar.rs +++ b/widget/src/progress_bar.rs @@ -99,11 +99,11 @@ where _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits - .width(self.width) - .height(self.height.unwrap_or(Length::Fixed(Self::DEFAULT_HEIGHT))); - - let size = limits.resolve(Size::ZERO); + let size = limits.resolve( + Size::ZERO, + self.width, + self.height.unwrap_or(Length::Fixed(Self::DEFAULT_HEIGHT)), + ); layout::Node::new(size) } diff --git a/widget/src/row.rs b/widget/src/row.rs index d52b8c43..650c2c7d 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -34,7 +34,7 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> { Row { spacing: 0.0, padding: Padding::ZERO, - width: Length::Shrink, + width: Length::Fill, height: Length::Shrink, align_items: Alignment::Start, children, @@ -118,12 +118,12 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits.width(self.width).height(self.height); - layout::flex::resolve( layout::flex::Axis::Horizontal, renderer, &limits, + self.width, + self.height, self.padding, self.spacing, self.align_items, diff --git a/widget/src/rule.rs b/widget/src/rule.rs index b5c5fa55..ecaedf60 100644 --- a/widget/src/rule.rs +++ b/widget/src/rule.rs @@ -76,9 +76,7 @@ where _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits.width(self.width).height(self.height); - - layout::Node::new(limits.resolve(Size::ZERO)) + layout::Node::new(limits.resolve(Size::ZERO, self.width, self.height)) } fn draw( diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 49aed2f0..525463c4 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -489,7 +489,7 @@ pub fn layout<Renderer>( ); let content = layout_content(renderer, &child_limits); - let size = limits.resolve(content.size()); + let size = limits.resolve(content.size(), width, height); layout::Node::with_children(size, vec![content]) } diff --git a/widget/src/shader.rs b/widget/src/shader.rs index 8e334693..5b18ec7d 100644 --- a/widget/src/shader.rs +++ b/widget/src/shader.rs @@ -85,7 +85,7 @@ where limits: &layout::Limits, ) -> layout::Node { let limits = limits.width(self.width).height(self.height); - let size = limits.resolve(Size::ZERO); + let size = limits.resolve(Size::ZERO, self.width, self.height); layout::Node::new(size) } diff --git a/widget/src/slider.rs b/widget/src/slider.rs index ac0982c8..2b600d9d 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -173,8 +173,7 @@ where _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits.width(self.width).height(self.height); - let size = limits.resolve(Size::ZERO); + let size = limits.resolve(Size::ZERO, self.width, self.height); layout::Node::new(size) } diff --git a/widget/src/space.rs b/widget/src/space.rs index e5a8f169..afa9a7c8 100644 --- a/widget/src/space.rs +++ b/widget/src/space.rs @@ -59,9 +59,7 @@ where _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits.width(self.width).height(self.height); - - layout::Node::new(limits.resolve(Size::ZERO)) + layout::Node::new(limits.resolve(Size::ZERO, self.width, self.height)) } fn draw( diff --git a/widget/src/svg.rs b/widget/src/svg.rs index 2d01d1ab..8367ad18 100644 --- a/widget/src/svg.rs +++ b/widget/src/svg.rs @@ -115,10 +115,7 @@ where let image_size = Size::new(width as f32, height as f32); // The size to be available to the widget prior to `Shrink`ing - let raw_size = limits - .width(self.width) - .height(self.height) - .resolve(image_size); + let raw_size = limits.resolve(image_size, self.width, self.height); // The uncropped size of the image when fit to the bounds above let full_size = self.content_fit.fit(image_size, raw_size); diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index a2a186f0..214bce17 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -350,7 +350,7 @@ where } internal.editor.update( - limits.pad(self.padding).max(), + limits.shrink(self.padding).max(), self.font.unwrap_or_else(|| renderer.default_font()), self.text_size.unwrap_or_else(|| renderer.default_size()), self.line_height, diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 65d3e1eb..03eb2fd0 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -506,14 +506,11 @@ where { let font = font.unwrap_or_else(|| renderer.default_font()); let text_size = size.unwrap_or_else(|| renderer.default_size()); - let padding = padding.fit(Size::ZERO, limits.max()); - let limits = limits - .width(width) - .pad(padding) - .height(line_height.to_absolute(text_size)); + let height = line_height.to_absolute(text_size); - let text_bounds = limits.resolve(Size::ZERO); + let limits = limits.width(width).shrink(padding).height(height); + let text_bounds = limits.resolve(Size::ZERO, width, height); let placeholder_text = Text { font, @@ -552,41 +549,41 @@ where let icon_width = state.icon.min_width(); - let mut text_node = layout::Node::new( - text_bounds - Size::new(icon_width + icon.spacing, 0.0), - ); - - let mut icon_node = - layout::Node::new(Size::new(icon_width, text_bounds.height)); - - match icon.side { - Side::Left => { - text_node.move_to(Point::new( + let (text_position, icon_position) = match icon.side { + Side::Left => ( + Point::new( padding.left + icon_width + icon.spacing, padding.top, - )); - - icon_node.move_to(Point::new(padding.left, padding.top)); - } - Side::Right => { - text_node.move_to(Point::new(padding.left, padding.top)); - - icon_node.move_to(Point::new( + ), + Point::new(padding.left, padding.top), + ), + Side::Right => ( + Point::new(padding.left, padding.top), + Point::new( padding.left + text_bounds.width - icon_width, padding.top, - )); - } + ), + ), }; + let text_node = layout::Node::new( + text_bounds - Size::new(icon_width + icon.spacing, 0.0), + ) + .move_to(text_position); + + let icon_node = + layout::Node::new(Size::new(icon_width, text_bounds.height)) + .move_to(icon_position); + layout::Node::with_children( - text_bounds.pad(padding), + text_bounds.expand(padding), vec![text_node, icon_node], ) } else { - let mut text = layout::Node::new(text_bounds); - text.move_to(Point::new(padding.left, padding.top)); + let text = layout::Node::new(text_bounds) + .move_to(Point::new(padding.left, padding.top)); - layout::Node::with_children(text_bounds.pad(padding), vec![text]) + layout::Node::with_children(text_bounds.expand(padding), vec![text]) } } diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index b888980a..adef13e4 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -353,7 +353,7 @@ where .then(|| viewport.size()) .unwrap_or(Size::INFINITY), ) - .pad(Padding::new(self.padding)), + .shrink(Padding::new(self.padding)), ); let text_bounds = text_layout.bounds(); diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index 01d3359c..e489104c 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -170,8 +170,7 @@ where _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits.width(self.width).height(self.height); - let size = limits.resolve(Size::ZERO); + let size = limits.resolve(Size::ZERO, self.width, self.height); layout::Node::new(size) } |