diff options
Diffstat (limited to 'src/layout/shape.rs')
| -rw-r--r-- | src/layout/shape.rs | 64 |
1 files changed, 18 insertions, 46 deletions
diff --git a/src/layout/shape.rs b/src/layout/shape.rs index 3469f660..13d5418f 100644 --- a/src/layout/shape.rs +++ b/src/layout/shape.rs @@ -1,6 +1,7 @@ use std::f64::consts::SQRT_2; use super::*; +use crate::util::RcExt; /// Places its child into a sizable and fillable shape. #[derive(Debug)] @@ -15,7 +16,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<LayoutNode>, + pub child: Option<BlockNode>, } /// The type of a shape. @@ -31,40 +32,15 @@ pub enum ShapeKind { Ellipse, } -impl Layout for ShapeNode { - fn layout( - &self, - ctx: &mut LayoutContext, - regions: &Regions, - ) -> Vec<Constrained<Rc<Frame>>> { +impl InlineLevel for ShapeNode { + fn layout(&self, ctx: &mut LayoutContext, space: Length, base: Size) -> Frame { // Resolve width and height relative to the region's base. - 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 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); - } - - cts - }; + let width = self.width.map(|w| w.resolve(base.w)); + let height = self.height.map(|h| h.resolve(base.h)); // Layout. - let mut frames = if let Some(child) = &self.child { - let mut node: &dyn Layout = child; + let mut frame = if let Some(child) = &self.child { + let mut node: &dyn BlockLevel = child; let padded; if matches!(self.shape, ShapeKind::Circle | ShapeKind::Ellipse) { @@ -79,14 +55,12 @@ impl Layout for ShapeNode { // The "pod" is the region into which the child will be layouted. let mut pod = { - let size = Size::new( - width.unwrap_or(regions.current.w), - height.unwrap_or(regions.current.h), - ); + let size = + Size::new(width.unwrap_or(space), height.unwrap_or(Length::inf())); let base = Size::new( - if width.is_some() { size.w } else { regions.base.w }, - if height.is_some() { size.h } else { regions.base.h }, + if width.is_some() { size.w } else { base.w }, + if height.is_some() { size.h } else { base.h }, ); let expand = Spec::new(width.is_some(), height.is_some()); @@ -108,17 +82,15 @@ impl Layout for ShapeNode { // Validate and set constraints. assert_eq!(frames.len(), 1); - frames[0].constraints = constraints; - frames + Rc::take(frames.into_iter().next().unwrap().item) } else { // Resolve shape size. let size = Size::new(width.unwrap_or_default(), height.unwrap_or_default()); - vec![Frame::new(size, size.h).constrain(constraints)] + Frame::new(size, size.h) }; // Add background shape if desired. if let Some(fill) = self.fill { - let frame = Rc::make_mut(&mut frames[0].item); let (pos, geometry) = match self.shape { ShapeKind::Square | ShapeKind::Rect => { (Point::zero(), Geometry::Rect(frame.size)) @@ -131,12 +103,12 @@ impl Layout for ShapeNode { frame.prepend(pos, Element::Geometry(geometry, fill)); } - frames + frame } } -impl From<ShapeNode> for LayoutNode { - fn from(shape: ShapeNode) -> Self { - Self::new(shape) +impl From<ShapeNode> for InlineNode { + fn from(node: ShapeNode) -> Self { + Self::new(node) } } |
