diff options
| author | Martin Haug <mhaug@live.de> | 2021-02-04 21:30:18 +0100 |
|---|---|---|
| committer | Martin Haug <mhaug@live.de> | 2021-02-04 21:30:18 +0100 |
| commit | 8469bad7487e111c8e5a0ec542f0232a0ebb4bdc (patch) | |
| tree | 6d2781a8c6e95a10de048d39f5bd6ebaa82bc6ea /src/layout/rect.rs | |
| parent | dacd7dadc04d4538f1063a86afd676695c7471ab (diff) | |
Add rectangle function 🎛
Diffstat (limited to 'src/layout/rect.rs')
| -rw-r--r-- | src/layout/rect.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/layout/rect.rs b/src/layout/rect.rs new file mode 100644 index 00000000..ab8e3b07 --- /dev/null +++ b/src/layout/rect.rs @@ -0,0 +1,71 @@ +use std::cmp::Ordering; + +use super::*; +use crate::{color::RgbaColor, geom::Linear}; + +/// A node that represents a rectangular box. +#[derive(Debug, Clone, PartialEq)] +pub struct NodeRect { + /// The fixed width, if any. + pub width: Option<Linear>, + /// The fixed height, if any. + pub height: Option<Linear>, + /// The background color. + pub color: Option<Color>, + /// The child node whose sides to pad. + pub child: Node, +} + +impl Layout for NodeRect { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted { + let Areas { current, full, .. } = areas; + + let height_opt = self.height.map(|h| h.resolve(full.height)); + let mut size = Size::new( + self.width.map(|w| w.resolve(full.width)).unwrap_or(current.width), + height_opt.unwrap_or(current.height), + ); + + let areas = Areas::once(size); + let mut layouted = self.child.layout(ctx, &areas); + + // If the children have some height, apply that, + // otherwise fall back to zero or the height property. + if let Some(max) = layouted + .frames() + .iter() + .map(|f| f.size.height) + .max_by(|x, y| x.partial_cmp(y).unwrap_or(Ordering::Equal)) + { + size.height = max; + } else { + size.height = height_opt.unwrap_or(Length::ZERO) + } + + if let Some(first) = layouted.frames_mut().first_mut() { + first.elements.insert( + 0, + ( + Point::ZERO, + Element::Geometry(Geometry { + shape: Shape::Rect(Rect { size }), + fill: Fill::Color(self.color.unwrap_or(Color::Rgba(RgbaColor { + r: 255, + g: 255, + b: 255, + a: 0, + }))), + }), + ), + ) + } + + layouted + } +} + +impl From<NodeRect> for NodeAny { + fn from(pad: NodeRect) -> Self { + Self::new(pad) + } +} |
