From 9146c920ac7970eae30775aa64802406f85815f9 Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Wed, 29 Nov 2023 11:43:52 -0800 Subject: [PATCH] Expand and stack fixes --- src/widget.rs | 18 ++++++++++++++++-- src/widgets/expand.rs | 15 ++++++++------- src/widgets/stack.rs | 31 ++++++++++++++----------------- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/widget.rs b/src/widget.rs index da6019f..24e00f2 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -34,7 +34,7 @@ use crate::styles::{ }; use crate::tree::Tree; use crate::utils::IgnorePoison; -use crate::value::{IntoDynamic, IntoValue, Validation, Value}; +use crate::value::{Dynamic, IntoDynamic, IntoValue, Validation, Value}; use crate::widgets::checkbox::{Checkable, CheckboxState}; use crate::widgets::{ Align, Button, Checkbox, Collapse, Container, Expand, Resize, Scroll, Space, Stack, Style, @@ -880,7 +880,7 @@ pub trait MakeWidget: Sized { /// Expands `self` to grow to fill its parent vertically. #[must_use] fn expand_vertically(self) -> Expand { - Expand::horizontal(self) + Expand::vertical(self) } /// Resizes `self` to `size`. @@ -1647,6 +1647,20 @@ impl Children { } } +impl Dynamic { + /// Returns `self` as a vertical [`Stack`] of rows. + #[must_use] + pub fn into_rows(self) -> Stack { + Stack::rows(self) + } + + /// Returns `self` as a horizontal [`Stack`] of columns. + #[must_use] + pub fn into_columns(self) -> Stack { + Stack::columns(self) + } +} + impl FromIterator for Children where W: MakeWidget, diff --git a/src/widgets/expand.rs b/src/widgets/expand.rs index 83bf4fc..ddeaf15 100644 --- a/src/widgets/expand.rs +++ b/src/widgets/expand.rs @@ -15,7 +15,7 @@ pub struct Expand { child: WidgetRef, } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] enum ExpandKind { Weighted(u8), Horizontal, @@ -84,10 +84,11 @@ impl Expand { } #[must_use] - pub(crate) fn weight(&self) -> Option { - match self.kind { - ExpandKind::Weighted(weight) => Some(weight), - ExpandKind::Horizontal | ExpandKind::Vertical => None, + pub(crate) fn weight(&self, vertical: bool) -> Option { + match (self.kind, vertical) { + (ExpandKind::Weighted(weight), _) => Some(weight), + (ExpandKind::Horizontal, false) | (ExpandKind::Vertical, true) => Some(1), + (ExpandKind::Horizontal | ExpandKind::Vertical, _) => None, } } } @@ -123,10 +124,10 @@ impl WrapperWidget for Expand { available_space .width .fit_measured(size.width, context.gfx.scale()), - size.height, + size.height.min(available_space.height.max()), ), ExpandKind::Vertical => ( - size.width, + size.width.min(available_space.width.max()), available_space .height .fit_measured(size.height, context.gfx.scale()), diff --git a/src/widgets/stack.rs b/src/widgets/stack.rs index 8fbf605..46a78ee 100644 --- a/src/widgets/stack.rs +++ b/src/widgets/stack.rs @@ -22,8 +22,7 @@ use crate::ConstraintLimit; /// [direction](StackDirection). #[derive(Debug)] pub struct Stack { - /// The direction to display the children using. - pub direction: Value, + direction: StackDirection, /// The children widgets that belong to this array. pub children: Value, layout: Layout, @@ -34,18 +33,11 @@ pub struct Stack { impl Stack { /// Returns a new widget with the given direction and widgets. - pub fn new( - direction: impl IntoValue, - widgets: impl IntoValue, - ) -> Self { - let direction = direction.into_value(); - - let initial_direction = direction.get(); - + pub fn new(direction: StackDirection, widgets: impl IntoValue) -> Self { Self { direction, children: widgets.into_value(), - layout: Layout::new(initial_direction), + layout: Layout::new(direction), layout_generation: None, synced_children: Vec::new(), } @@ -63,6 +55,7 @@ impl Stack { fn synchronize_children(&mut self, context: &mut EventContext<'_, '_>) { let current_generation = self.children.generation(); + self.children.invalidate_when_changed(context); if current_generation.map_or_else( || self.children.map(Children::len) != self.layout.children.len(), |gen| Some(gen) != self.layout_generation, @@ -89,10 +82,12 @@ impl Stack { } else { // This is a brand new child. let guard = widget.lock(); - let (mut widget, dimension) = if let Some((weight, expand)) = guard - .downcast_ref::() - .and_then(|expand| expand.weight().map(|weight| (weight, expand))) - { + let (mut widget, dimension) = if let Some((weight, expand)) = + guard.downcast_ref::().and_then(|expand| { + expand + .weight(self.direction.orientation == StackOrientation::Row) + .map(|weight| (weight, expand)) + }) { ( expand.child().clone(), StackDimension::Fractional { weight }, @@ -429,8 +424,10 @@ impl Layout { let index = self.children.index_of_id(id).expect("child not found"); let (measured, other) = self.orientation.split_size(measure( index, - self.orientation - .make_size(ConstraintLimit::SizeToFit(remaining), other_constraint), + self.orientation.make_size( + ConstraintLimit::SizeToFit(available_space), + other_constraint, + ), !needs_final_layout, )); self.layouts[index].size = measured;