use crate::*; impl> Layout for T {} pub trait Layout: Draw + Sized { fn full_w (self) -> impl Draw { Full::W(self) } fn full_h (self) -> impl Draw { Full::H(self) } fn full_wh (self) -> impl Draw { Full::WH(self) } fn origin (self, azimuth: impl Into>) -> impl Draw { Origin(azimuth.into(), self) } fn origin_c (self) -> impl Draw { Origin(Some(Azimuth::C), self) } fn origin_x (self) -> impl Draw { Origin(Some(Azimuth::X), self) } fn origin_y (self) -> impl Draw { Origin(Some(Azimuth::Y), self) } fn origin_n (self) -> impl Draw { Origin(Some(Azimuth::N), self) } fn origin_s (self) -> impl Draw { Origin(Some(Azimuth::S), self) } fn origin_e (self) -> impl Draw { Origin(Some(Azimuth::E), self) } fn origin_w (self) -> impl Draw { Origin(Some(Azimuth::W), self) } fn origin_ne (self) -> impl Draw { Origin(Some(Azimuth::NE), self) } fn origin_se (self) -> impl Draw { Origin(Some(Azimuth::SE), self) } fn origin_nw (self) -> impl Draw { Origin(Some(Azimuth::NW), self) } fn origin_sw (self) -> impl Draw { Origin(Some(Azimuth::SW), self) } } /// Uses [AtomicUsize] to measure size during\ /// rendering (which is normally read-only). #[derive(Default, Debug, Clone)] pub struct Sizer( /// Width pub Arc, /// Height pub Arc, ); impl Xy for Sizer { fn x (&self) -> u16 { self.0.load(Relaxed) as u16 } fn y (&self) -> u16 { self.1.load(Relaxed) as u16 } } impl Wide for Sizer { fn w (&self) -> u16 { self.0.load(Relaxed) as u16 } } impl Tall for Sizer { fn h (&self) -> u16 { self.1.load(Relaxed) as u16 } } impl PartialEq for Sizer { fn eq (&self, _: &Self) -> bool { todo!() } } impl Sizer { pub const fn of (&self, of: impl Draw) -> impl Draw { draw(move|to: &mut T|{ let area = of.draw(to)?; self.0.store(area.map(|a|a.w()).unwrap_or(T::Unit::zero()).into(), Relaxed); self.1.store(area.map(|a|a.h()).unwrap_or(T::Unit::zero()).into(), Relaxed); Ok(area) }) } } macro_rules! def_layout_modifier { ( $Trait:ident ($fn_x:ident $fn_y:ident $fn_xy:ident), $Struct:ident { $X:ident $Y:ident $XY:ident } $kw_name:ident $name:literal |$self:ident, $to:ident| $body:block ) => { impl> $Trait for T {} pub trait $Trait: Draw + Sized { fn $fn_x > + Copy> (self, x: N) -> $Struct { $Struct::$X(self, x) } fn $fn_y > + Copy> (self, y: N) -> $Struct { $Struct::$Y(self, y) } fn $fn_xy > + Copy> (self, x: N, y: N) -> $Struct { $Struct::$XY(self, x, y) } } pub enum $Struct, X: Into>> { __(PhantomData), $X(I, X), $Y(I, X), $XY(I, X, X), } impl , X: Into> + Copy> Draw for $Struct { fn draw (&$self, $to: &mut S) -> Perhaps> { $body } } fn_kw_layout!($kw_name |state, output, expr| { let head = expr.head()?; let mut frags = head.src()?.unwrap_or_default().split("/"); Ok(matches!(expr.head()?, Some("exact")).then(||{ let args = expr.tail(); let arg0 = args.head(); let tail0 = args.tail(); let arg1 = tail0.head(); let tail1 = tail0.tail(); let arg2 = tail1.head(); eval_xy!( $name => expr, head, output, state, frags.next(), $fn_xy, $fn_x, $fn_y, arg0, arg1, arg2, ) }).transpose()?.flatten()) }); } } mod area; pub use self::area::*; mod axis; pub use self::axis::*; mod azimuth; pub use self::azimuth::*; mod cond; pub use self::cond::*; mod iter; pub use self::iter::*;