Expand and stack fixes

This commit is contained in:
Jonathan Johnson 2023-11-29 11:43:52 -08:00
parent 589c3dbc7f
commit 9146c920ac
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
3 changed files with 38 additions and 26 deletions

View file

@ -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<Children> {
/// 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<W> FromIterator<W> for Children
where
W: MakeWidget,

View file

@ -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<u8> {
match self.kind {
ExpandKind::Weighted(weight) => Some(weight),
ExpandKind::Horizontal | ExpandKind::Vertical => None,
pub(crate) fn weight(&self, vertical: bool) -> Option<u8> {
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()),

View file

@ -22,8 +22,7 @@ use crate::ConstraintLimit;
/// [direction](StackDirection).
#[derive(Debug)]
pub struct Stack {
/// The direction to display the children using.
pub direction: Value<StackDirection>,
direction: StackDirection,
/// The children widgets that belong to this array.
pub children: Value<Children>,
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<StackDirection>,
widgets: impl IntoValue<Children>,
) -> Self {
let direction = direction.into_value();
let initial_direction = direction.get();
pub fn new(direction: StackDirection, widgets: impl IntoValue<Children>) -> 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::<Expand>()
.and_then(|expand| expand.weight().map(|weight| (weight, expand)))
{
let (mut widget, dimension) = if let Some((weight, expand)) =
guard.downcast_ref::<Expand>().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;