diff --git a/src/render.rs b/src/render.rs index 91d3a65..cf0c830 100644 --- a/src/render.rs +++ b/src/render.rs @@ -114,3 +114,21 @@ impl DrawContext { self.drawing.clear(); } } + +impl Area { + fn right(&self) -> u16 { + self.x + self.width + } + + fn bottom(&self) -> u16 { + self.y + self.height + } + + pub fn merge(&mut self, other: &Self) { + self.x = self.x.min(other.x); + self.y = self.y.min(other.y); + + self.width = self.right().max(other.right()) - self.x; + self.height = self.bottom().max(other.bottom()) - self.y; + } +} diff --git a/src/view_plugins.rs b/src/view_plugins.rs index 368705a..cda57d0 100644 --- a/src/view_plugins.rs +++ b/src/view_plugins.rs @@ -88,6 +88,37 @@ pub fn size_auto(ctx: &mut DrawContext, _view: &View) { } } +/// Automatically computes both width and height based on drawn content. +/// Merges the allocation for multiple drawings. +pub fn size_auto_merge(ctx: &mut DrawContext, _view: &View) { + ctx.allocated.x = u16::MAX; + ctx.allocated.y = u16::MAX; + ctx.allocated.width = 0; + ctx.allocated.height = 0; + + for i in &ctx.drawing { + match i { + DrawInstruction::Text(_, text) => { + let mut height = 0; + + for line in text.lines() { + ctx.allocated.width = ctx.allocated.width.max(line.len() as u16); + height += 1; + } + + ctx.allocated.height = height; + } + DrawInstruction::View(area, view) => { + let mut c = DrawContext::new(area.clone()); + view(&mut c); + size_auto(&mut c, view); + ctx.allocated.merge(&c.allocated); + } + DrawInstruction::Child(_, _) => {} + } + } +} + /// Automatically computes width based on drawn content. /// /// # Sizing rules