mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 11:46:42 +01:00
uuugh
This commit is contained in:
parent
ca862b9802
commit
90fc869e14
42 changed files with 645 additions and 1158 deletions
|
|
@ -1,40 +1,111 @@
|
|||
use crate::*;
|
||||
|
||||
/// Composable renderable with static dispatch.
|
||||
pub trait Content<E: Out>: Sized {
|
||||
/// Return opaque [Draw]able.
|
||||
fn content (&self) -> impl Draw<E> + Layout<E> + '_ { () }
|
||||
}
|
||||
|
||||
/// The platonic ideal unit of [Content]:
|
||||
/// total emptiness at dead center (e=1vg^sqrt(-1))
|
||||
impl<E: Out> Content<E> for () {}
|
||||
|
||||
impl<E: Out, T: Draw<E> + Layout<E>> Content<E> for fn()->T {
|
||||
fn content (&self) -> impl Draw<E> + Layout<E> + '_ {
|
||||
self()
|
||||
pub trait HasContent<O: Out> { fn content (&self) -> impl Content<O>; }
|
||||
pub trait Content<O: Out>: Draw<O> + Layout<O> {}
|
||||
impl<O: Out, T: Draw<O> + Layout<O>> Content<O> for T {}
|
||||
impl<'a, O: Out> AsRef<dyn Draw<O> + 'a> for dyn Content<O> + 'a { fn as_ref (&self) -> &(dyn Draw<O> + 'a) { self } }
|
||||
impl<'a, O: Out> AsRef<dyn Layout<O> + 'a> for dyn Content<O> + 'a { fn as_ref (&self) -> &(dyn Layout<O> + 'a) { self } }
|
||||
/// Drawable with dynamic dispatch.
|
||||
pub trait Draw<O: Out> { fn draw (&self, to: &mut O); }
|
||||
impl<O: Out> Draw<O> for () { fn draw (&self, to: &mut O) {} }
|
||||
impl<O: Out> Draw<O> for fn(&mut O) { fn draw (&self, to: &mut O) { (*self)(to) } }
|
||||
impl<O: Out> Draw<O> for Box<dyn Draw<O>> { fn draw (&self, to: &mut O) { (**self).draw(to) } }
|
||||
impl<O: Out, D: Draw<O>> Draw<O> for &D { fn draw (&self, to: &mut O) { (*self).draw(to) } }
|
||||
impl<O: Out, D: Draw<O>> Draw<O> for &mut D { fn draw (&self, to: &mut O) { (**self).draw(to) } }
|
||||
impl<O: Out, D: Draw<O>> Draw<O> for Option<D> { fn draw (&self, to: &mut O) { if let Some(draw) = self { draw.draw(to) } } }
|
||||
/// Drawable area of display.
|
||||
pub trait Layout<O: Out> {
|
||||
fn x (&self, to: O::Area) -> O::Unit { to.x() }
|
||||
fn y (&self, to: O::Area) -> O::Unit { to.y() }
|
||||
fn min_w (&self, to: O::Area) -> O::Unit { 0.into() }
|
||||
fn max_w (&self, to: O::Area) -> O::Unit { to.w() }
|
||||
fn w (&self, to: O::Area) -> O::Unit {
|
||||
to.w().max(self.min_w(to)).min(self.max_w(to))
|
||||
}
|
||||
fn min_h (&self, to: O::Area) -> O::Unit { 0.into() }
|
||||
fn max_h (&self, to: O::Area) -> O::Unit { to.h() }
|
||||
fn h (&self, to: O::Area) -> O::Unit {
|
||||
to.h().max(self.min_h(to)).min(self.max_h(to))
|
||||
}
|
||||
fn layout (&self, to: O::Area) -> O::Area {
|
||||
[self.x(to), self.y(to), self.w(to), self.h(to)].into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement composable content for a struct.
|
||||
#[macro_export] macro_rules! content {
|
||||
|
||||
// Implement for all [Out]s.
|
||||
(|$self:ident:$Struct:ty| $content:expr) => {
|
||||
impl<E: Out> Content<E> for $Struct {
|
||||
fn content (&$self) -> impl Draw<E> + Layout<E> + '_ { Some($content) }
|
||||
}
|
||||
};
|
||||
|
||||
// Implement for specific [Out].
|
||||
($Out:ty:|
|
||||
$self:ident:
|
||||
$Struct:ident$(<$($($L:lifetime)? $($T:ident)? $(:$Trait:path)?),+>)?
|
||||
|$content:expr) => {
|
||||
impl $(<$($($L)? $($T)? $(:$Trait)?),+>)? Content<$Out>
|
||||
for $Struct $(<$($($L)? $($T)?),+>)? {
|
||||
fn content (&$self) -> impl Draw<$Out> + Layout<$Out> + '_ { $content }
|
||||
}
|
||||
};
|
||||
|
||||
impl<O: Out> Layout<O> for () {
|
||||
fn x (&self, a: O::Area) -> O::Unit { a.x() }
|
||||
fn y (&self, a: O::Area) -> O::Unit { a.y() }
|
||||
fn w (&self, _: O::Area) -> O::Unit { 0.into() }
|
||||
fn min_w (&self, _: O::Area) -> O::Unit { 0.into() }
|
||||
fn max_w (&self, _: O::Area) -> O::Unit { 0.into() }
|
||||
fn h (&self, _: O::Area) -> O::Unit { 0.into() }
|
||||
fn min_h (&self, _: O::Area) -> O::Unit { 0.into() }
|
||||
fn max_h (&self, _: O::Area) -> O::Unit { 0.into() }
|
||||
fn layout (&self, a: O::Area) -> O::Area { [a.x(), a.y(), 0.into(), 0.into()].into() }
|
||||
}
|
||||
|
||||
impl<O: Out, L: Layout<O>> Layout<O> for &L {
|
||||
fn x (&self, a: O::Area) -> O::Unit { (*self).x(a) }
|
||||
fn y (&self, a: O::Area) -> O::Unit { (*self).y(a) }
|
||||
fn w (&self, a: O::Area) -> O::Unit { (*self).w(a) }
|
||||
fn min_w (&self, a: O::Area) -> O::Unit { (*self).min_w(a) }
|
||||
fn max_w (&self, a: O::Area) -> O::Unit { (*self).max_w(a) }
|
||||
fn h (&self, a: O::Area) -> O::Unit { (*self).h(a) }
|
||||
fn min_h (&self, a: O::Area) -> O::Unit { (*self).min_h(a) }
|
||||
fn max_h (&self, a: O::Area) -> O::Unit { (*self).max_h(a) }
|
||||
fn layout (&self, a: O::Area) -> O::Area { (*self).layout(a) }
|
||||
}
|
||||
|
||||
impl<O: Out, L: Layout<O>> Layout<O> for &mut L {
|
||||
fn x (&self, a: O::Area) -> O::Unit { (**self).x(a) }
|
||||
fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) }
|
||||
fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) }
|
||||
fn min_w (&self, a: O::Area) -> O::Unit { (**self).min_w(a) }
|
||||
fn max_w (&self, a: O::Area) -> O::Unit { (**self).max_w(a) }
|
||||
fn h (&self, a: O::Area) -> O::Unit { (**self).h(a) }
|
||||
fn min_h (&self, a: O::Area) -> O::Unit { (**self).min_h(a) }
|
||||
fn max_h (&self, a: O::Area) -> O::Unit { (**self).max_h(a) }
|
||||
fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) }
|
||||
}
|
||||
|
||||
impl<O: Out> Layout<O> for Box<dyn Layout<O>> {
|
||||
fn x (&self, a: O::Area) -> O::Unit { (**self).x(a) }
|
||||
fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) }
|
||||
fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) }
|
||||
fn min_w (&self, a: O::Area) -> O::Unit { (**self).min_w(a) }
|
||||
fn max_w (&self, a: O::Area) -> O::Unit { (**self).max_w(a) }
|
||||
fn h (&self, a: O::Area) -> O::Unit { (**self).h(a) }
|
||||
fn min_h (&self, a: O::Area) -> O::Unit { (**self).min_h(a) }
|
||||
fn max_h (&self, a: O::Area) -> O::Unit { (**self).max_h(a) }
|
||||
fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) }
|
||||
}
|
||||
|
||||
impl<O: Out, L: Layout<O>> Layout<O> for Option<L> {
|
||||
fn x (&self, to: O::Area) -> O::Unit {
|
||||
self.as_ref().map(|c|c.x(to)).unwrap_or(to.x())
|
||||
}
|
||||
fn y (&self, to: O::Area) -> O::Unit {
|
||||
self.as_ref().map(|c|c.y(to)).unwrap_or(to.y())
|
||||
}
|
||||
fn min_w (&self, to: O::Area) -> O::Unit {
|
||||
self.as_ref().map(|c|c.min_w(to)).unwrap_or(0.into())
|
||||
}
|
||||
fn max_w (&self, to: O::Area) -> O::Unit {
|
||||
self.as_ref().map(|c|c.max_w(to)).unwrap_or(0.into())
|
||||
}
|
||||
fn w (&self, to: O::Area) -> O::Unit {
|
||||
self.as_ref().map(|c|c.w(to)).unwrap_or(0.into())
|
||||
}
|
||||
fn min_h (&self, to: O::Area) -> O::Unit {
|
||||
self.as_ref().map(|c|c.min_h(to)).unwrap_or(0.into())
|
||||
}
|
||||
fn max_h (&self, to: O::Area) -> O::Unit {
|
||||
self.as_ref().map(|c|c.max_h(to)).unwrap_or(0.into())
|
||||
}
|
||||
fn h (&self, to: O::Area) -> O::Unit {
|
||||
self.as_ref().map(|c|c.h(to)).unwrap_or(0.into())
|
||||
}
|
||||
fn layout (&self, to: O::Area) -> O::Area {
|
||||
self.as_ref().map(|c|c.layout([self.x(to), self.y(to), self.w(to), self.h(to)].into()))
|
||||
.unwrap_or([to.x(), to.y(), 0.into(), 0.into()].into())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue