wip: impl_draw, optional drawing

This commit is contained in:
facile pop culture reference 2026-07-06 05:35:48 +03:00
parent 0b9e9c0696
commit bf16288884
12 changed files with 213 additions and 229 deletions

View file

@ -35,11 +35,18 @@ pub trait Screen: Xy<Self::Unit> + Wh<Self::Unit> + Send + Sync + Sized {
/// todo!("your draw logic")
/// });
/// ```
#[macro_export] macro_rules! impl_draw ((|
$self:ident:$Self:ty, $to:ident:$To:ty
|$draw:block)=>{ impl Draw<$To> for $Self {
fn draw ($self, $to: &mut $To) -> Usually<XYWH<<$To as Screen>::Unit>> $draw
} });
#[macro_export] macro_rules! impl_draw (
($(<$($T:ident: $Trait:path,)+>)?|
$self:ident:$Self:path, $to:ident:$To:ty
|$draw:block)=>{ impl$(<$($T:$Trait),+>)? Draw<$To> for $Self {
fn draw ($self, $to: &mut $To) -> Perhaps<XYWH<<$To as Screen>::Unit>> $draw
} };
($(<$($T:ident: $Trait:path,)+>)?|
$self:ident:$Self:ty, $to:ident:$To:ty
|$draw:block)=>{ impl$(<$($T:$Trait),+>)? Draw<$To> for $Self {
fn draw ($self, $to: &mut $To) -> Perhaps<XYWH<<$To as Screen>::Unit>> $draw
} }
);
/// Drawable that supports dynamic dispatch.
///
@ -57,38 +64,36 @@ pub trait Screen: Xy<Self::Unit> + Wh<Self::Unit> + Send + Sync + Sized {
/// use tengri::{*, draw::*, term::*};
/// struct MyWidget(bool);
/// impl Draw<Tui> for MyWidget {
/// fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
/// fn draw (self, to: &mut Tui) -> Perhaps<XYWH<u16>> {
/// todo!("your draw logic")
/// }
/// }
/// ```
pub trait Draw<S: Screen> {
fn draw (self, to: &mut S) -> Usually<XYWH<S::Unit>>;
fn draw (self, to: &mut S) -> Perhaps<XYWH<S::Unit>>;
fn layout (&self, area: XYWH<S::Unit>) -> Perhaps<XYWH<S::Unit>> {
Ok(Some(area))
}
}
impl<S: Screen> Draw<S> for () {
fn draw (self, __: &mut S) -> Usually<XYWH<S::Unit>> {
Ok(Default::default())
fn draw (self, _: &mut S) -> Perhaps<XYWH<S::Unit>> {
Ok(None)
}
}
impl<S: Screen, D: Draw<S>> Draw<S> for Option<D> {
fn draw (self, to: &mut S) -> Usually<XYWH<S::Unit>> {
self.map(|it|it.draw(to)).transpose().map(Option::unwrap_or_default)
}
}
impl_draw!(<S: Screen, D: Draw<S>,>|self: Option<D>, to: S|{
self.map(|it|it.draw(to)).transpose().map(Option::unwrap_or_default)
});
//impl<S: Screen, D: Draw<S>> Draw<S> for RwLock<D> {
//fn draw (self, __: &mut S) -> Usually<XYWH<S::Unit>> {
//fn draw (self, __: &mut S) -> Perhaps<XYWH<S::Unit>> {
//todo!()
//}
//}
//impl<T: Screen, D: Draw<T>> Draw<T> for Arc<D> {
//fn draw (self, __: &mut T) -> Usually<XYWH<T::Unit>> {
//fn draw (self, __: &mut T) -> Perhaps<XYWH<T::Unit>> {
//todo!()
//}
//}
@ -101,19 +106,19 @@ pub trait View<T: Screen> {
}
impl<T: Screen, V: View<T>> Draw<T> for &V {
fn draw (self, to: &mut T) -> Usually<XYWH<T::Unit>> {
fn draw (self, to: &mut T) -> Perhaps<XYWH<T::Unit>> {
self.view().draw(to)
}
}
/// Because we can't implement [Draw] for `F: FnOnce...` without conflicts.
pub struct Thunk<T: Screen, F: FnOnce(&mut T)->Usually<XYWH<T::Unit>>>(
pub struct Thunk<T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>>(
pub F,
std::marker::PhantomData<T>
);
impl<T: Screen, F: FnOnce(&mut T)->Usually<XYWH<T::Unit>>> Draw<T> for Thunk<T, F> {
fn draw (self, to: &mut T) -> Usually<XYWH<T::Unit>> {
impl<T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> Draw<T> for Thunk<T, F> {
fn draw (self, to: &mut T) -> Perhaps<XYWH<T::Unit>> {
(self.0)(to)
}
}
@ -126,7 +131,7 @@ impl<T: Screen, F: FnOnce(&mut T)->Usually<XYWH<T::Unit>>> Draw<T> for Thunk<T,
/// thunk(|to: &mut Tui|Ok(to.1))
/// # }
/// ```
pub const fn thunk <T: Screen, F: FnOnce(&mut T)->Usually<XYWH<T::Unit>>> (
pub const fn thunk <T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> (
draw: F
) -> Thunk<T, F> {
Thunk(draw, std::marker::PhantomData)