mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 03:36:42 +01:00
- okay, that seems to have fixed the FieldH/FieldV issue? - thought that'd never happen - still not happy with how Layout override is working
This commit is contained in:
parent
731f4a971e
commit
8c54510f63
9 changed files with 179 additions and 118 deletions
|
|
@ -16,17 +16,11 @@ pub trait HasContent<O: Out> {
|
|||
fn content (&self) -> impl Content<O>;
|
||||
}
|
||||
|
||||
|
||||
pub struct Bounded<O: Out, D>(pub O::Area, pub D);
|
||||
impl<O: Out, D: Content<O>> HasContent<O> for Bounded<O, D> {
|
||||
fn content (&self) -> impl Content<O> { &self.1 }
|
||||
}
|
||||
|
||||
impl<O: Out, T: Draw<O>> Draw<O> for Bounded<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;
|
||||
}
|
||||
}
|
||||
//impl<O: Out, T: HasContent<O>> Draw<O> for T {
|
||||
//fn draw (&self, to: &mut O) {
|
||||
//let area = to.area();
|
||||
//*to.area_mut() = self.0;
|
||||
//self.content().draw(to);
|
||||
//*to.area_mut() = area;
|
||||
//}
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,30 @@
|
|||
use crate::*;
|
||||
|
||||
/// 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) } } }
|
||||
pub trait Draw<O: Out> {
|
||||
fn draw (&self, to: &mut O);
|
||||
}
|
||||
impl<O: Out> Draw<O> for () {
|
||||
fn draw (&self, _: &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 Arc<D> {
|
||||
fn draw (&self, to: &mut O) { (**self).draw(to) }
|
||||
}
|
||||
impl<O: Out, D: Draw<O>> Draw<O> for RwLock<D> {
|
||||
fn draw (&self, to: &mut O) { self.read().unwrap().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) } }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,15 +11,27 @@ 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 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 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))
|
||||
}
|
||||
|
|
@ -64,6 +76,18 @@ impl<O: Out, L: Layout<O>> Layout<O> for &mut L {
|
|||
fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) }
|
||||
}
|
||||
|
||||
impl<O: Out, L: Layout<O>> Layout<O> for Arc<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) }
|
||||
|
|
@ -76,6 +100,18 @@ impl<O: Out> Layout<O> for Box<dyn Layout<O>> {
|
|||
fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) }
|
||||
}
|
||||
|
||||
impl<O: Out, L: Layout<O>> Layout<O> for RwLock<L> {
|
||||
fn x (&self, a: O::Area) -> O::Unit { self.read().unwrap().x(a) }
|
||||
fn y (&self, a: O::Area) -> O::Unit { self.read().unwrap().y(a) }
|
||||
fn w (&self, a: O::Area) -> O::Unit { self.read().unwrap().w(a) }
|
||||
fn min_w (&self, a: O::Area) -> O::Unit { self.read().unwrap().min_w(a) }
|
||||
fn max_w (&self, a: O::Area) -> O::Unit { self.read().unwrap().max_w(a) }
|
||||
fn h (&self, a: O::Area) -> O::Unit { self.read().unwrap().h(a) }
|
||||
fn min_h (&self, a: O::Area) -> O::Unit { self.read().unwrap().min_h(a) }
|
||||
fn max_h (&self, a: O::Area) -> O::Unit { self.read().unwrap().max_h(a) }
|
||||
fn layout (&self, a: O::Area) -> O::Area { self.read().unwrap().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())
|
||||
|
|
@ -106,3 +142,20 @@ impl<O: Out, L: Layout<O>> Layout<O> for Option<L> {
|
|||
.unwrap_or([to.x(), to.y(), 0.into(), 0.into()].into())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Bounded<O: Out, D>(pub O::Area, pub D);
|
||||
|
||||
impl<O: Out, D: Content<O>> HasContent<O> for Bounded<O, D> {
|
||||
fn content (&self) -> impl Content<O> {
|
||||
&self.1
|
||||
}
|
||||
}
|
||||
|
||||
impl<O: Out, T: Draw<O>> Draw<O> for Bounded<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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
mod widget_border; pub use self::widget_border::*;
|
||||
mod widget_field; pub use self::widget_field::*;
|
||||
mod widget_form; pub use self::widget_form::*;
|
||||
mod widget_style; pub use self::widget_style::*;
|
||||
mod widget_tryptich; pub use self::widget_tryptich::*;
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct FieldH<Theme, Label, Value>(pub Theme, pub Label, pub Value);
|
||||
impl<O: Out, T, L: Content<O>, V: Content<O>> HasContent<O> for FieldH<T, L, V> {
|
||||
fn content (&self) -> impl Content<O> { Bsp::e(&self.1, &self.2) }
|
||||
}
|
||||
|
||||
pub struct FieldV<Theme, Label, Value>(pub Theme, pub Label, pub Value);
|
||||
impl<O: Out, T, L: Content<O>, V: Content<O>> HasContent<O> for FieldV<T, L, V> {
|
||||
fn content (&self) -> impl Content<O> { Bsp::s(&self.1, &self.2) }
|
||||
}
|
||||
55
output/src/widget/widget_form.rs
Normal file
55
output/src/widget/widget_form.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct FieldH<Theme, Label, Value>(pub Theme, pub Label, pub Value);
|
||||
impl<O: Out, T, L: Content<O>, V: Content<O>> HasContent<O> for FieldH<T, L, V> {
|
||||
fn content (&self) -> impl Content<O> { Bsp::e(&self.1, &self.2) }
|
||||
}
|
||||
impl<O: Out, T, L: Content<O>, V: Content<O>> Layout<O> for FieldH<T, L, V> {
|
||||
fn layout (&self, to: O::Area) -> O::Area { self.content().layout(to) }
|
||||
}
|
||||
impl<O: Out, T, L: Content<O>, V: Content<O>> Draw<O> for FieldH<T, L, V> {
|
||||
fn draw (&self, to: &mut O) { self.content().draw(to) }
|
||||
}
|
||||
|
||||
pub struct FieldV<Theme, Label, Value>(pub Theme, pub Label, pub Value);
|
||||
impl<O: Out, T, L: Content<O>, V: Content<O>> HasContent<O> for FieldV<T, L, V> {
|
||||
fn content (&self) -> impl Content<O> { Bsp::s(&self.1, &self.2) }
|
||||
}
|
||||
impl<O: Out, T, L: Content<O>, V: Content<O>> Layout<O> for FieldV<T, L, V> {
|
||||
fn layout (&self, to: O::Area) -> O::Area { self.content().layout(to) }
|
||||
}
|
||||
impl<O: Out, T, L: Content<O>, V: Content<O>> Draw<O> for FieldV<T, L, V> {
|
||||
fn draw (&self, to: &mut O) { self.content().draw(to) }
|
||||
}
|
||||
|
||||
// TODO:
|
||||
pub struct Field<C, T, U> {
|
||||
pub direction: Direction,
|
||||
pub label: Option<T>,
|
||||
pub label_fg: Option<C>,
|
||||
pub label_bg: Option<C>,
|
||||
pub label_align: Option<Direction>,
|
||||
pub value: Option<U>,
|
||||
pub value_fg: Option<C>,
|
||||
pub value_bg: Option<C>,
|
||||
pub value_align: Option<Direction>,
|
||||
}
|
||||
impl<C, T, U> Field<C, T, U> {
|
||||
pub fn new (direction: Direction) -> Field<C, (), ()> {
|
||||
Field::<C, (), ()> {
|
||||
direction,
|
||||
label: None, label_fg: None, label_bg: None, label_align: None,
|
||||
value: None, value_fg: None, value_bg: None, value_align: None,
|
||||
}
|
||||
}
|
||||
pub fn label <L> (
|
||||
self, label: Option<L>, align: Option<Direction>, fg: Option<C>, bg: Option<C>
|
||||
) -> Field<C, L, U> {
|
||||
Field::<C, L, U> { label, label_fg: fg, label_bg: bg, label_align: align, ..self }
|
||||
}
|
||||
pub fn value <V> (
|
||||
self, value: Option<V>, align: Option<Direction>, fg: Option<C>, bg: Option<C>
|
||||
) -> Field<C, T, V> {
|
||||
Field::<C, T, V> { value, value_fg: fg, value_bg: bg, value_align: align, ..self }
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@ mod tui_border; pub use self::tui_border::*;
|
|||
mod tui_button; pub use self::tui_button::*;
|
||||
mod tui_color; pub use self::tui_color::*;
|
||||
mod tui_error; pub use self::tui_error::*;
|
||||
mod tui_field; pub use self::tui_field::*;
|
||||
mod tui_phat; pub use self::tui_phat::*;
|
||||
mod tui_repeat; pub use self::tui_repeat::*;
|
||||
mod tui_scroll; pub use self::tui_scroll::*;
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
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:
|
||||
pub struct Field<T, U> {
|
||||
pub direction: Direction,
|
||||
pub label: Option<T>,
|
||||
pub label_fg: Option<ItemColor>,
|
||||
pub label_bg: Option<ItemColor>,
|
||||
pub label_align: Option<Direction>,
|
||||
pub value: Option<U>,
|
||||
pub value_fg: Option<ItemColor>,
|
||||
pub value_bg: Option<ItemColor>,
|
||||
pub value_align: Option<Direction>,
|
||||
}
|
||||
impl<T: Content<TuiOut>, U: Content<TuiOut>> HasContent<TuiOut> for Field<T, U> {
|
||||
fn content (&self) -> impl Content<TuiOut> {
|
||||
"TODO"
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Field<T, U> {
|
||||
pub fn new (direction: Direction) -> Field<(), ()> {
|
||||
Field {
|
||||
direction,
|
||||
label: None,
|
||||
label_fg: None,
|
||||
label_bg: None,
|
||||
label_align: None,
|
||||
value: None,
|
||||
value_fg: None,
|
||||
value_bg: None,
|
||||
value_align: None,
|
||||
}
|
||||
}
|
||||
pub fn label <L> (
|
||||
self,
|
||||
label: Option<L>,
|
||||
align: Option<Direction>,
|
||||
fg: Option<ItemColor>,
|
||||
bg: Option<ItemColor>
|
||||
) -> Field<L, U> {
|
||||
Field {
|
||||
label,
|
||||
label_fg: fg,
|
||||
label_bg: bg,
|
||||
label_align: align,
|
||||
..self
|
||||
}
|
||||
}
|
||||
pub fn value <V> (
|
||||
self,
|
||||
value: Option<V>,
|
||||
align: Option<Direction>,
|
||||
fg: Option<ItemColor>,
|
||||
bg: Option<ItemColor>
|
||||
) -> Field<T, V> {
|
||||
Field {
|
||||
value,
|
||||
value_fg: fg,
|
||||
value_bg: bg,
|
||||
value_align: align,
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,35 @@
|
|||
use crate::*;
|
||||
use crate::ratatui::prelude::Position;
|
||||
use unicode_width::{UnicodeWidthStr, UnicodeWidthChar};
|
||||
impl Layout<TuiOut> for &str { fn layout (&self, to: [u16;4]) -> [u16;4] { to.center_xy([width_chars_max(to.w(), self), 1]) } }
|
||||
impl Draw<TuiOut> for &str { fn draw (&self, to: &mut TuiOut) { let [x, y, w, ..] = self.layout(to.area()); to.text(&self, x, y, w) } }
|
||||
impl Layout<TuiOut> for String { fn layout (&self, to: [u16;4]) -> [u16;4] { self.as_str().layout(to) } }
|
||||
impl Draw<TuiOut> for String { fn draw (&self, to: &mut TuiOut) { self.as_str().draw(to) } }
|
||||
impl Layout<TuiOut> for Arc<str> { fn layout (&self, to: [u16;4]) -> [u16;4] { self.as_ref().layout(to) } }
|
||||
impl Draw<TuiOut> for Arc<str> { fn draw (&self, to: &mut TuiOut) { self.as_ref().draw(to) } }
|
||||
|
||||
impl Draw<TuiOut> for &str {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let [x, y, w, ..] = self.layout(to.area());
|
||||
to.text(&self, x, y, w)
|
||||
}
|
||||
}
|
||||
impl Draw<TuiOut> for String {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
self.as_str().draw(to)
|
||||
}
|
||||
}
|
||||
impl Draw<TuiOut> for Arc<str> {
|
||||
fn draw (&self, to: &mut TuiOut) { self.as_ref().draw(to) }
|
||||
}
|
||||
|
||||
impl Layout<TuiOut> for &str {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] { to.center_xy([width_chars_max(to.w(), self), 1]) }
|
||||
}
|
||||
impl Layout<TuiOut> for String {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
self.as_str().layout(to)
|
||||
}
|
||||
}
|
||||
impl Layout<TuiOut> for Arc<str> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
self.as_ref().layout(to)
|
||||
}
|
||||
}
|
||||
|
||||
fn width_chars_max (max: u16, text: impl AsRef<str>) -> u16 {
|
||||
let mut width: u16 = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue