diff options
Diffstat (limited to 'src/library/shape.rs')
| -rw-r--r-- | src/library/shape.rs | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/src/library/shape.rs b/src/library/shape.rs index 5be26aa4..c64dedb3 100644 --- a/src/library/shape.rs +++ b/src/library/shape.rs @@ -94,7 +94,7 @@ pub struct ShapeNode { /// How to fill the shape, if at all. pub fill: Option<Paint>, /// The child node to place into the shape, if any. - pub child: Option<BlockNode>, + pub child: Option<PackedNode>, } /// The type of a shape. @@ -110,15 +110,36 @@ pub enum ShapeKind { Ellipse, } -impl InlineLevel for ShapeNode { - fn layout(&self, ctx: &mut LayoutContext, space: Length, base: Size) -> Frame { +impl Layout for ShapeNode { + fn layout( + &self, + ctx: &mut LayoutContext, + regions: &Regions, + ) -> Vec<Constrained<Rc<Frame>>> { // Resolve width and height relative to the region's base. - let width = self.width.map(|w| w.resolve(base.w)); - let height = self.height.map(|h| h.resolve(base.h)); + let width = self.width.map(|w| w.resolve(regions.base.w)); + let height = self.height.map(|h| h.resolve(regions.base.h)); + + // Generate constraints. + let mut cts = Constraints::new(regions.expand); + cts.set_base_if_linear(regions.base, Spec::new(self.width, self.height)); + + // Set tight exact and base constraints if the child is + // automatically sized since we don't know what the child might do. + if self.width.is_none() { + cts.exact.x = Some(regions.current.w); + cts.base.x = Some(regions.base.w); + } + + // Same here. + if self.height.is_none() { + cts.exact.y = Some(regions.current.h); + cts.base.y = Some(regions.base.h); + } // Layout. let mut frame = if let Some(child) = &self.child { - let mut node: &dyn BlockLevel = child; + let mut node: &dyn Layout = child; let padded; if matches!(self.shape, ShapeKind::Circle | ShapeKind::Ellipse) { @@ -133,11 +154,14 @@ impl InlineLevel for ShapeNode { // The "pod" is the region into which the child will be layouted. let mut pod = { - let size = Size::new(width.unwrap_or(space), height.unwrap_or(base.h)); + let size = Size::new( + width.unwrap_or(regions.current.w), + height.unwrap_or(regions.base.h), + ); let base = Size::new( - if width.is_some() { size.w } else { base.w }, - if height.is_some() { size.h } else { base.h }, + if width.is_some() { size.w } else { regions.base.w }, + if height.is_some() { size.h } else { regions.base.h }, ); let expand = Spec::new(width.is_some(), height.is_some()); @@ -180,6 +204,6 @@ impl InlineLevel for ShapeNode { frame.prepend(pos, Element::Geometry(geometry, fill)); } - frame + vec![frame.constrain(cts)] } } |
