mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
103 lines
3.1 KiB
Rust
103 lines
3.1 KiB
Rust
use crate::*;
|
|
|
|
pub trait Widget: Send + Sync {
|
|
type Engine: Engine;
|
|
fn layout (&self, to: <<Self as Widget>::Engine as Engine>::Area) ->
|
|
Perhaps<<<Self as Widget>::Engine as Engine>::Area>
|
|
{
|
|
Ok(Some(to))
|
|
}
|
|
fn render (&self, to: &mut Self::Engine) ->
|
|
Perhaps<<<Self as Widget>::Engine as Engine>::Area>;
|
|
}
|
|
impl<'a, E: Engine> Widget for Box<dyn Widget<Engine = E> + 'a> {
|
|
type Engine = E;
|
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
|
(**self).layout(to)
|
|
}
|
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
|
(**self).render(to)
|
|
}
|
|
}
|
|
impl<E: Engine> Widget for &dyn Widget<Engine = E> {
|
|
type Engine = E;
|
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
|
(*self).layout(to)
|
|
}
|
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
|
(*self).render(to)
|
|
}
|
|
}
|
|
impl<E: Engine> Widget for &mut dyn Widget<Engine = E> {
|
|
type Engine = E;
|
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
|
(**self).layout(to)
|
|
}
|
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
|
(**self).render(to)
|
|
}
|
|
}
|
|
impl<E: Engine, W: Widget<Engine = E>> Widget for Arc<W> {
|
|
type Engine = E;
|
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
|
self.as_ref().layout(to)
|
|
}
|
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
|
self.as_ref().render(to)
|
|
}
|
|
}
|
|
impl<E: Engine, W: Widget<Engine = E>> Widget for Mutex<W> {
|
|
type Engine = E;
|
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
|
self.lock().unwrap().layout(to)
|
|
}
|
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
|
self.lock().unwrap().render(to)
|
|
}
|
|
}
|
|
impl<E: Engine, W: Widget<Engine = E>> Widget for RwLock<W> {
|
|
type Engine = E;
|
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
|
self.read().unwrap().layout(to)
|
|
}
|
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
|
self.read().unwrap().render(to)
|
|
}
|
|
}
|
|
impl<E: Engine, W: Widget<Engine = E>> Widget for Option<W> {
|
|
type Engine = E;
|
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
|
Ok(self.as_ref().map(|widget|widget.layout(to)).transpose()?.flatten())
|
|
}
|
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
|
Ok(self.as_ref().map(|widget|widget.render(to)).transpose()?.flatten())
|
|
}
|
|
}
|
|
|
|
pub trait Content: Send + Sync {
|
|
type Engine: Engine;
|
|
fn content (&self) -> impl Widget<Engine = <Self as Content>::Engine>;
|
|
}
|
|
//impl<E> Content<E> for () where E: Engine {
|
|
//fn content (&self) -> impl Widget<E> {
|
|
//()
|
|
//}
|
|
//}
|
|
impl<E: Engine, W: Content<Engine = E>> Widget for W {
|
|
type Engine = E;
|
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
|
self.content().layout(to)
|
|
}
|
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
|
match self.layout(to.area())? {
|
|
Some(area) => to.render_in(area, &self.content()),
|
|
None => Ok(None)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A UI component.
|
|
pub trait Component<E: Engine>: Widget<Engine = E> + Handle<E> {}
|
|
|
|
/// Everything that implements [Render] and [Handle] is a [Component].
|
|
impl<E: Engine, C: Widget<Engine = E> + Handle<E>> Component<E> for C {}
|