mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-04-30 22:30:13 +02:00
161 lines
4.7 KiB
Rust
161 lines
4.7 KiB
Rust
use crate::*;
|
|
|
|
#[macro_export] macro_rules! render {
|
|
(|$self:ident:$Struct:ident$(<$($L:lifetime),*E$(,$T:ident$(:$U:path)?)*$(,)?>)?|$cb:expr) => {
|
|
impl<E: Engine, $($($L),*$($T $(: $U)?),*)?> Render<E> for $Struct $(<$($L,)* E, $($T),*>)? {
|
|
fn min_size (&$self, to: <E as Engine>::Size) -> Perhaps<<E as Engine>::Size> {
|
|
$cb.min_size(to)
|
|
}
|
|
fn render (&$self, to: &mut <E as Engine>::Output) -> Usually<()> {
|
|
$cb.render(to)
|
|
}
|
|
}
|
|
};
|
|
(<$E:ty>|$self:ident:$Struct:ident$(<
|
|
$($($L:lifetime),+)?
|
|
$($($T:ident$(:$U:path)?),+)?
|
|
>)?|$cb:expr) => {
|
|
impl $(<
|
|
$($($L),+)?
|
|
$($($T$(:$U)?),+)?
|
|
>)? Render<$E> for $Struct $(<
|
|
$($($L),+)?
|
|
$($($T),+)?
|
|
>)? {
|
|
fn min_size (&$self, to: <$E as Engine>::Size) -> Perhaps<<$E as Engine>::Size> {
|
|
$cb.min_size(to)
|
|
}
|
|
fn render (&$self, to: &mut <$E as Engine>::Output) -> Usually<()> {
|
|
$cb.render(to)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Rendering target
|
|
pub trait Output<E: Engine> {
|
|
/// Current output area
|
|
fn area (&self) -> E::Area;
|
|
/// Mutable pointer to area
|
|
fn area_mut (&mut self) -> &mut E::Area;
|
|
/// Render widget in area
|
|
fn render_in (&mut self, area: E::Area, widget: &dyn Render<E>) -> Usually<()>;
|
|
}
|
|
|
|
/// Cast to dynamic pointer
|
|
pub fn widget <E: Engine, T: Render<E>> (w: &T) -> &dyn Render<E> {
|
|
w as &dyn Render<E>
|
|
}
|
|
|
|
/// A renderable component
|
|
pub trait Render<E: Engine>: Send + Sync {
|
|
/// Minimum size to use
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
Ok(Some(to))
|
|
}
|
|
/// Draw to output render target
|
|
fn render (&self, to: &mut E::Output) -> Usually<()>;
|
|
}
|
|
|
|
impl<E: Engine, R: Render<E>> Render<E> for &R {
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
(*self).min_size(to)
|
|
}
|
|
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
(*self).render(to)
|
|
}
|
|
}
|
|
|
|
impl<E: Engine> Render<E> for &dyn Render<E> {
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
(*self).min_size(to)
|
|
}
|
|
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
(*self).render(to)
|
|
}
|
|
}
|
|
|
|
//impl<E: Engine> Render<E> for &mut dyn Render<E> {
|
|
//fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
//(*self).min_size(to)
|
|
//}
|
|
//fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
//(*self).render(to)
|
|
//}
|
|
//}
|
|
|
|
impl<E: Engine> Render<E> for Box<dyn Render<E> + '_> {
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
(**self).min_size(to)
|
|
}
|
|
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
(**self).render(to)
|
|
}
|
|
}
|
|
|
|
impl<E: Engine, W: Render<E>> Render<E> for Arc<W> {
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
self.as_ref().min_size(to)
|
|
}
|
|
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
self.as_ref().render(to)
|
|
}
|
|
}
|
|
|
|
impl<E: Engine, W: Render<E>> Render<E> for Mutex<W> {
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
self.lock().unwrap().min_size(to)
|
|
}
|
|
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
self.lock().unwrap().render(to)
|
|
}
|
|
}
|
|
|
|
impl<E: Engine, W: Render<E>> Render<E> for RwLock<W> {
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
self.read().unwrap().min_size(to)
|
|
}
|
|
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
self.read().unwrap().render(to)
|
|
}
|
|
}
|
|
|
|
impl<E: Engine, W: Render<E>> Render<E> for Option<W> {
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
Ok(self.as_ref().map(|widget|widget.min_size(to)).transpose()?.flatten())
|
|
}
|
|
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
self.as_ref().map(|widget|widget.render(to)).unwrap_or(Ok(()))
|
|
}
|
|
}
|
|
|
|
/// A custom [Render] defined by passing layout and render closures in place.
|
|
pub struct Widget<
|
|
E: Engine,
|
|
L: Send + Sync + Fn(E::Size)->Perhaps<E::Size>,
|
|
R: Send + Sync + Fn(&mut E::Output)->Usually<()>
|
|
>(L, R, PhantomData<E>);
|
|
|
|
impl<
|
|
E: Engine,
|
|
L: Send + Sync + Fn(E::Size)->Perhaps<E::Size>,
|
|
R: Send + Sync + Fn(&mut E::Output)->Usually<()>
|
|
> Widget<E, L, R> {
|
|
pub fn new (layout: L, render: R) -> Self {
|
|
Self(layout, render, Default::default())
|
|
}
|
|
}
|
|
|
|
impl<
|
|
E: Engine,
|
|
L: Send + Sync + Fn(E::Size)->Perhaps<E::Size>,
|
|
R: Send + Sync + Fn(&mut E::Output)->Usually<()>
|
|
> Render<E> for Widget<E, L, R> {
|
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
|
self.0(to)
|
|
}
|
|
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
|
self.1(to)
|
|
}
|
|
}
|