mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-08-28 13:06:56 +02:00
This commit is contained in:
parent
de591addb3
commit
8a6eb19e27
3 changed files with 88 additions and 70 deletions
|
|
@ -3,16 +3,6 @@ use crate::*;
|
||||||
impl<S: Screen, T: Draw<S>> Layout<S> for T {}
|
impl<S: Screen, T: Draw<S>> Layout<S> for T {}
|
||||||
|
|
||||||
pub trait Layout<S: Screen>: Draw<S> + Sized {
|
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> {
|
fn origin (self, azimuth: impl Into<Option<Azimuth>>) -> impl Draw<S> {
|
||||||
Origin(azimuth.into(), self)
|
Origin(azimuth.into(), self)
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +88,7 @@ impl Sizer {
|
||||||
|
|
||||||
/// Some layout operations exist in multiple variants that take a single argument.
|
/// Some layout operations exist in multiple variants that take a single argument.
|
||||||
/// Their handling in [eval_view] is uniform and goes like this:
|
/// Their handling in [eval_view] is uniform and goes like this:
|
||||||
macro_rules! eval_enum ((
|
#[macro_export] macro_rules! eval_enum ((
|
||||||
$name:literal, $output:ident, $state:ident, $value:expr, $Enum:ident {
|
$name:literal, $output:ident, $state:ident, $value:expr, $Enum:ident {
|
||||||
$($v:literal => $V:ident),* $(,)?
|
$($v:literal => $V:ident),* $(,)?
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +101,7 @@ macro_rules! eval_enum ((
|
||||||
|
|
||||||
/// Some layout operations exist in XY, X, and Y variants that take 3 or 2 arguments.
|
/// Some layout operations exist in XY, X, and Y variants that take 3 or 2 arguments.
|
||||||
/// Their handling in [eval_view] is uniform and goes like this:
|
/// Their handling in [eval_view] is uniform and goes like this:
|
||||||
macro_rules! eval_xy (
|
#[macro_export] macro_rules! eval_xy (
|
||||||
// Valueless variant:
|
// Valueless variant:
|
||||||
// (fill/x ...)
|
// (fill/x ...)
|
||||||
// (fill/y ...)
|
// (fill/y ...)
|
||||||
|
|
@ -166,7 +156,36 @@ macro_rules! eval_xy (
|
||||||
}};
|
}};
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! def_layout_modifier {
|
#[macro_export] macro_rules! fn_kw_layout {
|
||||||
|
($name:ident |$state:ident, $output: ident, $expr:ident| $body:block) => {
|
||||||
|
#[cfg(all(feature = "draw", feature = "eval"))]
|
||||||
|
pub fn $name <O: Screen, S> (
|
||||||
|
$state: &S, $output: &mut O, $expr: &str
|
||||||
|
) -> Perhaps<XYWH<O::Unit>> where
|
||||||
|
S: Interpret<O, Option<XYWH<O::Unit>>>
|
||||||
|
+ for<'b> Namespace<'b, bool>
|
||||||
|
+ for<'b> Namespace<'b, O::Unit>
|
||||||
|
+ for<'b> Namespace<'b, Option<O::Unit>>
|
||||||
|
$body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export] macro_rules! fn_kw_layout_tui {
|
||||||
|
($name:ident |$state:ident, $output: ident, $expr:ident| $body:block) => {
|
||||||
|
#[cfg(all(feature = "draw", feature = "eval", feature = "term"))]
|
||||||
|
pub fn $name <S> (
|
||||||
|
$state: &S, $output: &mut Tui, $expr: &str
|
||||||
|
) -> Perhaps<XYWH<u16>> where
|
||||||
|
S: Interpret<Tui, Option<XYWH<u16>>>
|
||||||
|
+ for<'b> Namespace<'b, bool>
|
||||||
|
+ for<'b> Namespace<'b, u16>
|
||||||
|
+ for<'b> Namespace<'b, Option<u16>>
|
||||||
|
+ for<'b> Namespace<'b, Color>
|
||||||
|
$body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export] macro_rules! def_layout_modifier {
|
||||||
(
|
(
|
||||||
$Trait:ident ($fn_x:ident $fn_y:ident $fn_xy:ident),
|
$Trait:ident ($fn_x:ident $fn_y:ident $fn_xy:ident),
|
||||||
$Struct:ident { $X:ident $Y:ident $XY:ident } $kw_name:ident $name:literal
|
$Struct:ident { $X:ident $Y:ident $XY:ident } $kw_name:ident $name:literal
|
||||||
|
|
@ -188,9 +207,7 @@ macro_rules! def_layout_modifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for $Struct<S, I, 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>> {
|
fn draw (&$self, $to: &mut S) -> Perhaps<XYWH<S::Unit>> { $body }
|
||||||
$body
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn_kw_layout!($kw_name |state, output, expr| {
|
fn_kw_layout!($kw_name |state, output, expr| {
|
||||||
|
|
@ -213,6 +230,43 @@ macro_rules! def_layout_modifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export] macro_rules! def_layout_modifier_flat {
|
||||||
|
(
|
||||||
|
$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 (self) -> $Struct<S, Self> { $Struct::$X(self) }
|
||||||
|
fn $fn_y (self) -> $Struct<S, Self> { $Struct::$Y(self) }
|
||||||
|
fn $fn_xy (self) -> $Struct<S, Self> { $Struct::$XY(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum $Struct<S: Screen, I: Draw<S>> {
|
||||||
|
__(PhantomData<S>), $X(I), $Y(I), $XY(I),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <S: Screen, I: Draw<S>> Draw<S> for $Struct<S, I> {
|
||||||
|
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!(frags.next(), Some($name)).then(||{
|
||||||
|
let args = expr.tail();
|
||||||
|
let arg0 = args.head();
|
||||||
|
eval_xy!(
|
||||||
|
$name => expr, head, output, state, frags.next(),
|
||||||
|
$fn_xy, $fn_x, $fn_y, arg0,
|
||||||
|
)
|
||||||
|
}).transpose()?.flatten())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod area; pub use self::area::*;
|
mod area; pub use self::area::*;
|
||||||
mod axis; pub use self::axis::*;
|
mod axis; pub use self::axis::*;
|
||||||
mod azimuth; pub use self::azimuth::*;
|
mod azimuth; pub use self::azimuth::*;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,23 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
/// Use whole drawing area along one or both axes.
|
def_layout_modifier_flat!(
|
||||||
pub enum Full<T: Screen, I: Draw<T>> {
|
LayoutFull (full_w full_h full_wh),
|
||||||
__(PhantomData<T>),
|
Full { W H WH } kw_full "full" |self, to| {
|
||||||
W(I),
|
let XYWH(x0, y0, w0, h0) = to.area();
|
||||||
H(I),
|
let item = match self {
|
||||||
WH(I),
|
Self::W(i) => i, Self::H(i) => i, Self::WH(i) => i, _ => unreachable!()
|
||||||
}
|
};
|
||||||
|
let (x1, y1, w1, h1) = match self {
|
||||||
impl_draw!(<T: Screen, I: Draw<T>,>|self: Full<T, I>, to: T|{
|
Self::W(..) => (Some(x0), None, Some(w0), None),
|
||||||
let XYWH(x0, y0, w0, h0) = to.area();
|
Self::H(..) => (None, Some(y0), None, Some(h0)),
|
||||||
let item = match self {
|
Self::WH(..) => (Some(x0), Some(y0), Some(w0), Some(h0)),
|
||||||
Self::W(i) => i, Self::H(i) => i, Self::WH(i) => i, _ => unreachable!()
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
let (x1, y1, w1, h1) = match self {
|
Ok(to.draw(to.area(), item)?.map(|XYWH(x2, y2, w2, h2)|XYWH(
|
||||||
Self::W(..) => (Some(x0), None, Some(w0), None),
|
x1.unwrap_or(x2), y1.unwrap_or(y2), w1.unwrap_or(w2), h1.unwrap_or(h2),
|
||||||
Self::H(..) => (None, Some(y0), None, Some(h0)),
|
)))
|
||||||
Self::WH(..) => (Some(x0), Some(y0), Some(w0), Some(h0)),
|
}
|
||||||
_ => unreachable!()
|
);
|
||||||
};
|
|
||||||
Ok(to.draw(to.area(), item)?.map(|XYWH(x2, y2, w2, h2)|XYWH(
|
|
||||||
x1.unwrap_or(x2), y1.unwrap_or(y2), w1.unwrap_or(w2), h1.unwrap_or(h2),
|
|
||||||
)))
|
|
||||||
});
|
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_layout_full () -> Usually<()> {
|
#[cfg(test)] #[test] fn test_layout_full () -> Usually<()> {
|
||||||
assert_eq!(check_layout("1")?, Some(XYWH(1u16, 1, 1, 1)));
|
assert_eq!(check_layout("1")?, Some(XYWH(1u16, 1, 1, 1)));
|
||||||
|
|
|
||||||
31
src/lib.rs
31
src/lib.rs
|
|
@ -29,37 +29,6 @@ pub(crate) use ::{
|
||||||
std::marker::PhantomData
|
std::marker::PhantomData
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
||||||
macro_rules! fn_kw_layout {
|
|
||||||
($name:ident |$state:ident, $output: ident, $expr:ident| $body:block) => {
|
|
||||||
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
||||||
pub fn $name <O: Screen, S> (
|
|
||||||
$state: &S, $output: &mut O, $expr: &str
|
|
||||||
) -> Perhaps<XYWH<O::Unit>> where
|
|
||||||
S: Interpret<O, Option<XYWH<O::Unit>>>
|
|
||||||
+ for<'b> Namespace<'b, bool>
|
|
||||||
+ for<'b> Namespace<'b, O::Unit>
|
|
||||||
+ for<'b> Namespace<'b, Option<O::Unit>>
|
|
||||||
$body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(feature = "draw", feature = "eval", feature = "term"))]
|
|
||||||
macro_rules! fn_kw_layout_tui {
|
|
||||||
($name:ident |$state:ident, $output: ident, $expr:ident| $body:block) => {
|
|
||||||
#[cfg(all(feature = "draw", feature = "eval", feature = "term"))]
|
|
||||||
pub fn $name <S> (
|
|
||||||
$state: &S, $output: &mut Tui, $expr: &str
|
|
||||||
) -> Perhaps<XYWH<u16>> where
|
|
||||||
S: Interpret<Tui, Option<XYWH<u16>>>
|
|
||||||
+ for<'b> Namespace<'b, bool>
|
|
||||||
+ for<'b> Namespace<'b, u16>
|
|
||||||
+ for<'b> Namespace<'b, Option<u16>>
|
|
||||||
+ for<'b> Namespace<'b, Color>
|
|
||||||
$body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "lang")] pub use ::dizzle::{Usually, Perhaps};
|
#[cfg(feature = "lang")] pub use ::dizzle::{Usually, Perhaps};
|
||||||
#[cfg(feature = "lang")] use ::dizzle::*;
|
#[cfg(feature = "lang")] use ::dizzle::*;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue