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