mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-07-17 07:56:56 +02:00
144 lines
3.7 KiB
Rust
144 lines
3.7 KiB
Rust
use crate::*;
|
|
|
|
/// Output target.
|
|
///
|
|
/// ```
|
|
/// use tengri::*;
|
|
/// struct TestOut { w: u16, h: u16 };
|
|
/// impl Wide<u16> for TestOut {}
|
|
/// impl Tall<u16> for TestOut {}
|
|
/// impl Xy<u16> for TestOut { fn x (&self) -> u16 { 0 } fn y (&self) -> u16 { 0 } }
|
|
/// impl Screen for TestOut {
|
|
/// type Unit = u16;
|
|
/// fn show <D: Draw<Self>> (&mut self, _: D) -> Drawn<u16> {
|
|
/// println!("placed");
|
|
/// Ok(None)
|
|
/// }
|
|
/// }
|
|
///
|
|
/// impl_draw!(|self: String, to: TestOut|{
|
|
/// to.w = self.len() as u16;
|
|
/// Ok(None)
|
|
/// });
|
|
/// ```
|
|
pub trait Screen: Xy<Self::Unit> + Wh<Self::Unit> + Send + Sync + Sized {
|
|
type Unit: Coord;
|
|
/// Render drawable in subarea specified by `area`
|
|
fn show (&mut self, content: impl Draw<Self>) -> Perhaps<XYWH<Self::Unit>>;
|
|
/// Get current clipping area
|
|
fn area (&self) -> XYWH<Self::Unit>;
|
|
/// Set clipping area
|
|
fn clip <T> (
|
|
&mut self,
|
|
area: impl Into<Option<XYWH<Self::Unit>>>,
|
|
draw: impl FnOnce(&mut Self)->T
|
|
) -> T;
|
|
}
|
|
|
|
/// Implement the [Draw] trait for a particular drawable and [Screen].
|
|
///
|
|
/// ```
|
|
/// use tengri::*;
|
|
/// struct MyDrawable;
|
|
/// impl_draw!(|self: MyDrawable, to: Tui|{
|
|
/// todo!("your draw logic")
|
|
/// });
|
|
/// ```
|
|
#[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.
|
|
///
|
|
/// Drawables are composable, e.g. the [when] and [either] conditionals
|
|
/// or the layout constraints.
|
|
///
|
|
/// Drawables are consumable, i.e. the [Draw::draw] method receives an
|
|
/// owned `self` and does not return it, consuming the drawable.
|
|
///
|
|
/// To draw a thing multiple times, instead of explicitly constructing it
|
|
/// every time, implement the [View] trait instead, which will construct
|
|
/// a [Draw]able.
|
|
///
|
|
/// ```
|
|
/// use tengri::*;
|
|
/// struct MyWidget(bool);
|
|
/// impl Draw<Tui> for MyWidget {
|
|
/// fn draw (self, to: &mut Tui) -> Perhaps<XYWH<u16>> {
|
|
/// todo!("your draw logic")
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
pub trait Draw<S: Screen> {
|
|
fn draw (self, to: &mut S) -> Drawn<S::Unit>;
|
|
fn layout (&self, area: XYWH<S::Unit>) -> Drawn<S::Unit> {
|
|
Ok(Some(area))
|
|
}
|
|
}
|
|
|
|
pub type Drawn<U> = Perhaps<XYWH<U>>;
|
|
|
|
impl<S: Screen> Draw<S> for () {
|
|
fn draw (self, _: &mut S) -> Drawn<S::Unit> {
|
|
Ok(None)
|
|
}
|
|
}
|
|
|
|
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) -> Drawn<S::Unit> {
|
|
//todo!()
|
|
//}
|
|
//}
|
|
|
|
//impl<T: Screen, D: Draw<T>> Draw<T> for Arc<D> {
|
|
//fn draw (self, __: &mut T) -> Perhaps<XYWH<T::Unit>> {
|
|
//todo!()
|
|
//}
|
|
//}
|
|
|
|
/// Emit a [Draw]able.
|
|
///
|
|
/// Speculative. How to avoid conflicts with [Draw] proper?
|
|
pub trait View<T: Screen> {
|
|
fn view (&self) -> impl Draw<T>;
|
|
}
|
|
|
|
impl<T: Screen> View<T> for () {
|
|
fn view (&self) -> impl Draw<T> {
|
|
()
|
|
}
|
|
}
|
|
|
|
impl<T: Screen, V: View<T>> Draw<T> for &V {
|
|
fn draw (self, to: &mut T) -> Perhaps<XYWH<T::Unit>> {
|
|
self.view().draw(to)
|
|
}
|
|
}
|
|
|
|
features! {
|
|
"draw": [
|
|
color,
|
|
coord,
|
|
iter,
|
|
layout,
|
|
lrtb,
|
|
sizer,
|
|
space,
|
|
split,
|
|
thunk,
|
|
xywh
|
|
]
|
|
}
|