use crate::{ geometry::{rect::RectF, vector::Vector2F}, json, AnyElement, Element, LayoutContext, SceneBuilder, SizeConstraint, View, ViewContext, }; use json::ToJson; use serde_json::json; pub struct Align { child: AnyElement, alignment: Vector2F, } impl Align { pub fn new(child: AnyElement) -> Self { Self { child, alignment: Vector2F::zero(), } } pub fn top(mut self) -> Self { self.alignment.set_y(-1.0); self } pub fn bottom(mut self) -> Self { self.alignment.set_y(1.0); self } pub fn left(mut self) -> Self { self.alignment.set_x(-1.0); self } pub fn right(mut self) -> Self { self.alignment.set_x(1.0); self } } impl Element for Align { type LayoutState = (); type PaintState = (); fn layout( &mut self, mut constraint: SizeConstraint, view: &mut V, cx: &mut LayoutContext, ) -> (Vector2F, Self::LayoutState) { let mut size = constraint.max; constraint.min = Vector2F::zero(); let child_size = self.child.layout(constraint, view, cx); if size.x().is_infinite() { size.set_x(child_size.x()); } if size.y().is_infinite() { size.set_y(child_size.y()); } (size, ()) } fn paint( &mut self, scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut ViewContext, ) -> Self::PaintState { let my_center = bounds.size() / 2.; let my_target = my_center + my_center * self.alignment; let child_center = self.child.size() / 2.; let child_target = child_center + child_center * self.alignment; self.child.paint( scene, bounds.origin() - (child_target - my_target), visible_bounds, view, cx, ); } fn rect_for_text_range( &self, range_utf16: std::ops::Range, _: RectF, _: RectF, _: &Self::LayoutState, _: &Self::PaintState, view: &V, cx: &ViewContext, ) -> Option { self.child.rect_for_text_range(range_utf16, view, cx) } fn debug( &self, bounds: pathfinder_geometry::rect::RectF, _: &Self::LayoutState, _: &Self::PaintState, view: &V, cx: &ViewContext, ) -> json::Value { json!({ "type": "Align", "bounds": bounds.to_json(), "alignment": self.alignment.to_json(), "child": self.child.debug(view, cx), }) } }