macro_rules! impl_stack_for_each {
($Stack:ident, $Layout:ident) => {
impl<C, F, V> $Stack<ForEach<C, F, V>>
where
C: Collection,
C::Item: Identifiable,
F: 'static + Fn(C::Item) -> V,
V: View,
{
pub fn for_each(collection: C, generator: F) -> Self {
Self {
layout: $Layout::default(),
contents: ForEach::new(collection, generator),
}
}
}
};
}
pub(crate) use impl_stack_for_each;
pub(crate) mod distribute;
mod vstack;
pub use vstack::*;
mod hstack;
pub use hstack::*;
mod zstack;
pub use zstack::*;
pub use waterui_core::layout::{Alignment, HorizontalAlignment, VerticalAlignment};
use crate::Layout;
use nami::Computed;
use waterui_core::layout::StretchAxis;
pub(crate) fn stack_stretch_axis(main: Axis, children: &[StretchAxis]) -> StretchAxis {
let mut fills_main = false;
let mut fills_cross = false;
for child in children {
match child {
StretchAxis::None => {}
StretchAxis::Both => {
fills_main = true;
fills_cross = true;
}
StretchAxis::MainAxis => fills_main = true,
StretchAxis::CrossAxis => fills_cross = true,
StretchAxis::Horizontal => {
if main.is_horizontal() {
fills_main = true;
} else {
fills_cross = true;
}
}
StretchAxis::Vertical => {
if main.is_vertical() {
fills_main = true;
} else {
fills_cross = true;
}
}
}
}
let (horizontal, vertical) = if main.is_horizontal() {
(fills_main, fills_cross)
} else {
(fills_cross, fills_main)
};
match (horizontal, vertical) {
(true, true) => StretchAxis::Both,
(true, false) => StretchAxis::Horizontal,
(false, true) => StretchAxis::Vertical,
(false, false) => StretchAxis::None,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Axis {
Horizontal,
Vertical,
}
impl Axis {
#[must_use]
pub const fn is_horizontal(&self) -> bool {
matches!(self, Self::Horizontal)
}
#[must_use]
pub const fn is_vertical(&self) -> bool {
matches!(self, Self::Vertical)
}
}
#[derive(Debug, Clone)]
pub enum LazyStackAxis {
Vertical {
spacing: Computed<f32>,
alignment: HorizontalAlignment,
},
Horizontal {
spacing: Computed<f32>,
alignment: VerticalAlignment,
},
}
#[must_use]
pub fn lazy_stack_axis(layout: &dyn Layout) -> Option<LazyStackAxis> {
let layout = layout as &dyn core::any::Any;
if let Some(vstack) = layout.downcast_ref::<VStackLayout>() {
return Some(LazyStackAxis::Vertical {
spacing: vstack.spacing.clone(),
alignment: vstack.alignment,
});
}
if let Some(hstack) = layout.downcast_ref::<HStackLayout>() {
return Some(LazyStackAxis::Horizontal {
spacing: hstack.spacing.clone(),
alignment: hstack.alignment,
});
}
None
}