From 07a1206c2f9d0905ccae163931506afce9560e7e Mon Sep 17 00:00:00 2001 From: same mf who else Date: Sun, 15 Feb 2026 05:18:55 +0200 Subject: [PATCH] refactor: remove Out::{Area, Size}. 7 errors left... --- output/src/lib.rs | 6 +- output/src/out_impls.rs | 392 +++++++++++++++++++++----------------- output/src/out_structs.rs | 23 ++- output/src/out_traits.rs | 47 ++--- 4 files changed, 253 insertions(+), 215 deletions(-) diff --git a/output/src/lib.rs b/output/src/lib.rs index 65c7580..6f6bc7a 100644 --- a/output/src/lib.rs +++ b/output/src/lib.rs @@ -16,7 +16,7 @@ pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicUsize, Ordering::Relaxed} pub(crate) use std::marker::PhantomData; pub(crate) use dizzle::*; -// Define macros first, so that private macros are available in private modules. +// Define macros first, so that private macros are available in private modules: /// Clear a pre-allocated buffer, then write into it. #[macro_export] macro_rules! rewrite { @@ -117,8 +117,8 @@ macro_rules! layout_op_xy ( macro_rules! push_pull(($T:ident: $method: ident)=>{ layout_op_xy!(1: $T); impl> Layout for $T { - fn x (&self, area: O::Area) -> O::Unit { area.x().$method(self.dx()) } - fn y (&self, area: O::Area) -> O::Unit { area.y().$method(self.dy()) } + fn x (&self, area: XYWH) -> O::Unit { area.x().$method(self.dx()) } + fn y (&self, area: XYWH) -> O::Unit { area.y().$method(self.dy()) } } }); diff --git a/output/src/out_impls.rs b/output/src/out_impls.rs index 99dfdc6..755d152 100644 --- a/output/src/out_impls.rs +++ b/output/src/out_impls.rs @@ -49,37 +49,62 @@ impl WH { } } impl XYWH { - fn with_w (&self, w: N) -> XYWH { Self(self.x(), self.y(), w, self.h()) } - fn with_h (&self, h: N) -> XYWH { Self(self.x(), self.y(), self.w(), h) } - fn lrtb (&self) -> XYWH { Self(self.x(), self.x2(), self.y(), self.y2()) } - fn clipped_w (&self, w: N) -> XYWH { Self(self.x(), self.y(), self.w().min(w), self.h()) } - fn clipped_h (&self, h: N) -> XYWH { Self(self.x(), self.y(), self.w(), self.h().min(h)) } - fn clipped (&self, wh: impl HasWH) -> XYWH { Self(self.x(), self.y(), wh.w(), wh.h()) } + fn zero (&self) -> Self { + Self(0.into(), 0.into(), 0.into(), 0.into()) + } + fn x2 (&self) -> N { + self.x().plus(self.w()) + } + fn y2 (&self) -> N { + self.y().plus(self.h()) + } + fn with_w (&self, w: N) -> XYWH { + Self(self.x(), self.y(), w, self.h()) + } + fn with_h (&self, h: N) -> XYWH { + Self(self.x(), self.y(), self.w(), h) + } + fn lrtb (&self) -> XYWH { + Self(self.x(), self.x2(), self.y(), self.y2()) + } + fn clipped_w (&self, w: N) -> XYWH { + Self(self.x(), self.y(), self.w().min(w), self.h()) + } + fn clipped_h (&self, h: N) -> XYWH { + Self(self.x(), self.y(), self.w(), self.h().min(h)) + } + fn clipped (&self, wh: WH) -> XYWH { + Self(self.x(), self.y(), wh.w(), wh.h()) + } /// Iterate over every covered X coordinate. fn iter_x (&self) -> impl Iterator where N: std::iter::Step { - self.x()..(self.x()+self.w()) + let Self(x, _, w, _) = *self; + x..(x+w) } /// Iterate over every covered Y coordinate. fn iter_y (&self) -> impl Iterator where N: std::iter::Step { - self.y()..(self.y()+self.h()) + let Self(_, y, _, h) = *self; + y..(y+h) } fn center (&self) -> XY { + let Self(x, y, w, h) = self; XY(self.x().plus(self.w()/2.into()), self.y().plus(self.h()/2.into())) } fn centered (&self) -> XY { - XY(self.x().minus(self.w()/2.into()), self.y().minus(self.h()/2.into())) + let Self(x, y, w, h) = *self; + XY(x.minus(w/2.into()), y.minus(h/2.into())) } fn centered_x (&self, n: N) -> XYWH { - let [x, y, w, h] = self.xywh(); - Self((x.plus(w / 2.into())).minus(n / 2.into()), y.plus(h / 2.into()), n, 1.into()) + let Self(x, y, w, h) = *self; + XYWH((x.plus(w / 2.into())).minus(n / 2.into()), y.plus(h / 2.into()), n, 1.into()) } fn centered_y (&self, n: N) -> XYWH { - let [x, y, w, h] = self.xywh(); - Self(x.plus(w / 2.into()), (y.plus(h / 2.into())).minus(n / 2.into()), 1.into(), n) + let Self(x, y, w, h) = *self; + XYWH(x.plus(w / 2.into()), (y.plus(h / 2.into())).minus(n / 2.into()), 1.into(), n) } fn centered_xy (&self, [n, m]: [N;2]) -> XYWH { - let [x, y, w, h] = self.xywh(); - Self((x.plus(w / 2.into())).minus(n / 2.into()), (y.plus(h / 2.into())).minus(m / 2.into()), n, m) + let Self(x, y, w, h) = *self; + XYWH((x.plus(w / 2.into())).minus(n / 2.into()), (y.plus(h / 2.into())).minus(m / 2.into()), n, m) } } @@ -167,14 +192,14 @@ impl Memo { } impl Direction { - pub fn split_fixed (self, area: impl HasXYWH, a: N) -> ([N;4],[N;4]) { - let XYWH(x, y, w, h) = area.xywh(); + pub fn split_fixed (self, area: XYWH, a: N) -> (XYWH, XYWH) { + let XYWH(x, y, w, h) = area; match self { - North => ([x, y.plus(h).minus(a), w, a], [x, y, w, h.minus(a)]), - South => ([x, y, w, a], [x, y.plus(a), w, h.minus(a)]), - East => ([x, y, a, h], [x.plus(a), y, w.minus(a), h]), - West => ([x.plus(w).minus(a), y, a, h], [x, y, w.minus(a), h]), - Above | Below => (area.xywh(), area.xywh()) + North => (XYWH(x, y.plus(h).minus(a), w, a), XYWH(x, y, w, h.minus(a))), + South => (XYWH(x, y, w, a), XYWH(x, y.plus(a), w, h.minus(a))), + East => (XYWH(x, y, a, h), XYWH(x.plus(a), y, w.minus(a), h)), + West => (XYWH(x.plus(w).minus(a), y, a, h), XYWH(x, y, w.minus(a), h)), + Above | Below => (area, area) } } } @@ -221,7 +246,7 @@ impl Measure { pub fn format (&self) -> Arc { format!("{}x{}", self.w(), self.h()).into() } pub fn of > (&self, item: T) -> Bsp, T> { Bsp::b(Fill::XY(self), item) } pub fn new (x: O::Unit, y: O::Unit) -> Self { - Self { __: PhantomData::default(), x: Arc::new(x.into()), y: Arc::new(y.into()), } + Self { __: PhantomData::default(), x: Arc::new(x.atomic()), y: Arc::new(y.atomic()), } } } @@ -230,88 +255,91 @@ impl From<[O::Unit; 2]> for Measure { } impl Layout for () { - fn x (&self, a: O::Area) -> O::Unit { a.x() } - fn y (&self, a: O::Area) -> O::Unit { a.y() } - fn w (&self, _: O::Area) -> O::Unit { 0.into() } - fn w_min (&self, _: O::Area) -> O::Unit { 0.into() } - fn w_max (&self, _: O::Area) -> O::Unit { 0.into() } - fn h (&self, _: O::Area) -> O::Unit { 0.into() } - fn h_min (&self, _: O::Area) -> O::Unit { 0.into() } - fn h_max (&self, _: O::Area) -> O::Unit { 0.into() } - fn layout (&self, a: O::Area) -> O::Area { [a.x(), a.y(), 0.into(), 0.into()].into() } + fn x (&self, a: XYWH) -> O::Unit { a.x() } + fn y (&self, a: XYWH) -> O::Unit { a.y() } + fn w (&self, _: XYWH) -> O::Unit { 0.into() } + fn w_min (&self, _: XYWH) -> O::Unit { 0.into() } + fn w_max (&self, _: XYWH) -> O::Unit { 0.into() } + fn h (&self, _: XYWH) -> O::Unit { 0.into() } + fn h_min (&self, _: XYWH) -> O::Unit { 0.into() } + fn h_max (&self, _: XYWH) -> O::Unit { 0.into() } + fn layout (&self, a: XYWH) -> XYWH { XYWH(a.x(), a.y(), 0.into(), 0.into()) } } impl> Layout for &L { - fn x (&self, a: O::Area) -> O::Unit { (*self).x(a) } - fn y (&self, a: O::Area) -> O::Unit { (*self).y(a) } - fn w (&self, a: O::Area) -> O::Unit { (*self).w(a) } - fn w_min (&self, a: O::Area) -> O::Unit { (*self).w_min(a) } - fn w_max (&self, a: O::Area) -> O::Unit { (*self).w_max(a) } - fn h (&self, a: O::Area) -> O::Unit { (*self).h(a) } - fn h_min (&self, a: O::Area) -> O::Unit { (*self).h_min(a) } - fn h_max (&self, a: O::Area) -> O::Unit { (*self).h_max(a) } - fn layout (&self, a: O::Area) -> O::Area { (*self).layout(a) } + fn x (&self, a: XYWH) -> O::Unit { (*self).x(a) } + fn y (&self, a: XYWH) -> O::Unit { (*self).y(a) } + fn w (&self, a: XYWH) -> O::Unit { (*self).w(a) } + fn w_min (&self, a: XYWH) -> O::Unit { (*self).w_min(a) } + fn w_max (&self, a: XYWH) -> O::Unit { (*self).w_max(a) } + fn h (&self, a: XYWH) -> O::Unit { (*self).h(a) } + fn h_min (&self, a: XYWH) -> O::Unit { (*self).h_min(a) } + fn h_max (&self, a: XYWH) -> O::Unit { (*self).h_max(a) } + fn layout (&self, a: XYWH) -> XYWH { (*self).layout(a) } } impl> Layout for &mut L { - fn x (&self, a: O::Area) -> O::Unit { (**self).x(a) } - fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) } - fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) } - fn w_min (&self, a: O::Area) -> O::Unit { (**self).w_min(a) } - fn w_max (&self, a: O::Area) -> O::Unit { (**self).w_max(a) } - fn h (&self, a: O::Area) -> O::Unit { (**self).h(a) } - fn h_min (&self, a: O::Area) -> O::Unit { (**self).h_min(a) } - fn h_max (&self, a: O::Area) -> O::Unit { (**self).h_max(a) } - fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) } + fn x (&self, a: XYWH) -> O::Unit { (**self).x(a) } + fn y (&self, a: XYWH) -> O::Unit { (**self).y(a) } + fn w (&self, a: XYWH) -> O::Unit { (**self).w(a) } + fn w_min (&self, a: XYWH) -> O::Unit { (**self).w_min(a) } + fn w_max (&self, a: XYWH) -> O::Unit { (**self).w_max(a) } + fn h (&self, a: XYWH) -> O::Unit { (**self).h(a) } + fn h_min (&self, a: XYWH) -> O::Unit { (**self).h_min(a) } + fn h_max (&self, a: XYWH) -> O::Unit { (**self).h_max(a) } + fn layout (&self, a: XYWH) -> XYWH { (**self).layout(a) } } impl> Layout for Arc { - fn x (&self, a: O::Area) -> O::Unit { (**self).x(a) } - fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) } - fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) } - fn w_min (&self, a: O::Area) -> O::Unit { (**self).w_min(a) } - fn w_max (&self, a: O::Area) -> O::Unit { (**self).w_max(a) } - fn h (&self, a: O::Area) -> O::Unit { (**self).h(a) } - fn h_min (&self, a: O::Area) -> O::Unit { (**self).h_min(a) } - fn h_max (&self, a: O::Area) -> O::Unit { (**self).h_max(a) } - fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) } + fn x (&self, a: XYWH) -> O::Unit { (**self).x(a) } + fn y (&self, a: XYWH) -> O::Unit { (**self).y(a) } + fn w (&self, a: XYWH) -> O::Unit { (**self).w(a) } + fn w_min (&self, a: XYWH) -> O::Unit { (**self).w_min(a) } + fn w_max (&self, a: XYWH) -> O::Unit { (**self).w_max(a) } + fn h (&self, a: XYWH) -> O::Unit { (**self).h(a) } + fn h_min (&self, a: XYWH) -> O::Unit { (**self).h_min(a) } + fn h_max (&self, a: XYWH) -> O::Unit { (**self).h_max(a) } + fn layout (&self, a: XYWH) -> XYWH { (**self).layout(a) } } impl Layout for Box> { - fn x (&self, a: O::Area) -> O::Unit { (**self).x(a) } - fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) } - fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) } - fn w_min (&self, a: O::Area) -> O::Unit { (**self).w_min(a) } - fn w_max (&self, a: O::Area) -> O::Unit { (**self).w_max(a) } - fn h (&self, a: O::Area) -> O::Unit { (**self).h(a) } - fn h_min (&self, a: O::Area) -> O::Unit { (**self).h_min(a) } - fn h_max (&self, a: O::Area) -> O::Unit { (**self).h_max(a) } - fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) } + fn x (&self, a: XYWH) -> O::Unit { (**self).x(a) } + fn y (&self, a: XYWH) -> O::Unit { (**self).y(a) } + fn w (&self, a: XYWH) -> O::Unit { (**self).w(a) } + fn w_min (&self, a: XYWH) -> O::Unit { (**self).w_min(a) } + fn w_max (&self, a: XYWH) -> O::Unit { (**self).w_max(a) } + fn h (&self, a: XYWH) -> O::Unit { (**self).h(a) } + fn h_min (&self, a: XYWH) -> O::Unit { (**self).h_min(a) } + fn h_max (&self, a: XYWH) -> O::Unit { (**self).h_max(a) } + fn layout (&self, a: XYWH) -> XYWH { (**self).layout(a) } } impl> Layout for RwLock { - fn x (&self, a: O::Area) -> O::Unit { self.read().unwrap().x(a) } - fn y (&self, a: O::Area) -> O::Unit { self.read().unwrap().y(a) } - fn w (&self, a: O::Area) -> O::Unit { self.read().unwrap().w(a) } - fn w_min (&self, a: O::Area) -> O::Unit { self.read().unwrap().w_min(a) } - fn w_max (&self, a: O::Area) -> O::Unit { self.read().unwrap().w_max(a) } - fn h (&self, a: O::Area) -> O::Unit { self.read().unwrap().h(a) } - fn h_min (&self, a: O::Area) -> O::Unit { self.read().unwrap().h_min(a) } - fn h_max (&self, a: O::Area) -> O::Unit { self.read().unwrap().h_max(a) } - fn layout (&self, a: O::Area) -> O::Area { self.read().unwrap().layout(a) } + fn x (&self, a: XYWH) -> O::Unit { self.read().unwrap().x(a) } + fn y (&self, a: XYWH) -> O::Unit { self.read().unwrap().y(a) } + fn w (&self, a: XYWH) -> O::Unit { self.read().unwrap().w(a) } + fn w_min (&self, a: XYWH) -> O::Unit { self.read().unwrap().w_min(a) } + fn w_max (&self, a: XYWH) -> O::Unit { self.read().unwrap().w_max(a) } + fn h (&self, a: XYWH) -> O::Unit { self.read().unwrap().h(a) } + fn h_min (&self, a: XYWH) -> O::Unit { self.read().unwrap().h_min(a) } + fn h_max (&self, a: XYWH) -> O::Unit { self.read().unwrap().h_max(a) } + fn layout (&self, a: XYWH) -> XYWH { self.read().unwrap().layout(a) } } impl> Layout for Option { - fn x (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.x(to)).unwrap_or(to.x()) } - fn y (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.y(to)).unwrap_or(to.y()) } - fn w_min (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.w_min(to)).unwrap_or(0.into()) } - fn w_max (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.w_max(to)).unwrap_or(0.into()) } - fn w (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.w(to)).unwrap_or(0.into()) } - fn h_min (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.h_min(to)).unwrap_or(0.into()) } - fn h_max (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.h_max(to)).unwrap_or(0.into()) } - fn h (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.h(to)).unwrap_or(0.into()) } - fn layout (&self, to: O::Area) -> O::Area { self.as_ref().map(|c|c.layout([self.x(to), self.y(to), self.w(to), self.h(to)].into())) - .unwrap_or([to.x(), to.y(), 0.into(), 0.into()].into()) } + fn x (&self, to: XYWH) -> O::Unit { self.as_ref().map(|c|c.x(to)).unwrap_or(to.x()) } + fn y (&self, to: XYWH) -> O::Unit { self.as_ref().map(|c|c.y(to)).unwrap_or(to.y()) } + fn w_min (&self, to: XYWH) -> O::Unit { self.as_ref().map(|c|c.w_min(to)).unwrap_or(0.into()) } + fn w_max (&self, to: XYWH) -> O::Unit { self.as_ref().map(|c|c.w_max(to)).unwrap_or(0.into()) } + fn w (&self, to: XYWH) -> O::Unit { self.as_ref().map(|c|c.w(to)).unwrap_or(0.into()) } + fn h_min (&self, to: XYWH) -> O::Unit { self.as_ref().map(|c|c.h_min(to)).unwrap_or(0.into()) } + fn h_max (&self, to: XYWH) -> O::Unit { self.as_ref().map(|c|c.h_max(to)).unwrap_or(0.into()) } + fn h (&self, to: XYWH) -> O::Unit { self.as_ref().map(|c|c.h(to)).unwrap_or(0.into()) } + fn layout (&self, to: XYWH) -> XYWH { + self.as_ref() + .map(|c|c.layout(XYWH(self.x(to), self.y(to), self.w(to), self.h(to)).into())) + .unwrap_or(XYWH(to.x(), to.y(), 0.into(), 0.into())) + } } impl> HasContent for Bounded { @@ -335,9 +363,9 @@ impl> When { } impl> Layout for When { - fn layout (&self, to: O::Area) -> O::Area { + fn layout (&self, to: XYWH) -> XYWH { let Self(cond, item, ..) = self; - if *cond { item.layout(to) } else { O::Area::zero().into() } + if *cond { item.layout(to) } else { XYWH::::zero().into() } } } @@ -356,7 +384,7 @@ impl, B: Content> Either { } impl, B: Layout> Layout for Either { - fn layout (&self, to: E::Area) -> E::Area { + fn layout (&self, to: XYWH) -> XYWH { let Self(cond, a, b, ..) = self; if *cond { a.layout(to) } else { b.layout(to) } } @@ -376,14 +404,14 @@ impl, B: Content> Draw for Either { layout_op_xy!(0: Fill); impl> Layout for Fill { - fn x (&self, area: O::Area) -> O::Unit { if self.dx() { area.x() } else { self.inner().x(area) } } - fn y (&self, area: O::Area) -> O::Unit { if self.dy() { area.y() } else { self.inner().y(area) } } - fn w (&self, area: O::Area) -> O::Unit { if self.dx() { area.w() } else { self.inner().w(area) } } - fn w_min (&self, area: O::Area) -> O::Unit { if self.dx() { area.w() } else { self.inner().w_min(area) } } - fn w_max (&self, area: O::Area) -> O::Unit { if self.dx() { area.w() } else { self.inner().w_max(area) } } - fn h (&self, area: O::Area) -> O::Unit { if self.dy() { area.h() } else { self.inner().h(area) } } - fn h_min (&self, area: O::Area) -> O::Unit { if self.dy() { area.h() } else { self.inner().h_min(area) } } - fn h_max (&self, area: O::Area) -> O::Unit { if self.dy() { area.h() } else { self.inner().h_max(area) } } + fn x (&self, area: XYWH) -> O::Unit { if self.dx() { area.x() } else { self.inner().x(area) } } + fn y (&self, area: XYWH) -> O::Unit { if self.dy() { area.y() } else { self.inner().y(area) } } + fn w (&self, area: XYWH) -> O::Unit { if self.dx() { area.w() } else { self.inner().w(area) } } + fn w_min (&self, area: XYWH) -> O::Unit { if self.dx() { area.w() } else { self.inner().w_min(area) } } + fn w_max (&self, area: XYWH) -> O::Unit { if self.dx() { area.w() } else { self.inner().w_max(area) } } + fn h (&self, area: XYWH) -> O::Unit { if self.dy() { area.h() } else { self.inner().h(area) } } + fn h_min (&self, area: XYWH) -> O::Unit { if self.dy() { area.h() } else { self.inner().h_min(area) } } + fn h_max (&self, area: XYWH) -> O::Unit { if self.dy() { area.h() } else { self.inner().h_max(area) } } } impl Fill { #[inline] pub const fn dx (&self) -> bool { matches!(self, Self::X(_) | Self::XY(_)) } @@ -392,53 +420,57 @@ impl, B: Content> Draw for Either { layout_op_xy!(1 opt: Fixed); impl> Layout for Fixed { - fn w (&self, area: O::Area) -> O::Unit { self.dx().unwrap_or(self.inner().w(area)) } - fn w_min (&self, area: O::Area) -> O::Unit { self.dx().unwrap_or(self.inner().w_min(area)) } - fn w_max (&self, area: O::Area) -> O::Unit { self.dx().unwrap_or(self.inner().w_max(area)) } - fn h (&self, area: O::Area) -> O::Unit { self.dy().unwrap_or(self.inner().h(area)) } - fn h_min (&self, area: O::Area) -> O::Unit { self.dy().unwrap_or(self.inner().h_min(area)) } - fn h_max (&self, area: O::Area) -> O::Unit { self.dy().unwrap_or(self.inner().h_max(area)) } + fn w (&self, area: XYWH) -> O::Unit { self.dx().unwrap_or(self.inner().w(area)) } + fn w_min (&self, area: XYWH) -> O::Unit { self.dx().unwrap_or(self.inner().w_min(area)) } + fn w_max (&self, area: XYWH) -> O::Unit { self.dx().unwrap_or(self.inner().w_max(area)) } + fn h (&self, area: XYWH) -> O::Unit { self.dy().unwrap_or(self.inner().h(area)) } + fn h_min (&self, area: XYWH) -> O::Unit { self.dy().unwrap_or(self.inner().h_min(area)) } + fn h_max (&self, area: XYWH) -> O::Unit { self.dy().unwrap_or(self.inner().h_max(area)) } } layout_op_xy!(1 opt: Max); impl> Layout for Max { - fn layout (&self, area: E::Area) -> E::Area { - let [x, y, w, h] = self.inner().layout(area).xywh(); + fn layout (&self, area: XYWH) -> XYWH { + let XYWH(x, y, w, h) = self.inner().layout(area); match self { - Self::X(mw, _) => [x, y, w.min(*mw), h ], - Self::Y(mh, _) => [x, y, w, h.min(*mh)], - Self::XY(mw, mh, _) => [x, y, w.min(*mw), h.min(*mh)], - }.into() + Self::X(mw, _) => XYWH(x, y, w.min(*mw), h ), + Self::Y(mh, _) => XYWH(x, y, w, h.min(*mh)), + Self::XY(mw, mh, _) => XYWH(x, y, w.min(*mw), h.min(*mh)), + } } } layout_op_xy!(1 opt: Min); impl> Layout for Min { - fn layout (&self, area: E::Area) -> E::Area { - let [x, y, w, h] = self.inner().layout(area).xywh(); + fn layout (&self, area: XYWH) -> XYWH { + let XYWH(x, y, w, h) = self.inner().layout(area); match self { - Self::X(mw, _) => [x, y, w.max(*mw), h], - Self::Y(mh, _) => [x, y, w, h.max(*mh)], - Self::XY(mw, mh, _) => [x, y, w.max(*mw), h.max(*mh)], - }.into() + Self::X(mw, _) => XYWH(x, y, w.max(*mw), h), + Self::Y(mh, _) => XYWH(x, y, w, h.max(*mh)), + Self::XY(mw, mh, _) => XYWH(x, y, w.max(*mw), h.max(*mh)), + } } } layout_op_xy!(1 opt: Expand); impl> Layout for Expand { - fn w (&self, to: O::Area) -> O::Unit { self.inner().w(to).plus(self.dx().unwrap_or_default()) } - fn h (&self, to: O::Area) -> O::Unit { self.inner().w(to).plus(self.dy().unwrap_or_default()) } + fn w (&self, to: XYWH) -> O::Unit { + self.inner().w(to).plus(self.dx().unwrap_or_default()) + } + fn h (&self, to: XYWH) -> O::Unit { + self.inner().w(to).plus(self.dy().unwrap_or_default()) + } } // FIXME: why they differ? layout_op_xy!(1 opt: Shrink); impl> Layout for Shrink { - fn layout (&self, to: E::Area) -> E::Area { + fn layout (&self, to: XYWH) -> XYWH { let area = self.inner().layout(to); let dx = self.dx().unwrap_or_default(); let dy = self.dy().unwrap_or_default(); - [area.x(), area.y(), area.w().minus(dx), area.h().minus(dy)].into() + XYWH(area.x(), area.y(), area.w().minus(dx), area.h().minus(dy)) } } @@ -461,7 +493,7 @@ impl> Draw for Align { } impl> Layout for Align { - fn x (&self, to: O::Area) -> O::Unit { + fn x (&self, to: XYWH) -> O::Unit { match self.0 { NW | W | SW => to.x(), N | Center | S => to.x().plus(to.w() / 2.into()).minus(self.1.w(to) / 2.into()), @@ -469,7 +501,7 @@ impl> Layout for Align { _ => todo!(), } } - fn y (&self, to: O::Area) -> O::Unit { + fn y (&self, to: XYWH) -> O::Unit { match self.0 { NW | N | NE => to.y(), W | Center | E => to.y().plus(to.h() / 2.into()).minus(self.1.h(to) / 2.into()), @@ -499,10 +531,10 @@ impl> Draw for Pad { fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) } } impl> Layout for Pad { - fn x (&self, area: O::Area) -> O::Unit { area.x().plus(self.dx()) } - fn y (&self, area: O::Area) -> O::Unit { area.x().plus(self.dx()) } - fn w (&self, area: O::Area) -> O::Unit { area.w().minus(self.dx() * 2.into()) } - fn h (&self, area: O::Area) -> O::Unit { area.h().minus(self.dy() * 2.into()) } + fn x (&self, area: XYWH) -> O::Unit { area.x().plus(self.dx()) } + fn y (&self, area: XYWH) -> O::Unit { area.x().plus(self.dx()) } + fn w (&self, area: XYWH) -> O::Unit { area.w().minus(self.dx() * 2.into()) } + fn h (&self, area: XYWH) -> O::Unit { area.h().minus(self.dy() * 2.into()) } } impl Bsp { #[inline] pub const fn n (a: Head, b: Tail) -> Self { Self(North, a, b) } @@ -519,12 +551,10 @@ impl, Tail: Content> Draw for Bsp { South => { //panic!("{}", self.1.h(to.area())); let area_1 = self.1.layout(to.area()); - let area_2 = self.2.layout([ - to.area().x(), - to.area().y().plus(area_1.h()), - to.area().w(), - to.area().h().minus(area_1.h()) - ].into()); + let area_2 = self.2.layout(XYWH( + to.area().x(), to.area().y().plus(area_1.h()), + to.area().w(), to.area().h().minus(area_1.h()) + )); //panic!("{area_1:?} {area_2:?}"); to.place_at(area_1, &self.1); to.place_at(area_2, &self.2); @@ -543,69 +573,75 @@ impl, Tail: Content> Draw for Bsp { } } impl, Tail: Layout> Layout for Bsp { - fn w (&self, area: O::Area) -> O::Unit { + fn w (&self, area: XYWH) -> O::Unit { match self.0 { Above | Below | North | South => self.1.w(area).max(self.2.w(area)), East | West => self.1.w_min(area).plus(self.2.w(area)), } } - fn w_min (&self, area: O::Area) -> O::Unit { + fn w_min (&self, area: XYWH) -> O::Unit { match self.0 { Above | Below | North | South => self.1.w_min(area).max(self.2.w_min(area)), East | West => self.1.w_min(area).plus(self.2.w_min(area)), } } - fn w_max (&self, area: O::Area) -> O::Unit { + fn w_max (&self, area: XYWH) -> O::Unit { match self.0 { Above | Below | North | South => self.1.w_max(area).max(self.2.w_max(area)), East | West => self.1.w_max(area).plus(self.2.w_max(area)), } } - fn h (&self, area: O::Area) -> O::Unit { + fn h (&self, area: XYWH) -> O::Unit { match self.0 { Above | Below | East | West => self.1.h(area).max(self.2.h(area)), North | South => self.1.h(area).plus(self.2.h(area)), } } - fn h_min (&self, area: O::Area) -> O::Unit { + fn h_min (&self, area: XYWH) -> O::Unit { match self.0 { Above | Below | East | West => self.1.h_min(area).max(self.2.h_min(area)), North | South => self.1.h_min(area).plus(self.2.h_min(area)), } } - fn h_max (&self, area: O::Area) -> O::Unit { + fn h_max (&self, area: XYWH) -> O::Unit { match self.0 { Above | Below | North | South => self.1.h_max(area).max(self.2.h_max(area)), East | West => self.1.h_max(area).plus(self.2.h_max(area)), } } - fn layout (&self, area: O::Area) -> O::Area { + fn layout (&self, area: XYWH) -> XYWH { bsp_areas(area, self.0, &self.1, &self.2)[2] } } -fn bsp_areas , B: Layout> (area: O::Area, direction: Direction, a: &A, b: &B,) -> [O::Area;3] { - let [x, y, w, h] = area.xywh(); - let [aw, ah] = a.layout(area).wh(); - let [bw, bh] = b.layout(match direction { - Above | Below => area, - South => [x, y + ah, w, h.minus(ah)].into(), - North => [x, y, w, h.minus(ah)].into(), - East => [x + aw, y, w.minus(aw), h].into(), - West => [x, y, w.minus(aw), h].into(), +fn bsp_areas , B: Layout> ( + area: XYWH, + direction: Direction, + a: &A, + b: &B, +) -> [XYWH;3] { + let XYWH(x, y, w, h) = area; + let WH(aw, ah) = a.layout(area).wh(); + let WH(bw, bh) = b.layout(match direction { + South => XYWH(x, y + ah, w, h.minus(ah)), + North => XYWH(x, y, w, h.minus(ah)), + East => XYWH(x + aw, y, w.minus(aw), h), + West => XYWH(x, y, w.minus(aw), h), + Above => area, + Below => area, }).wh(); match direction { Above | Below => { - let [x, y, w, h] = area.center_xy([aw.max(bw), ah.max(bh)]); - let a = [(x + w/2.into()).minus(aw/2.into()), (y + h/2.into()).minus(ah/2.into()), aw, ah]; - let b = [(x + w/2.into()).minus(bw/2.into()), (y + h/2.into()).minus(bh/2.into()), bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] + let XYWH(x, y, w, h) = area.centered_xy([aw.max(bw), ah.max(bh)]); + let a = XYWH((x + w/2.into()).minus(aw/2.into()), (y + h/2.into()).minus(ah/2.into()), aw, ah); + let b = XYWH((x + w/2.into()).minus(bw/2.into()), (y + h/2.into()).minus(bh/2.into()), bw, bh); + [a.into(), b.into(), XYWH(x, y, w, h)] }, South => { - let [x, y, w, h] = area.center_xy([aw.max(bw), ah + bh]); - let a = [(x + w/2.into()).minus(aw/2.into()), y, aw, ah]; - let b = [(x + w/2.into()).minus(bw/2.into()), y + ah, bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] + let XYWH(x, y, w, h) = area.centered_xy([aw.max(bw), ah + bh]); + let a = XYWH((x + w/2.into()).minus(aw/2.into()), y, aw, ah); + let b = XYWH((x + w/2.into()).minus(bw/2.into()), y + ah, bw, bh); + [a.into(), b.into(), XYWH(x, y, w, h)] }, North => { - let [x, y, w, h] = area.center_xy([aw.max(bw), ah + bh]); - let a = [(x + (w/2.into())).minus(aw/2.into()), y + bh, aw, ah]; - let b = [(x + (w/2.into())).minus(bw/2.into()), y, bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] + let XYWH(x, y, w, h) = area.centered_xy([aw.max(bw), ah + bh]); + let a = XYWH((x + (w/2.into())).minus(aw/2.into()), y + bh, aw, ah); + let b = XYWH((x + (w/2.into())).minus(bw/2.into()), y, bw, bh); + [a.into(), b.into(), XYWH(x, y, w, h)] }, East => { - let [x, y, w, h] = area.center_xy([aw + bw, ah.max(bh)]); - let a = [x, (y + h/2.into()).minus(ah/2.into()), aw, ah]; - let b = [x + aw, (y + h/2.into()).minus(bh/2.into()), bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] + let XYWH(x, y, w, h) = area.centered_xy([aw + bw, ah.max(bh)]); + let a = XYWH(x, (y + h/2.into()).minus(ah/2.into()), aw, ah); + let b = XYWH(x + aw, (y + h/2.into()).minus(bh/2.into()), bw, bh); + [a.into(), b.into(), XYWH(x, y, w, h)] }, West => { - let [x, y, w, h] = area.center_xy([aw + bw, ah.max(bh)]); - let a = [x + bw, (y + h/2.into()).minus(ah/2.into()), aw, ah]; - let b = [x, (y + h/2.into()).minus(bh/2.into()), bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] + let XYWH(x, y, w, h) = area.centered_xy([aw + bw, ah.max(bh)]); + let a = XYWH(x + bw, (y + h/2.into()).minus(ah/2.into()), aw, ah); + let b = XYWH(x, (y + h/2.into()).minus(bh/2.into()), bw, bh); + [a.into(), b.into(), XYWH(x, y, w, h)] }, } } @@ -635,13 +671,13 @@ impl<'a, O, A, B, I, F, G> Layout for Map where F: Fn() -> I + Send + Sync + 'a, G: Fn(A, usize)->B + Send + Sync { - fn layout (&self, area: O::Area) -> O::Area { + fn layout (&self, area: XYWH) -> XYWH { let Self { get_iter, get_item, .. } = self; let mut index = 0; let [mut min_x, mut min_y] = area.center(); let [mut max_x, mut max_y] = area.center(); for item in get_iter() { - let [x,y,w,h] = get_item(item, index).layout(area).xywh(); + let XYWH(x, y, w, h) = get_item(item, index).layout(area); min_x = min_x.min(x); min_y = min_y.min(y); max_x = max_x.max(x + w); @@ -651,7 +687,7 @@ impl<'a, O, A, B, I, F, G> Layout for Map where let w = max_x - min_x; let h = max_y - min_y; //[min_x.into(), min_y.into(), w.into(), h.into()].into() - area.center_xy([w.into(), h.into()]).into() + area.centered_xy([w.into(), h.into()]) } } impl<'a, O, A, B, I, F, G> Draw for Map where @@ -720,15 +756,11 @@ impl Tryptich { } impl> Layout for Foreground { - fn layout (&self, to: O::Area) -> O::Area { - self.1.layout(to) - } + fn layout (&self, to: XYWH) -> XYWH { self.1.layout(to) } } impl> Layout for Background { - fn layout (&self, to: O::Area) -> O::Area { - self.1.layout(to) - } + fn layout (&self, to: XYWH) -> XYWH { self.1.layout(to) } } impl, V: Content> HasContent for FieldH { @@ -736,7 +768,7 @@ impl, V: Content> HasContent for FieldH } impl, V: Content> Layout for FieldH { - fn layout (&self, to: O::Area) -> O::Area { self.content().layout(to) } + fn layout (&self, to: XYWH) -> XYWH { self.content().layout(to) } } impl, V: Content> Draw for FieldH { @@ -748,14 +780,14 @@ impl, V: Content> HasContent for FieldV } impl, V: Content> Layout for FieldV { - fn layout (&self, to: O::Area) -> O::Area { self.content().layout(to) } + fn layout (&self, to: XYWH) -> XYWH { self.content().layout(to) } } impl, V: Content> Draw for FieldV { fn draw (&self, to: &mut O) { self.content().draw(to) } } impl> Layout for Border { - fn layout (&self, area: O::Area) -> O::Area { + fn layout (&self, area: XYWH) -> XYWH { self.1.layout(area) } } diff --git a/output/src/out_structs.rs b/output/src/out_structs.rs index 22b6465..b3b14bb 100644 --- a/output/src/out_structs.rs +++ b/output/src/out_structs.rs @@ -5,14 +5,16 @@ use crate::*; /// ``` /// let xy: XY = XY(0, 0); /// ``` -pub struct XY(pub C, pub C); +#[cfg_attr(test, derive(Arbitrary))] +#[derive(Copy, Clone)] pub struct XY(pub C, pub C); /// A size (Width, Height). /// /// ``` /// let wh: WH = WH(0, 0); /// ``` -pub struct WH(pub C, pub C); +#[cfg_attr(test, derive(Arbitrary))] +#[derive(Copy, Clone)] pub struct WH(pub C, pub C); /// Point with size. /// @@ -22,15 +24,16 @@ pub struct WH(pub C, pub C); /// /// * [ ] TODO: anchor field (determines at which corner/side is X0 Y0) /// -pub struct XYWH(pub C, pub C, pub C, pub C); +#[cfg_attr(test, derive(Arbitrary))] +#[derive(Copy, Clone)] pub struct XYWH(pub C, pub C, pub C, pub C); /// A cardinal direction. /// /// ``` /// let direction = Direction::Above; /// ``` -#[derive(Copy, Clone, PartialEq, Debug)] #[cfg_attr(test, derive(Arbitrary))] -pub enum Direction { +#[cfg_attr(test, derive(Arbitrary))] +#[derive(Copy, Clone, PartialEq, Debug)] pub enum Direction { North, South, East, West, Above, Below } @@ -39,8 +42,8 @@ pub enum Direction { /// ``` /// let alignment = Align::Center; /// ``` -#[derive(Debug, Copy, Clone, Default)] -pub enum Alignment { +#[cfg_attr(test, derive(Arbitrary))] +#[derive(Debug, Copy, Clone, Default)] pub enum Alignment { #[default] Center, X, Y, NW, N, NE, E, SE, S, SW, W } @@ -130,8 +133,8 @@ pub enum Expand { X(U, A), Y(U, A), XY(U, U, A), } /// /// ``` /// use ::tengri::{output::*, tui::*}; -/// let area: [u16;4] = [10, 10, 20, 20]; -/// fn test (area: [u16;4], item: &impl Draw, expected: [u16;4]) { +/// let area = XYWH(10u16, 10, 20, 20); +/// fn test (area: XYWH<16>, item: &impl Draw, expected: [u16;4]) { /// assert_eq!(Content::layout(item, area), expected); /// assert_eq!(Draw::layout(item, area), expected); /// }; @@ -166,7 +169,7 @@ pub enum Pad { X(U, A), Y(U, A), XY(U, U, A), } /// ``` /// let bounded = Bounded(XYWH(0, 0, 0, 0), ""); /// ``` -pub struct Bounded(pub O::Area, pub D); +pub struct Bounded(pub XYWH, pub D); /// Draws items from an iterator. /// diff --git a/output/src/out_traits.rs b/output/src/out_traits.rs index 10196cb..b004012 100644 --- a/output/src/out_traits.rs +++ b/output/src/out_traits.rs @@ -15,7 +15,7 @@ use crate::*; /// fn area_mut (&mut self) -> &mut [u16;4] { /// &mut self.0 /// } -/// fn place_at + ?Sized> (&mut self, area: [u16;4], _: &T) { +/// fn place_at + ?Sized> (&mut self, area: XYWH, _: &T) { /// println!("place_at: {area:?}"); /// () /// } @@ -29,20 +29,14 @@ use crate::*; pub trait Out: Send + Sync + Sized { /// Unit of length type Unit: Coord; - /// Rectangle without offset - type Size: HasWH; - /// Rectangle with offset - type Area: HasXYWH; /// Current output area - fn area (&self) -> Self::Area; + fn area (&self) -> XYWH; /// Mutable pointer to area. - fn area_mut (&mut self) -> &mut Self::Area; + fn area_mut (&mut self) -> &mut XYWH; /// Render drawable in area specified by `area` - fn place_at <'t, T: Draw + ?Sized> (&mut self, area: Self::Area, content: &'t T); + fn place_at <'t, T: Draw + ?Sized> (&mut self, area: XYWH, content: &'t T); /// Render drawable in area specified by `T::layout(self.area())` - #[inline] fn place <'t, T: Content + ?Sized> ( - &mut self, content: &'t T - ) { + #[inline] fn place <'t, T: Content + ?Sized> (&mut self, content: &'t T) { self.place_at(content.layout(self.area()), content) } } @@ -79,15 +73,17 @@ pub trait Lay: Sized {} /// Drawable area of display. pub trait Layout { - fn x (&self, to: O::Area) -> O::Unit { to.x() } - fn y (&self, to: O::Area) -> O::Unit { to.y() } - fn w_min (&self, _t: O::Area) -> O::Unit { 0.into() } - fn w_max (&self, to: O::Area) -> O::Unit { to.w() } - fn w (&self, to: O::Area) -> O::Unit { to.w().max(self.w_min(to)).min(self.w_max(to)) } - fn h_min (&self, _t: O::Area) -> O::Unit { 0.into() } - fn h_max (&self, to: O::Area) -> O::Unit { to.h() } - fn h (&self, to: O::Area) -> O::Unit { to.h().max(self.h_min(to)).min(self.h_max(to)) } - fn layout (&self, to: O::Area) -> O::Area { [self.x(to), self.y(to), self.w(to), self.h(to)].into() } + fn x (&self, to: XYWH) -> O::Unit { to.x() } + fn y (&self, to: XYWH) -> O::Unit { to.y() } + fn w_min (&self, _t: XYWH) -> O::Unit { 0.into() } + fn w_max (&self, to: XYWH) -> O::Unit { to.w() } + fn w (&self, to: XYWH) -> O::Unit { to.w().max(self.w_min(to)).min(self.w_max(to)) } + fn h_min (&self, _t: XYWH) -> O::Unit { 0.into() } + fn h_max (&self, to: XYWH) -> O::Unit { to.h() } + fn h (&self, to: XYWH) -> O::Unit { to.h().max(self.h_min(to)).min(self.h_max(to)) } + fn layout (&self, to: XYWH) -> XYWH { + XYWH(self.x(to), self.y(to), self.w(to), self.h(to)) + } } pub trait HasContent { @@ -111,9 +107,16 @@ pub trait Coord: Send + Sync + Copy + Into + Into { - fn zero () -> Self { 0.into() } fn plus (self, other: Self) -> Self; - fn minus (self, other: Self) -> Self { if self >= other { self - other } else { 0.into() } } + fn minus (self, other: Self) -> Self { + if self >= other { self - other } else { 0.into() } + } + fn atomic (self) -> AtomicUsize { + AtomicUsize::new(self.into()) + } + fn zero () -> Self { + 0.into() + } } // Something that has an origin point (X, Y).