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