align.rs

 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}