1use crate::{
2 json, AfterLayoutContext, DebugContext, Element, ElementBox, Event, EventContext,
3 LayoutContext, PaintContext, 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 after_layout(
55 &mut self,
56 _: Vector2F,
57 _: &mut Self::LayoutState,
58 cx: &mut AfterLayoutContext,
59 ) {
60 self.child.after_layout(cx);
61 }
62
63 fn paint(
64 &mut self,
65 bounds: pathfinder_geometry::rect::RectF,
66 _: &mut Self::LayoutState,
67 cx: &mut PaintContext,
68 ) -> Self::PaintState {
69 let my_center = bounds.size() / 2.;
70 let my_target = my_center + my_center * self.alignment;
71
72 let child_center = self.child.size() / 2.;
73 let child_target = child_center + child_center * self.alignment;
74
75 self.child
76 .paint(bounds.origin() - (child_target - my_target), cx);
77 }
78
79 fn dispatch_event(
80 &mut self,
81 event: &Event,
82 _: pathfinder_geometry::rect::RectF,
83 _: &mut Self::LayoutState,
84 _: &mut Self::PaintState,
85 cx: &mut EventContext,
86 ) -> bool {
87 self.child.dispatch_event(event, cx)
88 }
89
90 fn debug(
91 &self,
92 bounds: pathfinder_geometry::rect::RectF,
93 _: &Self::LayoutState,
94 _: &Self::PaintState,
95 cx: &DebugContext,
96 ) -> json::Value {
97 json!({
98 "type": "Align",
99 "bounds": bounds.to_json(),
100 "alignment": self.alignment.to_json(),
101 "child": self.child.debug(cx),
102 })
103 }
104}