mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-01-31 10:56:41 +01:00
Compare commits
1 commit
a4dbf88220
...
277f96d5cc
| Author | SHA1 | Date | |
|---|---|---|---|
| 277f96d5cc |
25 changed files with 265 additions and 403 deletions
28
Justfile
28
Justfile
|
|
@ -1,29 +1,17 @@
|
||||||
export LLVM_PROFILE_FILE := "cov/cargo-test-%p-%m.profraw"
|
covfig := "CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cov/cargo-test-%p-%m.profraw'"
|
||||||
grcov-binary := "--binary-path ./target/coverage/deps/"
|
grcov-binary := "--binary-path ./target/coverage/deps/"
|
||||||
grcov-ignore := "--ignore-not-existing --ignore '../*' --ignore \"/*\" --ignore 'target/*'"
|
grcov-ignore := "--ignore-not-existing --ignore '../*' --ignore \"/*\" --ignore 'target/*'"
|
||||||
|
|
||||||
bacon:
|
bacon:
|
||||||
bacon -s
|
{{covfig}} bacon -s
|
||||||
|
|
||||||
cov:
|
cov:
|
||||||
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' \
|
{{covfig}} time cargo test -j4 --workspace --profile coverage
|
||||||
time cargo test -j4 --workspace --profile coverage
|
|
||||||
rm -rf target/coverage/html || true
|
rm -rf target/coverage/html || true
|
||||||
time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t html -o target/coverage/html
|
{{covfig}} time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t html -o target/coverage/html
|
||||||
|
|
||||||
cov-md:
|
cov-md:
|
||||||
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' \
|
{{covfig}} time cargo test -j4 --workspace --profile coverage
|
||||||
time cargo test -j4 --workspace --profile coverage
|
{{covfig}} time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t markdown | sort
|
||||||
time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t markdown | sort
|
|
||||||
|
|
||||||
cov-md-ci:
|
cov-md-ci:
|
||||||
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' \
|
{{covfig}} time cargo test -j4 --workspace --profile coverage -- --skip test_tui_engine
|
||||||
time cargo test -j4 --workspace --profile coverage -- --skip test_tui_engine
|
{{covfig}} time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t markdown | sort
|
||||||
time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t markdown | sort
|
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' \
|
|
||||||
cargo doc
|
cargo doc
|
||||||
|
|
||||||
example-tui:
|
|
||||||
cargo run -p tengri_tui --example tui
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,13 @@
|
||||||
mod core_macros;
|
mod core_macros;
|
||||||
pub(crate) use std::error::Error;
|
pub(crate) use std::error::Error;
|
||||||
|
|
||||||
/// Standard result type.
|
/// Standard result type.
|
||||||
pub type Usually<T> = Result<T, Box<dyn Error>>;
|
pub type Usually<T> = Result<T, Box<dyn Error>>;
|
||||||
|
|
||||||
/// Standard optional result type.
|
/// Standard optional result type.
|
||||||
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||||
|
|
||||||
/// Type-dispatched `get` and `get_mut`.
|
/// Type-dispatched `get` and `get_mut`.
|
||||||
pub trait Has<T>: Send + Sync { fn get (&self) -> &T; fn get_mut (&mut self) -> &mut T; }
|
pub trait Has<T>: Send + Sync { fn get (&self) -> &T; fn get_mut (&mut self) -> &mut T; }
|
||||||
|
|
||||||
/// Type-dispatched `get` and `get_mut` that return an [Option]-wrapped result.
|
/// Type-dispatched `get` and `get_mut` that return an [Option]-wrapped result.
|
||||||
pub trait MaybeHas<T>: Send + Sync { fn get (&self) -> Option<&T>; fn get_mut (&mut self) -> Option<&mut T>; }
|
pub trait MaybeHas<T>: Send + Sync { fn get (&self) -> Option<&T>; fn get_mut (&mut self) -> Option<&mut T>; }
|
||||||
|
|
||||||
/// May compute a `RetVal` from `Args`.
|
/// May compute a `RetVal` from `Args`.
|
||||||
pub trait Eval<Args, RetVal> {
|
pub trait Eval<Args, RetVal> {
|
||||||
/// A custom operation on [Args] that may return [Result::Err] or [Option::None].
|
/// A custom operation on [Args] that may return [Result::Err] or [Option::None].
|
||||||
|
|
@ -27,11 +22,3 @@ pub trait Eval<Args, RetVal> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export] macro_rules! as_ref {
|
|
||||||
($T:ty: |$self:ident : $S:ty| $x:expr) => {
|
|
||||||
impl AsRef<$T> for $S {
|
|
||||||
fn as_ref (&$self) -> &$T { &$x }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ dsl_type!(DslExpr {
|
||||||
).into())
|
).into())
|
||||||
};
|
};
|
||||||
)*
|
)*
|
||||||
Ok(Some($body/* as $Type*/))
|
Ok(Some($body as $Type))
|
||||||
};
|
};
|
||||||
($name, get)
|
($name, get)
|
||||||
}),* )? ];
|
}),* )? ];
|
||||||
|
|
@ -74,14 +74,12 @@ pub trait DslNsExprs<'a, T: 'a>: 'a {
|
||||||
const EXPRS: DslExprs<'a, Self, T> = &[];
|
const EXPRS: DslExprs<'a, Self, T> = &[];
|
||||||
/// Resolve an expression if known.
|
/// Resolve an expression if known.
|
||||||
fn from_expr (&'a self, dsl: impl DslExpr + 'a) -> Perhaps<T> {
|
fn from_expr (&'a self, dsl: impl DslExpr + 'a) -> Perhaps<T> {
|
||||||
if let Some(dsl) = dsl.expr()? {
|
|
||||||
let head = dsl.head()?;
|
let head = dsl.head()?;
|
||||||
for (key, get) in Self::EXPRS.iter() {
|
for (key, get) in Self::EXPRS.iter() {
|
||||||
if Some(*key) == head {
|
if Some(*key) == head {
|
||||||
return get(self, dsl.tail()?.unwrap_or(""))
|
return get(self, dsl.tail()?.unwrap_or(""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return Ok(None)
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,31 +16,3 @@ pub trait DslNs<'a, T: 'a>: DslNsWords<'a, T> + DslNsExprs<'a, T> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export] macro_rules! dsl_ns {
|
|
||||||
($State:ty: $Type:ty {
|
|
||||||
$(literal = |$dsl:ident| $literal:expr;)?
|
|
||||||
$(word = |$state_w:ident| {
|
|
||||||
$($word:literal => $body_w:expr),* $(,)?
|
|
||||||
};)?
|
|
||||||
$(expr = |$state_e:ident| {
|
|
||||||
$($head:literal $args:tt => $body_e:expr),* $(,)?
|
|
||||||
};)?
|
|
||||||
}) => {
|
|
||||||
impl<'a> DslNs<'a, $Type> for $State {
|
|
||||||
$(fn from_literal (&self, $dsl: impl Dsl) -> Perhaps<$Type> {
|
|
||||||
$literal
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
impl<'a> DslNsWords<'a, $Type> for $State {
|
|
||||||
$(dsl_words! { 'a |$state_w| -> $Type {
|
|
||||||
$($word => $body_w),*
|
|
||||||
} })?
|
|
||||||
}
|
|
||||||
impl<'a> DslNsExprs<'a, $Type> for $State {
|
|
||||||
$(dsl_exprs! { 'a |$state_e| -> $Type {
|
|
||||||
$($head $args => $body_e),*
|
|
||||||
} })?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,37 @@ use crate::*;
|
||||||
pub trait Draw<O: Out> {
|
pub trait Draw<O: Out> {
|
||||||
/// Write data to display.
|
/// Write data to display.
|
||||||
fn draw (&self, to: &mut O);
|
fn draw (&self, to: &mut O);
|
||||||
|
|
||||||
|
fn boxed <'a> (self) -> Box<dyn Draw<O> + 'a> where Self: Sized + 'a {
|
||||||
|
Box::new(self) as Box<dyn Draw<O> + 'a>
|
||||||
|
}
|
||||||
|
fn rc <'a> (self) -> Rc<dyn Draw<O> + 'a> where Self: Sized + 'a {
|
||||||
|
Rc::new(self) as Rc<dyn Draw<O> + 'a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<O: Out> Draw<O> for () {
|
||||||
|
fn draw (&self, _: &mut O) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<O: Out, T: Draw<O>> Draw<O> for &T {
|
||||||
|
fn draw (&self, to: &mut O) {
|
||||||
|
(*self).draw(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<O: Out, T: Draw<O>> Draw<O> for &mut T {
|
||||||
|
fn draw (&self, to: &mut O) {
|
||||||
|
(**self).draw(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<O: Out, T: Draw<O>> Draw<O> for [T] {
|
||||||
|
fn draw (&self, to: &mut O) {
|
||||||
|
for draw in self.iter() {
|
||||||
|
draw.draw(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: Out> Draw<O> for fn(&mut O) {
|
impl<O: Out> Draw<O> for fn(&mut O) {
|
||||||
|
|
@ -12,12 +43,6 @@ impl<O: Out> Draw<O> for fn(&mut O) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: Out> Draw<O> for () { fn draw (&self, _: &mut O) {} }
|
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O>> Draw<O> for &T {
|
|
||||||
fn draw (&self, to: &mut O) { (*self).draw(to) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'x, O: Out> Draw<O> for &(dyn Draw<O> + 'x) {
|
impl<'x, O: Out> Draw<O> for &(dyn Draw<O> + 'x) {
|
||||||
fn draw (&self, to: &mut O) {
|
fn draw (&self, to: &mut O) {
|
||||||
(*self).draw(to)
|
(*self).draw(to)
|
||||||
|
|
@ -30,32 +55,6 @@ impl<'x, O: Out> Draw<O> for &mut (dyn Draw<O> + 'x) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O>> Draw<O> for RwLock<T> {
|
|
||||||
fn draw (&self, to: &mut O) { self.read().unwrap().draw(to) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O>> Draw<O> for [T] {
|
|
||||||
fn draw (&self, to: &mut O) {
|
|
||||||
for draw in self.iter() {
|
|
||||||
draw.draw(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//impl<O: Out, T: Draw<O>> Draw<O> for &mut T {
|
|
||||||
//fn draw (&self, to: &mut O) {
|
|
||||||
//(**self).draw(to)
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
//impl<O: Out, T: Iterator<Item = U>, U: Draw<O>> Draw<O> for &mut T {
|
|
||||||
//fn draw (&self, to: &mut O) {
|
|
||||||
//for draw in *self {
|
|
||||||
//draw.draw(to)
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// Implement custom drawing for a struct.
|
/// Implement custom drawing for a struct.
|
||||||
#[macro_export] macro_rules! draw {
|
#[macro_export] macro_rules! draw {
|
||||||
|
|
||||||
|
|
@ -83,12 +82,4 @@ impl<O: Out, T: Draw<O>> Draw<O> for [T] {
|
||||||
|
|
||||||
draw!(|self: Arc<T: Draw<O>>, to|(**self).draw(to));
|
draw!(|self: Arc<T: Draw<O>>, to|(**self).draw(to));
|
||||||
draw!(|self: Box<T: Draw<O>>, to|(**self).draw(to));
|
draw!(|self: Box<T: Draw<O>>, to|(**self).draw(to));
|
||||||
//draw!(|self: Option<T: Draw<O>>, to|if let Some(draw) = self { draw.draw(to) });
|
draw!(|self: Option<T: Draw<O>>, to|if let Some(draw) = self { draw.draw(to) });
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O>> Draw<O> for Option<T> {
|
|
||||||
fn draw (&self, to: &mut O) {
|
|
||||||
if let Some(draw) = self {
|
|
||||||
draw.draw(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#[allow(unused)] use crate::*;
|
|
||||||
|
|
||||||
pub struct Group<T>(T);
|
|
||||||
|
|
||||||
impl<T> Group<T> {
|
|
||||||
pub const fn new () -> Group<()> {
|
|
||||||
Group(())
|
|
||||||
}
|
|
||||||
pub const fn add <U> (self, value: U) -> Group<(T, U)> {
|
|
||||||
Group((self.0, value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -32,7 +32,7 @@ pub trait Layout<O: Out> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export] macro_rules! layout {
|
macro_rules! layout {
|
||||||
// Implement for all [Out] backends.
|
// Implement for all [Out] backends.
|
||||||
(|$self:ident:$Struct:ident $(<
|
(|$self:ident:$Struct:ident $(<
|
||||||
$($L:lifetime),* $($T:ident $(:$Trait:path)?),*
|
$($L:lifetime),* $($T:ident $(:$Trait:path)?),*
|
||||||
|
|
@ -63,24 +63,12 @@ impl<O: Out> Layout<O> for () {}
|
||||||
|
|
||||||
impl<O: Out, L: Layout<O>> Layout<O> for &L { /*FIXME*/ }
|
impl<O: Out, L: Layout<O>> Layout<O> for &L { /*FIXME*/ }
|
||||||
|
|
||||||
impl<O: Out, L: Layout<O>> Layout<O> for RwLock<L> { /*FIXME*/ }
|
|
||||||
|
|
||||||
impl<O: Out, L: Layout<O>> Layout<O> for Option<L> { /*FIXME*/ }
|
|
||||||
|
|
||||||
//impl<O: Out> Layout<O> for fn(&mut O) {}
|
|
||||||
|
|
||||||
impl<O: Out, L: Layout<O>> Layout<O> for Arc<L> {
|
impl<O: Out, L: Layout<O>> Layout<O> for Arc<L> {
|
||||||
fn layout (&self, to: O::Area) -> O::Area {
|
fn layout (&self, to: O::Area) -> O::Area {
|
||||||
(**self).layout(to)
|
(**self).layout(to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'x, O: Out> Layout<O> for &(dyn Draw<O> + 'x) {
|
|
||||||
fn layout (&self, to: O::Area) -> O::Area {
|
|
||||||
Fill::xy(self).layout(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod layout_align; pub use self::layout_align::*;
|
mod layout_align; pub use self::layout_align::*;
|
||||||
mod layout_bsp; pub use self::layout_bsp::*;
|
mod layout_bsp; pub use self::layout_bsp::*;
|
||||||
mod layout_cond; pub use self::layout_cond::*;
|
mod layout_cond; pub use self::layout_cond::*;
|
||||||
|
|
@ -95,4 +83,4 @@ mod layout_padding; pub use self::layout_padding::*;
|
||||||
mod layout_pull; pub use self::layout_pull::*;
|
mod layout_pull; pub use self::layout_pull::*;
|
||||||
mod layout_push; pub use self::layout_push::*;
|
mod layout_push; pub use self::layout_push::*;
|
||||||
mod layout_shrink; pub use self::layout_shrink::*;
|
mod layout_shrink; pub use self::layout_shrink::*;
|
||||||
mod layout_stack; //pub use self::layout_stack::*;
|
mod layout_stack; pub use self::layout_stack::*;
|
||||||
|
|
|
||||||
|
|
@ -32,32 +32,32 @@ use crate::*;
|
||||||
#[derive(Debug, Copy, Clone, Default)]
|
#[derive(Debug, Copy, Clone, Default)]
|
||||||
pub enum Alignment { #[default] Center, X, Y, NW, N, NE, E, SE, S, SW, W }
|
pub enum Alignment { #[default] Center, X, Y, NW, N, NE, E, SE, S, SW, W }
|
||||||
|
|
||||||
pub struct Align<T>(Alignment, T);
|
pub struct Align<A>(Alignment, A);
|
||||||
|
|
||||||
impl<T> Align<T> {
|
impl<A> Align<A> {
|
||||||
#[inline] pub const fn c (a: T) -> Self { Self(Alignment::Center, a) }
|
#[inline] pub const fn c (a: A) -> Self { Self(Alignment::Center, a) }
|
||||||
#[inline] pub const fn x (a: T) -> Self { Self(Alignment::X, a) }
|
#[inline] pub const fn x (a: A) -> Self { Self(Alignment::X, a) }
|
||||||
#[inline] pub const fn y (a: T) -> Self { Self(Alignment::Y, a) }
|
#[inline] pub const fn y (a: A) -> Self { Self(Alignment::Y, a) }
|
||||||
#[inline] pub const fn n (a: T) -> Self { Self(Alignment::N, a) }
|
#[inline] pub const fn n (a: A) -> Self { Self(Alignment::N, a) }
|
||||||
#[inline] pub const fn s (a: T) -> Self { Self(Alignment::S, a) }
|
#[inline] pub const fn s (a: A) -> Self { Self(Alignment::S, a) }
|
||||||
#[inline] pub const fn e (a: T) -> Self { Self(Alignment::E, a) }
|
#[inline] pub const fn e (a: A) -> Self { Self(Alignment::E, a) }
|
||||||
#[inline] pub const fn w (a: T) -> Self { Self(Alignment::W, a) }
|
#[inline] pub const fn w (a: A) -> Self { Self(Alignment::W, a) }
|
||||||
#[inline] pub const fn nw (a: T) -> Self { Self(Alignment::NW, a) }
|
#[inline] pub const fn nw (a: A) -> Self { Self(Alignment::NW, a) }
|
||||||
#[inline] pub const fn sw (a: T) -> Self { Self(Alignment::SW, a) }
|
#[inline] pub const fn sw (a: A) -> Self { Self(Alignment::SW, a) }
|
||||||
#[inline] pub const fn ne (a: T) -> Self { Self(Alignment::NE, a) }
|
#[inline] pub const fn ne (a: A) -> Self { Self(Alignment::NE, a) }
|
||||||
#[inline] pub const fn se (a: T) -> Self { Self(Alignment::SE, a) }
|
#[inline] pub const fn se (a: A) -> Self { Self(Alignment::SE, a) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Out, T: Layout<E>> Layout<E> for Align<T> {
|
impl<E: Out, A: Draw<E>> Draw<E> for Align<A> {
|
||||||
|
fn draw (&self, to: &mut E) {
|
||||||
|
self.1.draw(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<E: Out, A: Layout<E>> Layout<E> for Align<A> {
|
||||||
fn layout (&self, on: E::Area) -> E::Area {
|
fn layout (&self, on: E::Area) -> E::Area {
|
||||||
self.0.align(on, &self.1)
|
self.0.align(on, &self.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<E: Out, T: Draw<E> + Layout<E>> Draw<E> for Align<T> {
|
|
||||||
fn draw (&self, to: &mut E) {
|
|
||||||
to.place_at(self.layout(to.area()), &self.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Alignment {
|
impl Alignment {
|
||||||
fn align <E: Out> (&self, on: E::Area, content: &impl Layout<E>) -> E::Area {
|
fn align <E: Out> (&self, on: E::Area, content: &impl Layout<E>) -> E::Area {
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,26 @@ use crate::*;
|
||||||
use Direction::*;
|
use Direction::*;
|
||||||
|
|
||||||
/// A split or layer.
|
/// A split or layer.
|
||||||
pub struct Bsp<Head, Tail>(
|
pub struct Bsp<A, B>(
|
||||||
pub(crate) Direction,
|
pub(crate) Direction,
|
||||||
/// First element.
|
pub(crate) A,
|
||||||
pub(crate) Head,
|
pub(crate) B,
|
||||||
/// Second element.
|
|
||||||
pub(crate) Tail,
|
|
||||||
);
|
);
|
||||||
|
impl<A, B> Bsp<A, B> {
|
||||||
impl<Head, Tail> Bsp<Head, Tail> {
|
#[inline] pub const fn n (a: A, b: B) -> Self { Self(North, a, b) }
|
||||||
#[inline] pub const fn n (a: Head, b: Tail) -> Self { Self(North, a, b) }
|
#[inline] pub const fn s (a: A, b: B) -> Self { Self(South, a, b) }
|
||||||
#[inline] pub const fn s (a: Head, b: Tail) -> Self { Self(South, a, b) }
|
#[inline] pub const fn e (a: A, b: B) -> Self { Self(East, a, b) }
|
||||||
#[inline] pub const fn e (a: Head, b: Tail) -> Self { Self(East, a, b) }
|
#[inline] pub const fn w (a: A, b: B) -> Self { Self(West, a, b) }
|
||||||
#[inline] pub const fn w (a: Head, b: Tail) -> Self { Self(West, a, b) }
|
#[inline] pub const fn a (a: A, b: B) -> Self { Self(Above, a, b) }
|
||||||
#[inline] pub const fn a (a: Head, b: Tail) -> Self { Self(Above, a, b) }
|
#[inline] pub const fn b (a: A, b: B) -> Self { Self(Below, a, b) }
|
||||||
#[inline] pub const fn b (a: Head, b: Tail) -> Self { Self(Below, a, b) }
|
|
||||||
}
|
}
|
||||||
|
impl<E: Out, A: Layout<E>, B: Layout<E>> Layout<E> for Bsp<A, B> {
|
||||||
impl<
|
fn layout (&self, area: E::Area) -> E::Area {
|
||||||
O: Out,
|
bsp_areas(area, self.0, &self.1, &self.2)[2]
|
||||||
Head: Draw<O> + Layout<O>,
|
}
|
||||||
Tail: Draw<O> + Layout<O>
|
}
|
||||||
> Draw<O> for Bsp<Head, Tail> {
|
impl<E: Out, A: Draw<E> + Layout<E>, B: Draw<E> + Layout<E>> Draw<E> for Bsp<A, B> {
|
||||||
fn draw (&self, to: &mut O) {
|
fn draw (&self, to: &mut E) {
|
||||||
let [a, b, _] = bsp_areas(to.area(), self.0, &self.1, &self.2);
|
let [a, b, _] = bsp_areas(to.area(), self.0, &self.1, &self.2);
|
||||||
if self.0 == Below {
|
if self.0 == Below {
|
||||||
to.place_at(a, &self.1);
|
to.place_at(a, &self.1);
|
||||||
|
|
@ -35,16 +32,9 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn bsp_areas <E: Out> (
|
||||||
impl<O: Out, Head: Layout<O>, Tail: Layout<O>> Layout<O> for Bsp<Head, Tail> {
|
area: E::Area, direction: Direction, a: &impl Layout<E>, b: &impl Layout<E>,
|
||||||
fn layout (&self, area: O::Area) -> O::Area {
|
) -> [E::Area;3] {
|
||||||
bsp_areas(area, self.0, &self.1, &self.2)[2]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bsp_areas <O: Out> (
|
|
||||||
area: O::Area, direction: Direction, a: &impl Layout<O>, b: &impl Layout<O>,
|
|
||||||
) -> [O::Area;3] {
|
|
||||||
let [x, y, w, h] = area.xywh();
|
let [x, y, w, h] = area.xywh();
|
||||||
let [aw, ah] = a.layout(area).wh();
|
let [aw, ah] = a.layout(area).wh();
|
||||||
let [bw, bh] = b.layout(match direction {
|
let [bw, bh] = b.layout(match direction {
|
||||||
|
|
|
||||||
|
|
@ -28,22 +28,20 @@ impl<E: Out, A: Draw<E>> Draw<E> for When<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show one item if a condition is true and another if the condition is false
|
/// Show one item if a condition is true and another if the condition is false
|
||||||
pub struct Either<E: Out, A: Draw<E> + Layout<E>, B: Draw<E> + Layout<E>>(pub bool, pub A, pub B, pub PhantomData<E>);
|
pub struct Either<A, B>(pub bool, pub A, pub B);
|
||||||
impl<E: Out, A: Draw<E> + Layout<E>, B: Draw<E> + Layout<E>> Either<E, A, B> {
|
impl<A, B> Either<A, B> {
|
||||||
/// Create a ternary view condition.
|
/// Create a ternary view condition.
|
||||||
pub const fn new (c: bool, a: A, b: B) -> Self {
|
pub const fn new (c: bool, a: A, b: B) -> Self { Self(c, a, b) }
|
||||||
Self(c, a, b, PhantomData)
|
|
||||||
}
|
}
|
||||||
}
|
impl<E: Out, A: Layout<E>, B: Layout<E>> Layout<E> for Either<A, B> {
|
||||||
impl<E: Out, A: Draw<E> + Layout<E>, B: Draw<E> + Layout<E>> Layout<E> for Either<E, A, B> {
|
|
||||||
fn layout (&self, to: E::Area) -> E::Area {
|
fn layout (&self, to: E::Area) -> E::Area {
|
||||||
let Self(cond, a, b, ..) = self;
|
let Self(cond, a, b) = self;
|
||||||
if *cond { a.layout(to) } else { b.layout(to) }
|
if *cond { a.layout(to) } else { b.layout(to) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<E: Out, A: Draw<E> + Layout<E>, B: Draw<E> + Layout<E>> Draw<E> for Either<E, A, B> {
|
impl<E: Out, A: Draw<E>, B: Draw<E>> Draw<E> for Either<A, B> {
|
||||||
fn draw (&self, to: &mut E) {
|
fn draw (&self, to: &mut E) {
|
||||||
let Self(cond, a, b, ..) = self;
|
let Self(cond, a, b) = self;
|
||||||
if *cond { a.draw(to) } else { b.draw(to) }
|
if *cond { a.draw(to) } else { b.draw(to) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub enum Fill<A> {
|
pub enum Fill<A> {
|
||||||
/// Use maximum width of area.
|
|
||||||
X(A),
|
X(A),
|
||||||
/// Use maximum height of area.
|
|
||||||
Y(A),
|
Y(A),
|
||||||
/// Use maximum width and height of area.
|
|
||||||
XY(A)
|
XY(A)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,25 +28,25 @@ impl<T> Fill<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O>> Draw<O> for Fill<T> {
|
impl<E: Out, T: Draw<E> + Layout<E>> Layout<E> for Fill<T> {
|
||||||
fn draw (&self, to: &mut O) {
|
fn min_w (&self, area: E::Area) -> E::Unit {
|
||||||
to.place_at(self.layout(to.area()), &self.content())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O>> Layout<O> for Fill<T> {
|
|
||||||
fn min_w (&self, area: O::Area) -> O::Unit {
|
|
||||||
if self.has_x() {
|
if self.has_x() {
|
||||||
area.w()
|
area.w()
|
||||||
} else {
|
} else {
|
||||||
0.into()
|
self.content().min_w(area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn min_h (&self, area: O::Area) -> O::Unit {
|
fn min_h (&self, area: E::Area) -> E::Unit {
|
||||||
if self.has_y() {
|
if self.has_y() {
|
||||||
area.h()
|
area.h()
|
||||||
} else {
|
} else {
|
||||||
0.into()
|
self.content().min_h(area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Out, T: Draw<E> + Layout<E>> Draw<E> for Fill<T> {
|
||||||
|
fn draw (&self, to: &mut E) {
|
||||||
|
to.place_at(self.layout(to.area()), &self.content())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,19 +29,25 @@ impl<U: Coordinate, T> Fixed<U, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O>> Draw<O> for Fixed<O::Unit, T> {
|
impl<E: Out, T: Draw<E> + Layout<E>> Draw<E> for Fixed<E::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) {
|
fn draw (&self, to: &mut E) {
|
||||||
let area = Layout::<O>::layout(&self, to.area());
|
to.place_at(self.layout(to.area()), &self.content())
|
||||||
to.place_at(area, &self.content())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: Out, T> Layout<O> for Fixed<O::Unit, T> {
|
impl<E: Out, T: Layout<E>> Layout<E> for Fixed<E::Unit, T> {
|
||||||
fn layout (&self, area: O::Area) -> O::Area {
|
fn layout (&self, area: E::Area) -> E::Area {
|
||||||
[area.x(), area.y(), match self {
|
let [x, y, w, h] = area.xywh();
|
||||||
Fixed::X(w, _) | Fixed::XY(w, _, _) => *w, _ => area.w()
|
let [x, y, w, h] = self.content().layout(match self {
|
||||||
}, match self {
|
Self::X(fw, _) => [x, y, *fw, h],
|
||||||
Fixed::Y(h, _) | Fixed::XY(_, h, _) => *h, _ => area.h()
|
Self::Y(fh, _) => [x, y, w, *fh],
|
||||||
}].into()
|
Self::XY(fw, fh, _) => [x, y, *fw, *fh],
|
||||||
|
}.into()).xywh();
|
||||||
|
let fixed_area = match self {
|
||||||
|
Self::X(fw, _) => [x, y, *fw, h],
|
||||||
|
Self::Y(fh, _) => [x, y, w, *fh],
|
||||||
|
Self::XY(fw, fh, _) => [x, y, *fw, *fh],
|
||||||
|
};
|
||||||
|
fixed_area.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
/// Draws items from an iterator.
|
/// Draws items from an iterator.
|
||||||
pub struct Map<O, A, B, I, F, G>
|
pub struct Map<E, A, B, I, F, G>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = A> + Send + Sync,
|
I: Iterator<Item = A> + Send + Sync,
|
||||||
F: Fn() -> I + Send + Sync,
|
F: Fn() -> I + Send + Sync,
|
||||||
{
|
{
|
||||||
__: PhantomData<(O, B)>,
|
__: PhantomData<(E, B)>,
|
||||||
/// Function that returns iterator over stacked components
|
/// Function that returns iterator over stacked components
|
||||||
get_iter: F,
|
get_iter: F,
|
||||||
/// Function that returns each stacked component
|
/// Function that returns each stacked component
|
||||||
get_item: G,
|
get_item: G,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, O, A, B, I, F, G> Map<O, A, B, I, F, G> where
|
impl<'a, E, A, B, I, F, G> Map<E, A, B, I, F, G> where
|
||||||
I: Iterator<Item = A> + Send + Sync + 'a,
|
I: Iterator<Item = A> + Send + Sync + 'a,
|
||||||
F: Fn() -> I + Send + Sync + 'a,
|
F: Fn() -> I + Send + Sync + 'a,
|
||||||
{
|
{
|
||||||
|
|
@ -27,30 +27,30 @@ impl<'a, O, A, B, I, F, G> Map<O, A, B, I, F, G> where
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_map_direction (($name:ident, $axis:ident, $align:ident)=>{
|
macro_rules! impl_map_direction (($name:ident, $axis:ident, $align:ident)=>{
|
||||||
impl<'a, O, A, B, I, F> Map<
|
impl<'a, E, A, B, I, F> Map<
|
||||||
O, A, Push<O::Unit, Align<Fixed<O::Unit, Fill<B>>>>, I, F, fn(A, usize)->B
|
E, A, Push<E::Unit, Align<Fixed<E::Unit, Fill<B>>>>, I, F, fn(A, usize)->B
|
||||||
> where
|
> where
|
||||||
O: Out,
|
E: Out,
|
||||||
B: Draw<O> + Layout<O>,
|
B: Draw<E>,
|
||||||
I: Iterator<Item = A> + Send + Sync + 'a,
|
I: Iterator<Item = A> + Send + Sync + 'a,
|
||||||
F: Fn() -> I + Send + Sync + 'a
|
F: Fn() -> I + Send + Sync + 'a
|
||||||
{
|
{
|
||||||
pub const fn $name (
|
pub const fn $name (
|
||||||
size: O::Unit,
|
size: E::Unit,
|
||||||
get_iter: F,
|
get_iter: F,
|
||||||
get_item: impl Fn(A, usize)->B + Send + Sync
|
get_item: impl Fn(A, usize)->B + Send + Sync
|
||||||
) -> Map<
|
) -> Map<
|
||||||
O, A,
|
E, A,
|
||||||
Push<O::Unit, Align<Fixed<O::Unit, B>>>,
|
Push<E::Unit, Align<Fixed<E::Unit, B>>>,
|
||||||
I, F,
|
I, F,
|
||||||
impl Fn(A, usize)->Push<O::Unit, Align<Fixed<O::Unit, B>>> + Send + Sync
|
impl Fn(A, usize)->Push<E::Unit, Align<Fixed<E::Unit, B>>> + Send + Sync
|
||||||
> {
|
> {
|
||||||
Map {
|
Map {
|
||||||
__: PhantomData,
|
__: PhantomData,
|
||||||
get_iter,
|
get_iter,
|
||||||
get_item: move |item: A, index: usize|{
|
get_item: move |item: A, index: usize|{
|
||||||
// FIXME: multiply
|
// FIXME: multiply
|
||||||
let mut push: O::Unit = O::Unit::from(0u16);
|
let mut push: E::Unit = E::Unit::from(0u16);
|
||||||
for _ in 0..index {
|
for _ in 0..index {
|
||||||
push = push + size;
|
push = push + size;
|
||||||
}
|
}
|
||||||
|
|
@ -66,14 +66,14 @@ impl_map_direction!(south, y, n);
|
||||||
impl_map_direction!(west, x, e);
|
impl_map_direction!(west, x, e);
|
||||||
impl_map_direction!(north, y, s);
|
impl_map_direction!(north, y, s);
|
||||||
|
|
||||||
impl<'a, O, A, B, I, F, G> Layout<O> for Map<O, A, B, I, F, G> where
|
impl<'a, E, A, B, I, F, G> Layout<E> for Map<E, A, B, I, F, G> where
|
||||||
O: Out,
|
E: Out,
|
||||||
B: Draw<O> + Layout<O>,
|
B: Draw<E> + Layout<E>,
|
||||||
I: Iterator<Item = A> + Send + Sync + 'a,
|
I: Iterator<Item = A> + Send + Sync + 'a,
|
||||||
F: Fn() -> I + Send + Sync + 'a,
|
F: Fn() -> I + Send + Sync + 'a,
|
||||||
G: Fn(A, usize)->B + Send + Sync
|
G: Fn(A, usize)->B + Send + Sync
|
||||||
{
|
{
|
||||||
fn layout (&self, area: O::Area) -> O::Area {
|
fn layout (&self, area: E::Area) -> E::Area {
|
||||||
let Self { get_iter, get_item, .. } = self;
|
let Self { get_iter, get_item, .. } = self;
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
let [mut min_x, mut min_y] = area.center();
|
let [mut min_x, mut min_y] = area.center();
|
||||||
|
|
@ -92,14 +92,14 @@ impl<'a, O, A, B, I, F, G> Layout<O> for Map<O, A, B, I, F, G> where
|
||||||
area.center_xy([w.into(), h.into()].into()).into()
|
area.center_xy([w.into(), h.into()].into()).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, O, A, B, I, F, G> Draw<O> for Map<O, A, B, I, F, G> where
|
impl<'a, E, A, B, I, F, G> Draw<E> for Map<E, A, B, I, F, G> where
|
||||||
O: Out,
|
E: Out,
|
||||||
B: Draw<O> + Layout<O>,
|
B: Draw<E> + Layout<E>,
|
||||||
I: Iterator<Item = A> + Send + Sync + 'a,
|
I: Iterator<Item = A> + Send + Sync + 'a,
|
||||||
F: Fn() -> I + Send + Sync + 'a,
|
F: Fn() -> I + Send + Sync + 'a,
|
||||||
G: Fn(A, usize)->B + Send + Sync
|
G: Fn(A, usize)->B + Send + Sync
|
||||||
{
|
{
|
||||||
fn draw (&self, to: &mut O) {
|
fn draw (&self, to: &mut E) {
|
||||||
let Self { get_iter, get_item, .. } = self;
|
let Self { get_iter, get_item, .. } = self;
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
let area = self.layout(to.area());
|
let area = self.layout(to.area());
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
mod content; pub use self::content::*;
|
mod content; pub use self::content::*;
|
||||||
mod draw; pub use self::draw::*;
|
mod draw; pub use self::draw::*;
|
||||||
mod group; pub use self::group::*;
|
|
||||||
mod layout; pub use self::layout::*;
|
mod layout; pub use self::layout::*;
|
||||||
mod space; pub use self::space::*;
|
mod space; pub use self::space::*;
|
||||||
mod thunk; pub use self::thunk::*;
|
mod thunk; pub use self::thunk::*;
|
||||||
|
|
@ -15,9 +14,11 @@ mod widget; pub use self::widget::*;
|
||||||
pub(crate) use self::Direction::*;
|
pub(crate) use self::Direction::*;
|
||||||
pub(crate) use std::fmt::{Debug, Display};
|
pub(crate) use std::fmt::{Debug, Display};
|
||||||
pub(crate) use std::marker::PhantomData;
|
pub(crate) use std::marker::PhantomData;
|
||||||
pub(crate) use std::ops::{Add, Sub, Mul, Div};
|
pub(crate) use std::ops::{Add, Sub, Mul, Div, Deref};
|
||||||
|
pub(crate) use std::rc::Rc;
|
||||||
pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicUsize, Ordering::Relaxed}};
|
pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicUsize, Ordering::Relaxed}};
|
||||||
pub(crate) use tengri_core::*;
|
pub(crate) use tengri_core::*;
|
||||||
|
#[cfg(feature = "dsl")] pub(crate) use ::tengri_dsl::*;
|
||||||
|
|
||||||
/// Draw target.
|
/// Draw target.
|
||||||
pub trait Out: Send + Sync + Sized {
|
pub trait Out: Send + Sync + Sized {
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,39 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
pub struct Group<T>(T);
|
||||||
|
|
||||||
|
impl<T> Group<T> {
|
||||||
|
pub const fn new () -> Group<()> {
|
||||||
|
Group(())
|
||||||
|
}
|
||||||
|
pub const fn add <U> (self, value: U) -> Group<(T, U)> {
|
||||||
|
Group((self.0, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Lazily-evaluated [Draw]able.
|
/// Lazily-evaluated [Draw]able.
|
||||||
pub struct Lazy<E, T, F>(PhantomData<(E, T)>, F);
|
pub struct Thunk<E: Out, T: Draw<E>, F: Fn()->T>(
|
||||||
impl<E: Out, T: Draw<E> + Layout<E>, F: Fn()->T> Lazy<E, T, F> {
|
PhantomData<E>,
|
||||||
|
F
|
||||||
|
);
|
||||||
|
impl<E: Out, T: Draw<E>, F: Fn()->T> Thunk<E, T, F> {
|
||||||
pub const fn new (thunk: F) -> Self {
|
pub const fn new (thunk: F) -> Self {
|
||||||
Self(PhantomData, thunk)
|
Self(PhantomData, thunk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<E: Out, T: Draw<E> + Layout<E>, F: Fn()->T> Content<E> for Lazy<E, T, F> {
|
impl<E: Out, T: Draw<E> + Layout<E>, F: Fn()->T> Content<E> for Thunk<E, T, F> {
|
||||||
fn content (&self) -> impl Draw<E> + Layout<E> + '_ {
|
fn content (&self) -> impl Draw<E> + Layout<E> + '_ {
|
||||||
(self.1)()
|
(self.1)()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Thunk<E: Out, F: Fn(&mut E)>(PhantomData<E>, F);
|
pub struct ThunkDraw<E: Out, F: Fn(&mut E)>(PhantomData<E>, F);
|
||||||
impl<E: Out, F: Fn(&mut E)> Thunk<E, F> {
|
impl<E: Out, F: Fn(&mut E)> ThunkDraw<E, F> {
|
||||||
pub const fn new (draw: F) -> Self { Self(PhantomData, draw) }
|
pub fn new (render: F) -> Self { Self(PhantomData, render) }
|
||||||
}
|
}
|
||||||
impl<E: Out, F: Fn(&mut E)> Draw<E> for Thunk<E, F> {
|
impl<E: Out, F: Fn(&mut E)> Draw<E> for ThunkDraw<E, F> {
|
||||||
fn draw (&self, to: &mut E) { (self.1)(to) }
|
fn draw (&self, to: &mut E) { (self.1)(to) }
|
||||||
}
|
}
|
||||||
impl<E: Out, F: Fn(&mut E)> Layout<E> for Thunk<E, F> {
|
|
||||||
fn layout (&self, to: E::Area) -> E::Area { to }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)] pub struct Memo<T, U> {
|
#[derive(Debug, Default)] pub struct Memo<T, U> {
|
||||||
pub value: T,
|
pub value: T,
|
||||||
|
|
@ -36,10 +47,10 @@ impl<T: PartialEq, U> Memo<T, U> {
|
||||||
pub fn update <R> (
|
pub fn update <R> (
|
||||||
&mut self,
|
&mut self,
|
||||||
newval: T,
|
newval: T,
|
||||||
draw: impl Fn(&mut U, &T, &T)->R
|
render: impl Fn(&mut U, &T, &T)->R
|
||||||
) -> Option<R> {
|
) -> Option<R> {
|
||||||
if newval != self.value {
|
if newval != self.value {
|
||||||
let result = draw(&mut*self.view.write().unwrap(), &newval, &self.value);
|
let result = render(&mut*self.view.write().unwrap(), &newval, &self.value);
|
||||||
self.value = newval;
|
self.value = newval;
|
||||||
return Some(result);
|
return Some(result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,3 @@ syn = { workspace = true }
|
||||||
quote = { workspace = true }
|
quote = { workspace = true }
|
||||||
proc-macro2 = { workspace = true }
|
proc-macro2 = { workspace = true }
|
||||||
heck = { workspace = true }
|
heck = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")']
|
|
||||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ pub(crate) struct ExposeMeta;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ExposeImpl(ItemImpl, BTreeMap<ExposeType, BTreeMap<String, Ident>>);
|
pub(crate) struct ExposeImpl(ItemImpl, BTreeMap<ExposeType, BTreeMap<String, Ident>>);
|
||||||
|
|
||||||
//#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
//struct ExposeSym(LitStr);
|
struct ExposeSym(LitStr);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct ExposeType(Box<Type>);
|
struct ExposeType(Box<Type>);
|
||||||
|
|
@ -169,33 +169,33 @@ impl ExposeImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl From<LitStr> for ExposeSym { fn from (this: LitStr) -> Self { Self(this) } }
|
impl From<LitStr> for ExposeSym { fn from (this: LitStr) -> Self { Self(this) } }
|
||||||
|
|
||||||
//impl PartialOrd for ExposeSym {
|
impl PartialOrd for ExposeSym {
|
||||||
//fn partial_cmp (&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp (&self, other: &Self) -> Option<Ordering> {
|
||||||
//let this = &self.0;
|
let this = &self.0;
|
||||||
//let that = &other.0;
|
let that = &other.0;
|
||||||
//Some(format!("{}", quote! { #this }).cmp(&format!("{}", quote! { #that })))
|
Some(format!("{}", quote! { #this }).cmp(&format!("{}", quote! { #that })))
|
||||||
//}
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
//impl Ord for ExposeSym {
|
impl Ord for ExposeSym {
|
||||||
//fn cmp (&self, other: &Self) -> Ordering {
|
fn cmp (&self, other: &Self) -> Ordering {
|
||||||
//let this = &self.0;
|
let this = &self.0;
|
||||||
//let that = &other.0;
|
let that = &other.0;
|
||||||
//format!("{}", quote! { #this }).cmp(&format!("{}", quote! { #that }))
|
format!("{}", quote! { #this }).cmp(&format!("{}", quote! { #that }))
|
||||||
//}
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
//impl PartialEq for ExposeSym {
|
impl PartialEq for ExposeSym {
|
||||||
//fn eq (&self, other: &Self) -> bool {
|
fn eq (&self, other: &Self) -> bool {
|
||||||
//let this = &self.0;
|
let this = &self.0;
|
||||||
//let that = &other.0;
|
let that = &other.0;
|
||||||
//format!("{}", quote! { #this }) == format!("{}", quote! { #that })
|
format!("{}", quote! { #this }) == format!("{}", quote! { #that })
|
||||||
//}
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
//impl Eq for ExposeSym {}
|
impl Eq for ExposeSym {}
|
||||||
|
|
||||||
impl From<Type> for ExposeType { fn from (this: Type) -> Self { Self(Box::new(this)) } }
|
impl From<Type> for ExposeType { fn from (this: Type) -> Self { Self(Box::new(this)) } }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
{pkgs?import<nixpkgs>{}}:let
|
{pkgs?import<nixpkgs>{}}:let
|
||||||
stdenv = pkgs.clang19Stdenv;
|
stdenv = pkgs.clang19Stdenv;
|
||||||
name = "tengri";
|
name = "tengri";
|
||||||
nativeBuildInputs = [ pkgs.pkg-config pkgs.libclang pkgs.mold ];
|
nativeBuildInputs = with pkgs; [ pkg-config libclang ];
|
||||||
buildInputs = [ pkgs.libclang ];
|
buildInputs = with pkgs; [ libclang ];
|
||||||
LIBCLANG_PATH = "${pkgs.libclang.lib.outPath}/lib";
|
LIBCLANG_PATH = "${pkgs.libclang.lib.outPath}/lib";
|
||||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [];
|
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (with pkgs; []);
|
||||||
in pkgs.mkShell.override {
|
in pkgs.mkShell.override {
|
||||||
inherit stdenv;
|
inherit stdenv;
|
||||||
} {
|
} {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,3 @@ tengri_tui = { optional = true, path = "../tui" }
|
||||||
tengri_proc = { path = "../proc" }
|
tengri_proc = { path = "../proc" }
|
||||||
tengri = { path = ".", features = [ "dsl" ] }
|
tengri = { path = ".", features = [ "dsl" ] }
|
||||||
crossterm = { workspace = true }
|
crossterm = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")']
|
|
||||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ impl ExampleCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tui_draw!(|self: Example, to|to.place(&self.content()));
|
|
||||||
content!(TuiOut: |self: Example|{
|
content!(TuiOut: |self: Example|{
|
||||||
let index = self.0 + 1;
|
let index = self.0 + 1;
|
||||||
let wh = self.1.wh();
|
let wh = self.1.wh();
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ impl Tui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export] macro_rules! tui_layout ((|$self:ident:$Self:ty, $to:ident|$expr:expr)=>{
|
macro_rules! tui_layout ((|$self:ident:$Self:ty, $to:ident|$expr:expr)=>{
|
||||||
impl Layout<TuiOut> for $Self {
|
impl Layout<TuiOut> for $Self {
|
||||||
fn layout (&$self, $to: [u16;4]) -> [u16;4] {
|
fn layout (&$self, $to: [u16;4]) -> [u16;4] {
|
||||||
$expr
|
$expr
|
||||||
|
|
@ -29,7 +29,7 @@ impl Tui {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
#[macro_export] macro_rules! tui_draw ((|$self:ident:$Self:ty, $to:ident|$expr:expr)=>{
|
macro_rules! tui_draw ((|$self:ident:$Self:ty, $to:ident|$expr:expr)=>{
|
||||||
impl Draw<TuiOut> for $Self {
|
impl Draw<TuiOut> for $Self {
|
||||||
fn draw (&$self, $to: &mut TuiOut) {
|
fn draw (&$self, $to: &mut TuiOut) {
|
||||||
$expr
|
$expr
|
||||||
|
|
@ -38,73 +38,18 @@ impl Tui {
|
||||||
});
|
});
|
||||||
|
|
||||||
mod tui_border; pub use self::tui_border::*;
|
mod tui_border; pub use self::tui_border::*;
|
||||||
mod tui_button; pub use self::tui_button::*;
|
mod tui_button; //pub use self::tui_button::*;
|
||||||
mod tui_color; pub use self::tui_color::*;
|
mod tui_color; pub use self::tui_color::*;
|
||||||
mod tui_error; pub use self::tui_error::*;
|
mod tui_error; pub use self::tui_error::*;
|
||||||
mod tui_field; pub use self::tui_field::*;
|
mod tui_field; pub use self::tui_field::*;
|
||||||
|
mod tui_number; //pub use self::tui_number::*;
|
||||||
mod tui_phat; pub use self::tui_phat::*;
|
mod tui_phat; pub use self::tui_phat::*;
|
||||||
mod tui_repeat; pub use self::tui_repeat::*;
|
mod tui_repeat; pub use self::tui_repeat::*;
|
||||||
mod tui_scroll; pub use self::tui_scroll::*;
|
mod tui_scroll; pub use self::tui_scroll::*;
|
||||||
mod tui_string; pub use self::tui_string::*;
|
mod tui_string; pub use self::tui_string::*;
|
||||||
|
mod tui_style; pub use self::tui_style::*;
|
||||||
mod tui_number; //pub use self::tui_number::*;
|
|
||||||
mod tui_tryptich; //pub use self::tui_tryptich::*;
|
mod tui_tryptich; //pub use self::tui_tryptich::*;
|
||||||
|
|
||||||
pub struct TuiForeground<T>(pub(crate) Foreground<Color, T>);
|
|
||||||
pub struct TuiBackground<T>(pub(crate) Background<Color, T>);
|
|
||||||
pub struct Modify<T>(pub bool, pub Modifier, pub T);
|
|
||||||
pub struct Styled<T>(pub Option<Style>, pub T);
|
|
||||||
|
|
||||||
impl<T: Layout<TuiOut>> Layout<TuiOut> for TuiForeground<T> {
|
|
||||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
|
||||||
self.0.layout(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: Layout<TuiOut> + Draw<TuiOut>> Draw<TuiOut> for TuiForeground<T> {
|
|
||||||
fn draw (&self, to: &mut TuiOut) {
|
|
||||||
let area = self.layout(to.area());
|
|
||||||
to.fill_bg(area, self.0.0);
|
|
||||||
to.place_at(area, &self.0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Layout<TuiOut>> Layout<TuiOut> for TuiBackground<T> {
|
|
||||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
|
||||||
self.0.layout(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: Layout<TuiOut> + Draw<TuiOut>> Draw<TuiOut> for TuiBackground<T> {
|
|
||||||
fn draw (&self, to: &mut TuiOut) {
|
|
||||||
let area = self.layout(to.area());
|
|
||||||
to.fill_bg(area, self.0.0);
|
|
||||||
to.place_at(area, &self.0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Layout<TuiOut>> Layout<TuiOut> for Modify<T> {
|
|
||||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
|
||||||
self.2.layout(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: Draw<TuiOut>> Draw<TuiOut> for Modify<T> {
|
|
||||||
fn draw (&self, to: &mut TuiOut) {
|
|
||||||
to.fill_mod(to.area(), self.0, self.1);
|
|
||||||
self.2.draw(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Layout<TuiOut>> Layout<TuiOut> for Styled<T> {
|
|
||||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
|
||||||
self.1.layout(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: Layout<TuiOut> + Draw<TuiOut>> Draw<TuiOut> for Styled<T> {
|
|
||||||
fn draw (&self, to: &mut TuiOut) {
|
|
||||||
to.place(&self.1);
|
|
||||||
// TODO write style over area
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//impl<T: Draw<TuiOut> + Layout<TuiOut>> Content<TuiOut> for Result<T, Box<dyn std::error::Error>> {
|
//impl<T: Draw<TuiOut> + Layout<TuiOut>> Content<TuiOut> for Result<T, Box<dyn std::error::Error>> {
|
||||||
//fn content (&self) -> impl Draw<TuiOut> + Layout<TuiOut> + '_ {
|
//fn content (&self) -> impl Draw<TuiOut> + Layout<TuiOut> + '_ {
|
||||||
//Bsp::a(self.as_ref().ok(), self.as_ref().err().map(
|
//Bsp::a(self.as_ref().ok(), self.as_ref().err().map(
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1 @@
|
||||||
use crate::{*, Color::*};
|
//use crate::{*, Color::*};
|
||||||
|
|
||||||
pub fn button_2 <'a> (
|
|
||||||
key: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
|
||||||
label: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
|
||||||
editing: bool,
|
|
||||||
) -> impl Draw<TuiOut> + Layout<TuiOut> + 'a {
|
|
||||||
let key = Tui::fg_bg(Tui::orange(), Tui::g(0), Bsp::e(
|
|
||||||
Tui::fg(Tui::g(0), "▐"),
|
|
||||||
Bsp::e(key, Tui::fg(Tui::g(96), "▐"))
|
|
||||||
));
|
|
||||||
let label = When::new(!editing, Tui::fg_bg(Tui::g(255), Tui::g(96), label));
|
|
||||||
Tui::bold(true, Bsp::e(key, label))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn button_3 <'a> (
|
|
||||||
key: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
|
||||||
label: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
|
||||||
value: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
|
||||||
editing: bool,
|
|
||||||
) -> impl Draw<TuiOut> + Layout<TuiOut> + 'a {
|
|
||||||
let key = Tui::fg_bg(Tui::orange(), Tui::g(0),
|
|
||||||
Bsp::e(Tui::fg(Tui::g(0), "▐"), Bsp::e(key, Tui::fg(if editing {
|
|
||||||
Tui::g(128)
|
|
||||||
} else {
|
|
||||||
Tui::g(96)
|
|
||||||
}, "▐"))));
|
|
||||||
let label = Bsp::e(
|
|
||||||
When::new(!editing, Bsp::e(
|
|
||||||
Tui::fg_bg(Tui::g(255), Tui::g(96), label),
|
|
||||||
Tui::fg_bg(Tui::g(128), Tui::g(96), "▐"),
|
|
||||||
)),
|
|
||||||
Bsp::e(
|
|
||||||
Tui::fg_bg(Tui::g(224), Tui::g(128), value),
|
|
||||||
Tui::fg_bg(Tui::g(128), Reset, "▌"),
|
|
||||||
));
|
|
||||||
Tui::bold(true, Bsp::e(key, label))
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@ tui_draw!(|self: &str, to|{
|
||||||
to.text(&self, x, y, w)
|
to.text(&self, x, y, w)
|
||||||
});
|
});
|
||||||
|
|
||||||
tui_layout!(|self: Arc<str>, to|self.as_ref().layout(to));
|
|
||||||
tui_draw!(|self: Arc<str>, to|self.as_ref().draw(to));
|
|
||||||
|
|
||||||
tui_layout!(|self: String, to|self.as_str().layout(to));
|
tui_layout!(|self: String, to|self.as_str().layout(to));
|
||||||
tui_draw!(|self: String, to|self.as_str().draw(to));
|
tui_draw!(|self: String, to|self.as_str().draw(to));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,56 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
pub struct TuiForeground<T>(pub(crate) Foreground<Color, T>);
|
||||||
|
pub struct TuiBackground<T>(pub(crate) Background<Color, T>);
|
||||||
|
pub struct Modify<T>(pub bool, pub Modifier, pub T);
|
||||||
|
pub struct Styled<T>(pub Option<Style>, pub T);
|
||||||
|
|
||||||
|
impl<T: Layout<TuiOut>> Layout<TuiOut> for TuiForeground<T> {
|
||||||
|
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||||
|
self.0.layout(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: Layout<TuiOut> + Draw<TuiOut>> Draw<TuiOut> for TuiForeground<T> {
|
||||||
|
fn draw (&self, to: &mut TuiOut) {
|
||||||
|
let area = self.layout(to.area());
|
||||||
|
to.fill_bg(area, self.0.0);
|
||||||
|
to.place_at(area, &self.0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Layout<TuiOut>> Layout<TuiOut> for TuiBackground<T> {
|
||||||
|
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||||
|
self.0.layout(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: Layout<TuiOut> + Draw<TuiOut>> Draw<TuiOut> for TuiBackground<T> {
|
||||||
|
fn draw (&self, to: &mut TuiOut) {
|
||||||
|
let area = self.layout(to.area());
|
||||||
|
to.fill_bg(area, self.0.0);
|
||||||
|
to.place_at(area, &self.0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Layout<TuiOut>> Layout<TuiOut> for Modify<T> {
|
||||||
|
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||||
|
self.2.layout(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: Draw<TuiOut>> Draw<TuiOut> for Modify<T> {
|
||||||
|
fn draw (&self, to: &mut TuiOut) {
|
||||||
|
to.fill_mod(to.area(), self.0, self.1);
|
||||||
|
self.2.draw(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Layout<TuiOut>> Layout<TuiOut> for Styled<T> {
|
||||||
|
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||||
|
self.1.layout(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: Layout<TuiOut> + Draw<TuiOut>> Draw<TuiOut> for Styled<T> {
|
||||||
|
fn draw (&self, to: &mut TuiOut) {
|
||||||
|
to.place(&self.1);
|
||||||
|
// TODO write style over area
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,11 @@ use crate::*;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::thread::{spawn, JoinHandle};
|
use std::thread::{spawn, JoinHandle};
|
||||||
use unicode_width::*;
|
use unicode_width::*;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TuiOut {
|
pub struct TuiOut {
|
||||||
pub buffer: Buffer,
|
pub buffer: Buffer,
|
||||||
pub area: [u16;4]
|
pub area: [u16;4]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Out for TuiOut {
|
impl Out for TuiOut {
|
||||||
type Unit = u16;
|
type Unit = u16;
|
||||||
type Size = [Self::Unit;2];
|
type Size = [Self::Unit;2];
|
||||||
|
|
@ -26,10 +24,6 @@ impl Out for TuiOut {
|
||||||
*self.area_mut() = last;
|
*self.area_mut() = last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Layout<TuiOut> for fn(&mut TuiOut) {}
|
|
||||||
|
|
||||||
impl TuiOut {
|
impl TuiOut {
|
||||||
/// Spawn the output thread.
|
/// Spawn the output thread.
|
||||||
pub fn run_output <T: Draw<TuiOut> + Send + Sync + 'static> (
|
pub fn run_output <T: Draw<TuiOut> + Send + Sync + 'static> (
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue