mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 03:36:42 +01:00
- output: impl Layout for Measure, FieldH, FieldV - tui: enable #[feature(trait_alias)] - tui: define some trait aliases
This commit is contained in:
parent
90fc869e14
commit
731f4a971e
13 changed files with 166 additions and 147 deletions
|
|
@ -1,111 +1,32 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
pub trait HasContent<O: Out> { fn content (&self) -> impl Content<O>; }
|
|
||||||
pub trait Content<O: Out>: Draw<O> + Layout<O> {}
|
pub trait Content<O: Out>: Draw<O> + Layout<O> {}
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O> + Layout<O>> Content<O> for T {}
|
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 } }
|
impl<'a, O: Out> AsRef<dyn Draw<O> + 'a> for dyn Content<O> + 'a {
|
||||||
/// Drawable with dynamic dispatch.
|
fn as_ref (&self) -> &(dyn Draw<O> + 'a) { self }
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: Out> Layout<O> for () {
|
impl<'a, O: Out> AsRef<dyn Layout<O> + 'a> for dyn Content<O> + 'a {
|
||||||
fn x (&self, a: O::Area) -> O::Unit { a.x() }
|
fn as_ref (&self) -> &(dyn Layout<O> + 'a) { self }
|
||||||
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 {
|
pub trait HasContent<O: Out> {
|
||||||
fn x (&self, a: O::Area) -> O::Unit { (*self).x(a) }
|
fn content (&self) -> impl Content<O>;
|
||||||
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) }
|
pub struct Bounded<O: Out, D>(pub O::Area, pub D);
|
||||||
fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) }
|
impl<O: Out, D: Content<O>> HasContent<O> for Bounded<O, D> {
|
||||||
fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) }
|
fn content (&self) -> impl Content<O> { &self.1 }
|
||||||
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>> {
|
impl<O: Out, T: Draw<O>> Draw<O> for Bounded<O, T> {
|
||||||
fn x (&self, a: O::Area) -> O::Unit { (**self).x(a) }
|
fn draw (&self, to: &mut O) {
|
||||||
fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) }
|
let area = to.area();
|
||||||
fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) }
|
*to.area_mut() = self.0;
|
||||||
fn min_w (&self, a: O::Area) -> O::Unit { (**self).min_w(a) }
|
self.1.draw(to);
|
||||||
fn max_w (&self, a: O::Area) -> O::Unit { (**self).max_w(a) }
|
*to.area_mut() = area;
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,10 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub struct Bound<O: Out, D>(pub O::Area, pub D);
|
/// Drawable with dynamic dispatch.
|
||||||
|
pub trait Draw<O: Out> { fn draw (&self, to: &mut O); }
|
||||||
impl<O: Out, D: Content<O>> HasContent<O> for Bound<O, D> {
|
impl<O: Out> Draw<O> for () { fn draw (&self, to: &mut O) {} }
|
||||||
fn content (&self) -> &impl Content<O> { &self.1 }
|
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, T> Layout<O> for Bound<O, T> {
|
impl<O: Out, D: Draw<O>> Draw<O> for &mut D { fn draw (&self, to: &mut O) { (**self).draw(to) } }
|
||||||
fn x (&self, _: O::Area) -> O::Unit { self.0.x() }
|
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) } } }
|
||||||
fn y (&self, _: O::Area) -> O::Unit { self.0.y() }
|
|
||||||
fn w (&self, _: O::Area) -> O::Unit { self.0.w() }
|
|
||||||
fn min_w (&self, _: O::Area) -> O::Unit { self.0.w() }
|
|
||||||
fn max_w (&self, _: O::Area) -> O::Unit { self.0.w() }
|
|
||||||
fn h (&self, _: O::Area) -> O::Unit { self.0.h() }
|
|
||||||
fn min_h (&self, _: O::Area) -> O::Unit { self.0.w() }
|
|
||||||
fn max_h (&self, _: O::Area) -> O::Unit { self.0.w() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<O: Out, T: Draw<O>> Draw<O> for Bound<O, T> {
|
|
||||||
fn draw (&self, to: &mut O) {
|
|
||||||
let area = to.area();
|
|
||||||
*to.area_mut() = self.0;
|
|
||||||
self.1.draw(to);
|
|
||||||
*to.area_mut() = area;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,101 @@ mod layout_pad; pub use self::layout_pad::*;
|
||||||
mod layout_move; pub use self::layout_move::*;
|
mod layout_move; pub use self::layout_move::*;
|
||||||
mod layout_size; pub use self::layout_size::*;
|
mod layout_size; pub use self::layout_size::*;
|
||||||
mod layout_stack; //pub use self::layout_stack::*;
|
mod layout_stack; //pub use self::layout_stack::*;
|
||||||
|
|
||||||
|
/// 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ impl<T> Align<T> {
|
||||||
#[inline] pub const fn se (a: T) -> Self { Self(Alignment::SE, a) }
|
#[inline] pub const fn se (a: T) -> Self { Self(Alignment::SE, a) }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Align<T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Align<T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), &self.1).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), &self.1).draw(to) }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Layout<O>> Layout<O> for Align<T> {
|
impl<O: Out, T: Layout<O>> Layout<O> for Align<T> {
|
||||||
fn x (&self, to: O::Area) -> O::Unit {
|
fn x (&self, to: O::Area) -> O::Unit {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ impl<O: Out, T: Layout<O>> Layout<O> for When<O, T> {
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for When<O, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for When<O, T> {
|
||||||
fn draw (&self, to: &mut O) {
|
fn draw (&self, to: &mut O) {
|
||||||
let Self(cond, item, ..) = self;
|
let Self(cond, item, ..) = self;
|
||||||
if *cond { Bound(self.layout(to.area()), item).draw(to) }
|
if *cond { Bounded(self.layout(to.area()), item).draw(to) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ impl<E: Out, A: Content<E>, B: Content<E>> Draw<E> for Either<E, A, B> {
|
||||||
fn draw (&self, to: &mut E) {
|
fn draw (&self, to: &mut E) {
|
||||||
let Self(cond, a, b, ..) = self;
|
let Self(cond, a, b, ..) = self;
|
||||||
let area = self.layout(to.area());
|
let area = self.layout(to.area());
|
||||||
if *cond { Bound(area, a).draw(to) } else { Bound(area, b).draw(to) }
|
if *cond { Bounded(area, a).draw(to) } else { Bounded(area, b).draw(to) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ impl<U: Coordinate, T> Push<U, T> {
|
||||||
#[inline] pub fn dy (&self) -> U { match self { Self::Y(y, ..) | Self::XY(_, y, _) => *y, Self::X(_, _) => 0.into() } }
|
#[inline] pub fn dy (&self) -> U { match self { Self::Y(y, ..) | Self::XY(_, y, _) => *y, Self::X(_, _) => 0.into() } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Push<O::Unit, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Push<O::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Layout<O>> Layout<O> for Push<O::Unit, T> {
|
impl<O: Out, T: Layout<O>> Layout<O> for Push<O::Unit, T> {
|
||||||
fn x (&self, area: O::Area) -> O::Unit { area.x().plus(self.dx()) }
|
fn x (&self, area: O::Area) -> O::Unit { area.x().plus(self.dx()) }
|
||||||
|
|
@ -25,7 +25,7 @@ impl<U: Coordinate, T> Pull<U, T> {
|
||||||
#[inline] pub fn dy (&self) -> U { match self { Self::Y(y, ..) | Self::XY(_, y, _) => *y, Self::X(_, _) => 0.into() } }
|
#[inline] pub fn dy (&self) -> U { match self { Self::Y(y, ..) | Self::XY(_, y, _) => *y, Self::X(_, _) => 0.into() } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Pull<O::Unit, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Pull<O::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Layout<O>> Layout<O> for Pull<O::Unit, T> {
|
impl<O: Out, T: Layout<O>> Layout<O> for Pull<O::Unit, T> {
|
||||||
fn x (&self, area: O::Area) -> O::Unit { area.x().minus(self.dx()) }
|
fn x (&self, area: O::Area) -> O::Unit { area.x().minus(self.dx()) }
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ impl<U: Coordinate, T> Pad<U, T> {
|
||||||
#[inline] pub fn dy (&self) -> U { match self { X(_, _) => 0.into(), Y(y, _) => *y, XY(_, y, _) => *y, } }
|
#[inline] pub fn dy (&self) -> U { match self { X(_, _) => 0.into(), Y(y, _) => *y, XY(_, y, _) => *y, } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Pad<O::Unit, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Pad<O::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Layout<O>> Layout<O> for Pad<O::Unit, T> {
|
impl<O: Out, T: Layout<O>> Layout<O> for Pad<O::Unit, T> {
|
||||||
fn x (&self, area: O::Area) -> O::Unit {
|
fn x (&self, area: O::Area) -> O::Unit {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ impl<A> Fill<A> {
|
||||||
#[inline] pub const fn dy (&self) -> bool { match self { Self::Y(_) | Self::XY(_) => true, _ => false } }
|
#[inline] pub const fn dy (&self) -> bool { match self { Self::Y(_) | Self::XY(_) => true, _ => false } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Fill<T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Fill<T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Layout<O>> Layout<O> for Fill<T> {
|
impl<O: Out, T: Layout<O>> Layout<O> for Fill<T> {
|
||||||
fn x (&self, area: O::Area) -> O::Unit { if self.dx() { area.x() } else { self.inner().x(area) } }
|
fn x (&self, area: O::Area) -> O::Unit { if self.dx() { area.x() } else { self.inner().x(area) } }
|
||||||
|
|
@ -29,7 +29,7 @@ impl<U: Copy, A> Fixed<U, A> {
|
||||||
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Fixed<O::Unit, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Fixed<O::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Layout<O>> Layout<O> for Fixed<O::Unit, T> {
|
impl<O: Out, T: Layout<O>> Layout<O> for Fixed<O::Unit, T> {
|
||||||
fn w (&self, area: O::Area) -> O::Unit { self.dx().unwrap_or(self.inner().w(area)) }
|
fn w (&self, area: O::Area) -> O::Unit { self.dx().unwrap_or(self.inner().w(area)) }
|
||||||
|
|
@ -49,7 +49,7 @@ impl<U: Copy, A> Max<U, A> {
|
||||||
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Max<O::Unit, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Max<O::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<E: Out, T: Layout<E>> Layout<E> for Max<E::Unit, T> {
|
impl<E: Out, T: Layout<E>> Layout<E> for Max<E::Unit, T> {
|
||||||
fn layout (&self, area: E::Area) -> E::Area {
|
fn layout (&self, area: E::Area) -> E::Area {
|
||||||
|
|
@ -71,7 +71,7 @@ impl<U: Copy, A> Min<U, A> {
|
||||||
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Min<O::Unit, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Min<O::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<E: Out, T: Layout<E>> Layout<E> for Min<E::Unit, T> {
|
impl<E: Out, T: Layout<E>> Layout<E> for Min<E::Unit, T> {
|
||||||
fn layout (&self, area: E::Area) -> E::Area {
|
fn layout (&self, area: E::Area) -> E::Area {
|
||||||
|
|
@ -93,7 +93,7 @@ impl<U: Copy + Default, A> Expand<U, A> {
|
||||||
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Expand<O::Unit, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Expand<O::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Layout<O>> Layout<O> for Expand<O::Unit, T> {
|
impl<O: Out, T: Layout<O>> Layout<O> for Expand<O::Unit, T> {
|
||||||
fn w (&self, to: O::Area) -> O::Unit { self.inner().w(to).plus(self.dx().unwrap_or_default()) }
|
fn w (&self, to: O::Area) -> O::Unit { self.inner().w(to).plus(self.dx().unwrap_or_default()) }
|
||||||
|
|
@ -109,7 +109,7 @@ impl<U: Copy, A> Shrink<U, A> {
|
||||||
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
#[inline] pub const fn dy (&self) -> Option<U> { match self { Self::Y(y, _) | Self::XY(y, ..) => Some(*y), _ => None } }
|
||||||
}
|
}
|
||||||
impl<O: Out, T: Content<O>> Draw<O> for Shrink<O::Unit, T> {
|
impl<O: Out, T: Content<O>> Draw<O> for Shrink<O::Unit, T> {
|
||||||
fn draw (&self, to: &mut O) { Bound(self.layout(to.area()), self.inner()).draw(to) }
|
fn draw (&self, to: &mut O) { Bounded(self.layout(to.area()), self.inner()).draw(to) }
|
||||||
}
|
}
|
||||||
impl<E: Out, T: Layout<E>> Layout<E> for Shrink<E::Unit, T> {
|
impl<E: Out, T: Layout<E>> Layout<E> for Shrink<E::Unit, T> {
|
||||||
fn layout (&self, to: E::Area) -> E::Area {
|
fn layout (&self, to: E::Area) -> E::Area {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#![feature(const_option_ops)]
|
#![feature(const_option_ops)]
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
#![feature(const_default)]
|
#![feature(const_default)]
|
||||||
|
#![feature(trait_alias)]
|
||||||
//#![feature(non_lifetime_binders)]
|
//#![feature(non_lifetime_binders)]
|
||||||
|
|
||||||
pub(crate) use self::Direction::*;
|
pub(crate) use self::Direction::*;
|
||||||
|
|
|
||||||
|
|
@ -2,28 +2,30 @@ use crate::*;
|
||||||
|
|
||||||
/// A widget that tracks its render width and height
|
/// A widget that tracks its render width and height
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Measure<E: Out> {
|
pub struct Measure<O: Out> {
|
||||||
_engine: PhantomData<E>,
|
_engine: PhantomData<O>,
|
||||||
pub x: Arc<AtomicUsize>,
|
pub x: Arc<AtomicUsize>,
|
||||||
pub y: Arc<AtomicUsize>,
|
pub y: Arc<AtomicUsize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Out> PartialEq for Measure<E> {
|
impl<O: Out> PartialEq for Measure<O> {
|
||||||
fn eq (&self, other: &Self) -> bool {
|
fn eq (&self, other: &Self) -> bool {
|
||||||
self.x.load(Relaxed) == other.x.load(Relaxed) &&
|
self.x.load(Relaxed) == other.x.load(Relaxed) &&
|
||||||
self.y.load(Relaxed) == other.y.load(Relaxed)
|
self.y.load(Relaxed) == other.y.load(Relaxed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<O: Out> Layout<O> for Measure<O> {}
|
||||||
|
|
||||||
// TODO: 🡘 🡙 ←🡙→ indicator to expand window when too small
|
// TODO: 🡘 🡙 ←🡙→ indicator to expand window when too small
|
||||||
impl<E: Out> Draw<E> for Measure<E> {
|
impl<O: Out> Draw<O> for Measure<O> {
|
||||||
fn draw (&self, to: &mut E) {
|
fn draw (&self, to: &mut O) {
|
||||||
self.x.store(to.area().w().into(), Relaxed);
|
self.x.store(to.area().w().into(), Relaxed);
|
||||||
self.y.store(to.area().h().into(), Relaxed);
|
self.y.store(to.area().h().into(), Relaxed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Out> Clone for Measure<E> {
|
impl<O: Out> Clone for Measure<O> {
|
||||||
fn clone (&self) -> Self {
|
fn clone (&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_engine: Default::default(),
|
_engine: Default::default(),
|
||||||
|
|
@ -33,7 +35,7 @@ impl<E: Out> Clone for Measure<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Out> std::fmt::Debug for Measure<E> {
|
impl<O: Out> std::fmt::Debug for Measure<O> {
|
||||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||||
f.debug_struct("Measure")
|
f.debug_struct("Measure")
|
||||||
.field("width", &self.x)
|
.field("width", &self.x)
|
||||||
|
|
@ -42,7 +44,7 @@ impl<E: Out> std::fmt::Debug for Measure<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Out> Measure<E> {
|
impl<O: Out> Measure<O> {
|
||||||
pub fn new () -> Self {
|
pub fn new () -> Self {
|
||||||
Self {
|
Self {
|
||||||
_engine: PhantomData::default(),
|
_engine: PhantomData::default(),
|
||||||
|
|
@ -75,7 +77,7 @@ impl<E: Out> Measure<E> {
|
||||||
pub fn format (&self) -> Arc<str> {
|
pub fn format (&self) -> Arc<str> {
|
||||||
format!("{}x{}", self.w(), self.h()).into()
|
format!("{}x{}", self.w(), self.h()).into()
|
||||||
}
|
}
|
||||||
pub fn of <T: Draw<E>> (&self, item: T) -> Bsp<Fill<&Self>, T> {
|
pub fn of <T: Draw<O>> (&self, item: T) -> Bsp<Fill<&Self>, T> {
|
||||||
Bsp::b(Fill::XY(self), item)
|
Bsp::b(Fill::XY(self), item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#![feature(type_changing_struct_update)]
|
#![feature(type_changing_struct_update)]
|
||||||
|
#![feature(trait_alias)]
|
||||||
#[cfg(test)] mod tui_test;
|
#[cfg(test)] mod tui_test;
|
||||||
mod tui_engine; pub use self::tui_engine::*;
|
mod tui_engine; pub use self::tui_engine::*;
|
||||||
mod tui_content; pub use self::tui_content::*;
|
mod tui_content; pub use self::tui_content::*;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
impl<T: TuiContent, U: TuiContent> Draw<TuiOut> for FieldH<ItemTheme, T, U> {
|
||||||
|
fn draw (&self, to: &mut TuiOut) { to.place(&self.content()) }
|
||||||
|
}
|
||||||
|
impl<T: TuiContent, U: TuiContent> Draw<TuiOut> for FieldV<ItemTheme, T, U> {
|
||||||
|
fn draw (&self, to: &mut TuiOut) { to.place(&self.content()) }
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
pub struct Field<T, U> {
|
pub struct Field<T, U> {
|
||||||
pub direction: Direction,
|
pub direction: Direction,
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,18 @@ impl Tui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TuiRun<R: Draw<TuiOut> + Handle<TuiIn> + 'static> {
|
pub trait TuiDraw = Draw<TuiOut>;
|
||||||
|
pub trait TuiLayout = Layout<TuiOut>;
|
||||||
|
pub trait TuiContent = Content<TuiOut>;
|
||||||
|
pub trait TuiHandle = Handle<TuiIn>;
|
||||||
|
pub trait TuiWidget = TuiDraw + TuiHandle;
|
||||||
|
|
||||||
|
pub trait TuiRun<T: TuiWidget + 'static> {
|
||||||
/// Run an app in the main loop.
|
/// Run an app in the main loop.
|
||||||
fn run (&self, state: &Arc<RwLock<R>>) -> Usually<()>;
|
fn run (&self, state: &Arc<RwLock<T>>) -> Usually<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Draw<TuiOut> + Handle<TuiIn> + Send + Sync + 'static> TuiRun<T> for Arc<RwLock<Tui>> {
|
impl<T: TuiWidget + Send + Sync + 'static> TuiRun<T> for Arc<RwLock<Tui>> {
|
||||||
fn run (&self, state: &Arc<RwLock<T>>) -> Usually<()> {
|
fn run (&self, state: &Arc<RwLock<T>>) -> Usually<()> {
|
||||||
let _input_thread = TuiIn::run_input(self, state, Duration::from_millis(100));
|
let _input_thread = TuiIn::run_input(self, state, Duration::from_millis(100));
|
||||||
self.write().unwrap().setup()?;
|
self.write().unwrap().setup()?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue