mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-08-07 14:16:56 +02:00
150 lines
4.4 KiB
Rust
150 lines
4.4 KiB
Rust
use crate::*;
|
|
|
|
impl<S: Screen, T: Draw<S>> Layout<S> for T {}
|
|
|
|
pub trait Layout<S: Screen>: Draw<S> + Sized {
|
|
fn full_w (self) -> impl Draw<S> {
|
|
Full::W(self)
|
|
}
|
|
fn full_h (self) -> impl Draw<S> {
|
|
Full::H(self)
|
|
}
|
|
fn full_wh (self) -> impl Draw<S> {
|
|
Full::WH(self)
|
|
}
|
|
|
|
fn origin (self, azimuth: impl Into<Option<Azimuth>>) -> impl Draw<S> {
|
|
Origin(azimuth.into(), self)
|
|
}
|
|
fn origin_c (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::C), self)
|
|
}
|
|
fn origin_x (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::X), self)
|
|
}
|
|
fn origin_y (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::Y), self)
|
|
}
|
|
|
|
fn origin_n (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::N), self)
|
|
}
|
|
fn origin_s (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::S), self)
|
|
}
|
|
fn origin_e (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::E), self)
|
|
}
|
|
fn origin_w (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::W), self)
|
|
}
|
|
|
|
fn origin_ne (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::NE), self)
|
|
}
|
|
fn origin_se (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::SE), self)
|
|
}
|
|
fn origin_nw (self) -> impl Draw<S> {
|
|
Origin(Some(Azimuth::NW), self)
|
|
}
|
|
fn origin_sw (self) -> impl Draw<S> {
|
|
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<AtomicUsize>,
|
|
/// Height
|
|
pub Arc<AtomicUsize>,
|
|
);
|
|
|
|
impl Xy<u16> for Sizer {
|
|
fn x (&self) -> u16 {
|
|
self.0.load(Relaxed) as u16
|
|
}
|
|
fn y (&self) -> u16 {
|
|
self.1.load(Relaxed) as u16
|
|
}
|
|
}
|
|
impl Wide<u16> for Sizer {
|
|
fn w (&self) -> u16 {
|
|
self.0.load(Relaxed) as u16
|
|
}
|
|
}
|
|
impl Tall<u16> 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 <T: Screen> (&self, of: impl Draw<T>) -> impl Draw<T> {
|
|
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<S: Screen, T: Draw<S>> $Trait<S> for T {}
|
|
|
|
pub trait $Trait<S: Screen>: Draw<S> + Sized {
|
|
fn $fn_x <N: Into<Option<S::Unit>> + Copy> (self, x: N)
|
|
-> $Struct<S, Self, N> { $Struct::$X(self, x) }
|
|
fn $fn_y <N: Into<Option<S::Unit>> + Copy> (self, y: N)
|
|
-> $Struct<S, Self, N> { $Struct::$Y(self, y) }
|
|
fn $fn_xy <N: Into<Option<S::Unit>> + Copy> (self, x: N, y: N)
|
|
-> $Struct<S, Self, N> { $Struct::$XY(self, x, y) }
|
|
}
|
|
|
|
pub enum $Struct<S: Screen, I: Draw<S>, X: Into<Option<S::Unit>>> {
|
|
__(PhantomData<S>), $X(I, X), $Y(I, X), $XY(I, X, X),
|
|
}
|
|
|
|
impl <S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for $Struct<S, I, X> {
|
|
fn draw (&$self, $to: &mut S) -> Perhaps<XYWH<S::Unit>> {
|
|
$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::*;
|