1use crate::{
2 geometry::{rect::RectF, vector::Vector2F},
3 json, DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
4 SizeConstraint,
5};
6use json::ToJson;
7
8use serde_json::json;
9
10pub struct Align {
11 child: ElementBox,
12 alignment: Vector2F,
13}
14
15impl Align {
16 pub fn new(child: ElementBox) -> Self {
17 Self {
18 child,
19 alignment: Vector2F::zero(),
20 }
21 }
22
23 pub fn top(mut self) -> Self {
24 self.alignment.set_y(-1.0);
25 self
26 }
27
28 pub fn right(mut self) -> Self {
29 self.alignment.set_x(1.0);
30 self
31 }
32}
33
34impl Element for Align {
35 type LayoutState = ();
36 type PaintState = ();
37
38 fn layout(
39 &mut self,
40 mut constraint: SizeConstraint,
41 cx: &mut LayoutContext,
42 ) -> (Vector2F, Self::LayoutState) {
43 let mut size = constraint.max;
44 constraint.min = Vector2F::zero();
45 let child_size = self.child.layout(constraint, cx);
46 if size.x().is_infinite() {
47 size.set_x(child_size.x());
48 }
49 if size.y().is_infinite() {
50 size.set_y(child_size.y());
51 }
52 (size, ())
53 }
54
55 fn paint(
56 &mut self,
57 bounds: RectF,
58 visible_bounds: RectF,
59 _: &mut Self::LayoutState,
60 cx: &mut PaintContext,
61 ) -> Self::PaintState {
62 let my_center = bounds.size() / 2.;
63 let my_target = my_center + my_center * self.alignment;
64
65 let child_center = self.child.size() / 2.;
66 let child_target = child_center + child_center * self.alignment;
67
68 self.child.paint(
69 bounds.origin() - (child_target - my_target),
70 visible_bounds,
71 cx,
72 );
73 }
74
75 fn dispatch_event(
76 &mut self,
77 event: &Event,
78 _: pathfinder_geometry::rect::RectF,
79 _: &mut Self::LayoutState,
80 _: &mut Self::PaintState,
81 cx: &mut EventContext,
82 ) -> bool {
83 self.child.dispatch_event(event, cx)
84 }
85
86 fn debug(
87 &self,
88 bounds: pathfinder_geometry::rect::RectF,
89 _: &Self::LayoutState,
90 _: &Self::PaintState,
91 cx: &DebugContext,
92 ) -> json::Value {
93 json!({
94 "type": "Align",
95 "bounds": bounds.to_json(),
96 "alignment": self.alignment.to_json(),
97 "child": self.child.debug(cx),
98 })
99 }
100}