use cvkg_core::{LayoutView, SizeProposal, Rect, LayoutCache, Size};
pub struct HStack {
spacing: f32,
children: Vec<Box<dyn LayoutView>>,
}
impl HStack {
pub fn new(spacing: f32) -> Self {
Self {
spacing,
children: Vec::new(),
}
}
pub fn add_view<V: LayoutView + 'static>(&mut self, view: V) {
self.children.push(Box::new(view));
}
}
impl LayoutView for HStack {
fn size_that_fits(&self, proposal: SizeProposal, subviews: &[&dyn LayoutView], cache: &mut LayoutCache) -> Size {
let mut width = 0.0f32;
let mut height = 0.0f32;
for (i, child) in subviews.iter().enumerate() {
let child_size = child.size_that_fits(proposal, &[], cache);
width += child_size.width;
height = height.max(child_size.height);
if i < subviews.len() - 1 {
width += self.spacing;
}
}
Size { width, height }
}
fn place_subviews(&self, bounds: Rect, subviews: &mut [&mut dyn LayoutView], cache: &mut LayoutCache) {
let mut x = bounds.x;
let y = bounds.y;
for (_i, child) in subviews.iter_mut().enumerate() {
let desired_size = child.size_that_fits(SizeProposal::unspecified(), &[], cache);
let child_rect = Rect {
x,
y,
width: desired_size.width,
height: bounds.height,
};
child.place_subviews(child_rect, &mut [], cache);
x += desired_size.width + self.spacing;
}
}
}
pub struct VStack {
spacing: f32,
children: Vec<Box<dyn LayoutView>>,
}
impl VStack {
pub fn new(spacing: f32) -> Self {
Self {
spacing,
children: Vec::new(),
}
}
pub fn add_view<V: LayoutView + 'static>(&mut self, view: V) {
self.children.push(Box::new(view));
}
}
impl LayoutView for VStack {
fn size_that_fits(&self, proposal: SizeProposal, subviews: &[&dyn LayoutView], cache: &mut LayoutCache) -> Size {
let mut width = 0.0f32;
let mut height = 0.0f32;
for (i, child) in subviews.iter().enumerate() {
let child_size = child.size_that_fits(proposal, &[], cache);
width = width.max(child_size.width);
height += child_size.height;
if i < subviews.len() - 1 {
height += self.spacing;
}
}
Size { width, height }
}
fn place_subviews(&self, bounds: Rect, subviews: &mut [&mut dyn LayoutView], cache: &mut LayoutCache) {
let x = bounds.x;
let mut y = bounds.y;
for (_i, child) in subviews.iter_mut().enumerate() {
let desired_size = child.size_that_fits(SizeProposal::unspecified(), &[], cache);
let child_rect = Rect {
x,
y,
width: bounds.width,
height: desired_size.height,
};
child.place_subviews(child_rect, &mut [], cache);
y += desired_size.height + self.spacing;
}
}
}
pub struct ZStack {
children: Vec<Box<dyn LayoutView>>,
}
impl ZStack {
pub fn new() -> Self {
Self {
children: Vec::new(),
}
}
pub fn add_view<V: LayoutView + 'static>(&mut self, view: V) {
self.children.push(Box::new(view));
}
}
impl LayoutView for ZStack {
fn size_that_fits(&self, proposal: SizeProposal, subviews: &[&dyn LayoutView], cache: &mut LayoutCache) -> Size {
let mut width = 0.0f32;
let mut height = 0.0f32;
for child in subviews.iter() {
let child_size = child.size_that_fits(proposal, &[], cache);
width = width.max(child_size.width);
height = height.max(child_size.height);
}
Size { width, height }
}
fn place_subviews(&self, bounds: Rect, subviews: &mut [&mut dyn LayoutView], cache: &mut LayoutCache) {
for child in subviews.iter_mut() {
child.place_subviews(bounds, &mut [], cache);
}
}
}