1use crate::{
2 AfterLayoutContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
3 SizeConstraint,
4};
5use pathfinder_geometry::vector::{vec2f, Vector2F};
6
7pub struct Align {
8 child: ElementBox,
9 alignment: Vector2F,
10}
11
12impl Align {
13 pub fn new(child: ElementBox) -> Self {
14 Self {
15 child,
16 alignment: Vector2F::zero(),
17 }
18 }
19
20 pub fn top_center(mut self) -> Self {
21 self.alignment = vec2f(0.0, -1.0);
22 self
23 }
24}
25
26impl Element for Align {
27 type LayoutState = ();
28 type PaintState = ();
29
30 fn layout(
31 &mut self,
32 mut constraint: SizeConstraint,
33 ctx: &mut LayoutContext,
34 ) -> (Vector2F, Self::LayoutState) {
35 let mut size = constraint.max;
36 constraint.min = Vector2F::zero();
37 let child_size = self.child.layout(constraint, ctx);
38 if size.x().is_infinite() {
39 size.set_x(child_size.x());
40 }
41 if size.y().is_infinite() {
42 size.set_y(child_size.y());
43 }
44 (size, ())
45 }
46
47 fn after_layout(
48 &mut self,
49 _: Vector2F,
50 _: &mut Self::LayoutState,
51 ctx: &mut AfterLayoutContext,
52 ) {
53 self.child.after_layout(ctx);
54 }
55
56 fn paint(
57 &mut self,
58 bounds: pathfinder_geometry::rect::RectF,
59 _: &mut Self::LayoutState,
60 ctx: &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
69 .paint(bounds.origin() - (child_target - my_target), ctx);
70 }
71
72 fn dispatch_event(
73 &mut self,
74 event: &Event,
75 _: pathfinder_geometry::rect::RectF,
76 _: &mut Self::LayoutState,
77 _: &mut Self::PaintState,
78 ctx: &mut EventContext,
79 ) -> bool {
80 self.child.dispatch_event(event, ctx)
81 }
82}