mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: big flat pt.11, down to 12, update literal render macro
This commit is contained in:
parent
a0175dabc8
commit
b718e54d33
9 changed files with 302 additions and 239 deletions
|
|
@ -11,27 +11,88 @@ pub trait Output<E: Engine> {
|
|||
fn render_in (&mut self, area: E::Area, widget: &impl Render<E>) -> Usually<()>;
|
||||
}
|
||||
|
||||
/// Something that can be represented by a renderable component.
|
||||
pub trait Content<E: Engine>: Send + Sync {
|
||||
fn content (&self) -> Option<impl Render<E>>;
|
||||
}
|
||||
impl<E: Engine, C: Content<E>> Content<E> for &C {
|
||||
fn content (&self) -> Option<impl Render<E>> {
|
||||
(*self).content()
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that writes to an [Output].
|
||||
pub trait Render<E: Engine>: Send + Sync {
|
||||
/// Minimum size to use
|
||||
fn min_size (&self, _: E::Size) -> Perhaps<E::Size> {
|
||||
Ok(None)
|
||||
}
|
||||
/// Draw to output render target
|
||||
fn render (&self, _: &mut E::Output) -> Usually<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
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, 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, R: Render<E>> Render<E> for Option<R> {
|
||||
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
if let Some(content) = self {
|
||||
content.min_size(to)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
if let Some(content) = self {
|
||||
content.render(to)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Define custom content for a struct.
|
||||
///
|
||||
/// This code wires the `Content` and `Render` traits together,
|
||||
/// since the only way to have the cake and eat it too is by
|
||||
/// implementing both traits for a given renderable.
|
||||
#[macro_export] macro_rules! render {
|
||||
|
||||
// Implement for all engines
|
||||
// Implement from [Content] for all [Engine]s
|
||||
(|$self:ident:$Struct:ident$(<$($L:lifetime),*E$(,$T:ident$(:$U:path)?)*$(,)?>)?|$cb:expr) => {
|
||||
impl<E: Engine, $($($L),*$($T $(: $U)?),*)?> Content<E> for $Struct $(<$($L,)* E, $($T),*>)? {
|
||||
fn content (&$self) -> Option<impl Render<$E>> {
|
||||
Some($cb)
|
||||
}
|
||||
fn content (&$self) -> Option<impl Render<$E>> { Some($cb) }
|
||||
}
|
||||
impl<E: Engine, $($($L),*$($T $(: $U)?),*)?> Render<E> for $Struct $(<$($L,)* E, $($T),*>)? {
|
||||
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
self.content().map(|content|content.min_size(to)).unwrap_or(Ok(None))
|
||||
self.content().unwrap().min_size(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
self.content().map(|content|content.render(to)).unwrap_or(Ok(()))
|
||||
self.content().unwrap().render(to)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Implement for a specific engine
|
||||
// Implement from [min_size] and [render] callbacks for all engines
|
||||
($Struct:ident$(<$($L:lifetime),*E$(,$T:ident$(:$U:path)?)*$(,)?>)?
|
||||
|$self1:ident, $to1:ident|$min_size:expr,
|
||||
|$self2:ident, $to2:ident|$render:expr) =>
|
||||
{
|
||||
impl<E: Engine, $($($L),*$($T $(: $U)?),*)?> Content<E> for $Struct $(<$($L,)* E, $($T),*>)? {
|
||||
fn content (&self) -> Option<impl Render<E>> { Some(self) }
|
||||
}
|
||||
impl<E: Engine, $($($L),*$($T $(: $U)?),*)?> Render<E> for $Struct $(<$($L,)* E, $($T),*>)? {
|
||||
fn min_size (&$self1, $to1: E::Size) -> Perhaps<E::Size> { $min_size }
|
||||
fn render (&$self2, $to2: &mut E::Output) -> Usually<()> { $render }
|
||||
}
|
||||
};
|
||||
|
||||
// Implement from [Content] for a particular [Engine]
|
||||
(<$E:ty>|$self:ident:$Struct:ident$(<
|
||||
$($($L:lifetime),+)?
|
||||
$($($T:ident$(:$U:path)?),+)?
|
||||
|
|
@ -61,45 +122,35 @@ pub trait Output<E: Engine> {
|
|||
self.content().map(|content|content.render(to)).unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Implement from [min_size] and [render] callbacks for a particular [Engine]
|
||||
(<$E:ty>($self:ident:$Struct:ident$(<$($L:lifetime),*$(,$T:ident$(:$U:path)?)*$(,)?>)?)
|
||||
|$to1:ident|$min_size:expr, |$to2:ident|$render:expr) =>
|
||||
{
|
||||
impl $(<
|
||||
$($L),* $($($T$(:$U)?),+)?
|
||||
>)? Content<$E> for $Struct $(<
|
||||
$($L),* $($($T),+)?
|
||||
>)? {
|
||||
fn content (&self) -> Option<impl Render<$E>> { Some(self) }
|
||||
}
|
||||
impl $(<
|
||||
$($L),* $($($T$(:$U)?),+)?
|
||||
>)? Render<$E> for $Struct $(<
|
||||
$($L),* $($($T),+)?
|
||||
>)? {
|
||||
fn min_size (&$self, $to1: <$E as Engine>::Size) -> Perhaps<<$E as Engine>::Size> {
|
||||
$min_size
|
||||
}
|
||||
fn render (&$self, $to2: &mut <$E as Engine>::Output) -> Usually<()> {
|
||||
$render
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Write content to output buffer.
|
||||
pub trait Render<E: Engine>: Send + Sync {
|
||||
/// Minimum size to use
|
||||
fn min_size (&self, _: E::Size) -> Perhaps<E::Size> {
|
||||
Ok(None)
|
||||
}
|
||||
/// Draw to output render target
|
||||
fn render (&self, _: &mut E::Output) -> Usually<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> Render<E> for &dyn Render<E> {}
|
||||
//impl<E: Engine> Render<E> for &mut dyn Render<E> {}
|
||||
//impl<E: Engine> Render<E> for Box<dyn Render<E>> {}
|
||||
impl<E: Engine, R: Render<E>> Render<E> for &R {}
|
||||
//impl<E: Engine, R: Render<E>> Render<E> for &mut R {}
|
||||
impl<E: Engine, R: Render<E>> Render<E> for Option<R> {}
|
||||
//impl<E: Engine, R: Render<E>> Render<E> for Arc<R> {}
|
||||
//impl<E: Engine, R: Render<E>> Render<E> for Mutex<R> {}
|
||||
//impl<E: Engine, R: Render<E>> Render<E> for RwLock<R> {}
|
||||
|
||||
/// Something that can be represented by a renderable component.
|
||||
pub trait Content<E: Engine>: Send + Sync {
|
||||
fn content (&self) -> Option<impl Render<E>>;
|
||||
}
|
||||
|
||||
//impl<E: Engine> Content<E> for &dyn Render<E> {}
|
||||
//impl<E: Engine> Content<E> for &mut dyn Render<E> {}
|
||||
//impl<E: Engine> Content<E> for Box<dyn Render<E>> {}
|
||||
impl<E: Engine, C: Content<E>> Content<E> for &C {
|
||||
fn content (&self) -> Option<impl Render<E>> {
|
||||
(*self).content()
|
||||
}
|
||||
}
|
||||
//impl<E: Engine, C: Content<E>> Content<E> for &mut C {}
|
||||
//impl<E: Engine, C: Content<E>> Content<E> for Option<C> {}
|
||||
//impl<E: Engine, C: Content<E>> Content<E> for Arc<C> {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue