1use json::ToJson;
2use serde_json::json;
3
4use crate::{
5 geometry::{rect::RectF, vector::Vector2F},
6 json, AfterLayoutContext, DebugContext, Element, ElementBox, Event, EventContext,
7 LayoutContext, PaintContext, SizeConstraint,
8};
9
10pub struct ConstrainedBox {
11 child: ElementBox,
12 constraint: SizeConstraint,
13}
14
15impl ConstrainedBox {
16 pub fn new(child: ElementBox) -> Self {
17 Self {
18 child,
19 constraint: SizeConstraint {
20 min: Vector2F::zero(),
21 max: Vector2F::splat(f32::INFINITY),
22 },
23 }
24 }
25
26 pub fn with_min_width(mut self, min_width: f32) -> Self {
27 self.constraint.min.set_x(min_width);
28 self
29 }
30
31 pub fn with_max_width(mut self, max_width: f32) -> Self {
32 self.constraint.max.set_x(max_width);
33 self
34 }
35
36 pub fn with_max_height(mut self, max_height: f32) -> Self {
37 self.constraint.max.set_y(max_height);
38 self
39 }
40
41 pub fn with_width(mut self, width: f32) -> Self {
42 self.constraint.min.set_x(width);
43 self.constraint.max.set_x(width);
44 self
45 }
46
47 pub fn with_height(mut self, height: f32) -> Self {
48 self.constraint.min.set_y(height);
49 self.constraint.max.set_y(height);
50 self
51 }
52}
53
54impl Element for ConstrainedBox {
55 type LayoutState = ();
56 type PaintState = ();
57
58 fn layout(
59 &mut self,
60 mut constraint: SizeConstraint,
61 cx: &mut LayoutContext,
62 ) -> (Vector2F, Self::LayoutState) {
63 constraint.min = constraint.min.max(self.constraint.min);
64 constraint.max = constraint.max.min(self.constraint.max);
65 constraint.max = constraint.max.max(constraint.min);
66 let size = self.child.layout(constraint, cx);
67 (size, ())
68 }
69
70 fn after_layout(
71 &mut self,
72 _: Vector2F,
73 _: &mut Self::LayoutState,
74 cx: &mut AfterLayoutContext,
75 ) {
76 self.child.after_layout(cx);
77 }
78
79 fn paint(
80 &mut self,
81 bounds: RectF,
82 _: &mut Self::LayoutState,
83 cx: &mut PaintContext,
84 ) -> Self::PaintState {
85 self.child.paint(bounds.origin(), cx);
86 }
87
88 fn dispatch_event(
89 &mut self,
90 event: &Event,
91 _: RectF,
92 _: &mut Self::LayoutState,
93 _: &mut Self::PaintState,
94 cx: &mut EventContext,
95 ) -> bool {
96 self.child.dispatch_event(event, cx)
97 }
98
99 fn debug(
100 &self,
101 _: RectF,
102 _: &Self::LayoutState,
103 _: &Self::PaintState,
104 cx: &DebugContext,
105 ) -> json::Value {
106 json!({"type": "ConstrainedBox", "set_constraint": self.constraint.to_json(), "child": self.child.debug(cx)})
107 }
108}