summaryrefslogtreecommitdiff
path: root/src/layout/rect.rs
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2021-02-04 21:30:18 +0100
committerMartin Haug <mhaug@live.de>2021-02-04 21:30:18 +0100
commit8469bad7487e111c8e5a0ec542f0232a0ebb4bdc (patch)
tree6d2781a8c6e95a10de048d39f5bd6ebaa82bc6ea /src/layout/rect.rs
parentdacd7dadc04d4538f1063a86afd676695c7471ab (diff)
Add rectangle function 🎛
Diffstat (limited to 'src/layout/rect.rs')
-rw-r--r--src/layout/rect.rs71
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)
+ }
+}