align.rs

  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}