align.rs

  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 left(mut self) -> Self {
 29        self.alignment.set_x(-1.0);
 30        self
 31    }
 32
 33    pub fn right(mut self) -> Self {
 34        self.alignment.set_x(1.0);
 35        self
 36    }
 37}
 38
 39impl Element for Align {
 40    type LayoutState = ();
 41    type PaintState = ();
 42
 43    fn layout(
 44        &mut self,
 45        mut constraint: SizeConstraint,
 46        cx: &mut LayoutContext,
 47    ) -> (Vector2F, Self::LayoutState) {
 48        let mut size = constraint.max;
 49        constraint.min = Vector2F::zero();
 50        let child_size = self.child.layout(constraint, cx);
 51        if size.x().is_infinite() {
 52            size.set_x(child_size.x());
 53        }
 54        if size.y().is_infinite() {
 55            size.set_y(child_size.y());
 56        }
 57        (size, ())
 58    }
 59
 60    fn paint(
 61        &mut self,
 62        bounds: RectF,
 63        visible_bounds: RectF,
 64        _: &mut Self::LayoutState,
 65        cx: &mut PaintContext,
 66    ) -> Self::PaintState {
 67        let my_center = bounds.size() / 2.;
 68        let my_target = my_center + my_center * self.alignment;
 69
 70        let child_center = self.child.size() / 2.;
 71        let child_target = child_center + child_center * self.alignment;
 72
 73        self.child.paint(
 74            bounds.origin() - (child_target - my_target),
 75            visible_bounds,
 76            cx,
 77        );
 78    }
 79
 80    fn dispatch_event(
 81        &mut self,
 82        event: &Event,
 83        _: pathfinder_geometry::rect::RectF,
 84        _: &mut Self::LayoutState,
 85        _: &mut Self::PaintState,
 86        cx: &mut EventContext,
 87    ) -> bool {
 88        self.child.dispatch_event(event, cx)
 89    }
 90
 91    fn debug(
 92        &self,
 93        bounds: pathfinder_geometry::rect::RectF,
 94        _: &Self::LayoutState,
 95        _: &Self::PaintState,
 96        cx: &DebugContext,
 97    ) -> json::Value {
 98        json!({
 99            "type": "Align",
100            "bounds": bounds.to_json(),
101            "alignment": self.alignment.to_json(),
102            "child": self.child.debug(cx),
103        })
104    }
105}