diff --git a/src/layout/stack.rs b/src/layout/stack.rs index c275921..4565657 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -54,6 +54,7 @@ pub struct Stack /// Children with their alignment, margin, and extra `(x, y)` translation /// applied after alignment. Drawn in order — last child is on top. pub children: Vec<( Element, HAlign, VAlign, f32, f32, f32 )>, + pub fit_content: bool, } impl Stack @@ -61,7 +62,13 @@ impl Stack /// Create an empty stack. pub fn new() -> Self { - Self { children: Vec::new() } + Self { children: Vec::new(), fit_content: false } + } + + pub fn fit_content( mut self ) -> Self + { + self.fit_content = true; + self } /// Append a child that fills the entire Stack rect (Android FrameLayout default). @@ -111,9 +118,31 @@ impl Stack self } - /// Return the preferred `(width, height)` — the maximum height among children. pub fn preferred_size( &self, max_width: f32, canvas: &Canvas ) -> (f32, f32) { + if self.fit_content + { + let content_w = self.children.iter() + .map( |( c, _, _, _, _, _ )| match c + { + Element::Spacer( s ) => s.fixed_width.unwrap_or( 0.0 ), + Element::Separator( _ ) => 0.0, + Element::Scroll( _ ) => 0.0, + Element::ProgressBar( _ ) => 0.0, + Element::Slider( _ ) => 0.0, + Element::TextEdit( t ) => if t.fixed_width.is_some() + { + t.preferred_size( max_width, canvas ).0 + } else { 0.0 }, + other => other.preferred_size( max_width, canvas ).0, + } ) + .fold( 0.0_f32, f32::max ); + let max_h = self.children.iter() + .map( |( c, _, _, _, _, _ )| c.preferred_size( max_width, canvas ).1 ) + .fold( 0.0_f32, f32::max ); + return ( content_w.min( max_width ), max_h ); + } + let max_h = self.children.iter() .map( |( c, _, _, _, _, _ )| c.preferred_size( max_width, canvas ).1 ) .fold( 0.0_f32, f32::max ); @@ -163,6 +192,7 @@ impl Stack .map( |( child, ha, va, margin, ox, oy )| ( child.map_arc( f ), ha, va, margin, ox, oy ) ) .collect(), + fit_content: self.fit_content, } } }