mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-07-17 07:56:56 +02:00
add origin and align methods to Layout trait
This commit is contained in:
parent
09463649c6
commit
13c886d9e0
18 changed files with 333 additions and 248 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use ::{
|
||||
std::{io::stdout, sync::{Arc, RwLock}},
|
||||
tengri::{*, term::*, lang::*, keys::*, draw::*, space::*, lang::*},
|
||||
ratatui::style::Color,
|
||||
tengri::{*, lang::*},
|
||||
};
|
||||
|
||||
tui_main!(State {
|
||||
|
|
@ -18,10 +18,10 @@ tui_view!(|self: State| {
|
|||
let wh = (self.size.w(), self.size.h());
|
||||
let src = VIEWS.get(self.cursor).unwrap_or(&"");
|
||||
let heading = format!("State {}/{} in {:?}", index, VIEWS.len(), &wh);
|
||||
let title = bg(Color::Rgb(60, 10, 10), y_push(1, align_n(heading)));
|
||||
let code = bg(Color::Rgb(10, 60, 10), y_push(2, align_n(format!("{}", src))));
|
||||
let title = bg(Color::Rgb(60, 10, 10), heading.align_n().push_y(1));
|
||||
let code = bg(Color::Rgb(10, 60, 10), format!("{}", src).align_n().push_y(2));
|
||||
//let content = ;//();//bg(Color::Rgb(10, 10, 60), View(self, CstIter::new(src)));
|
||||
let widget = thunk(move|to: &mut Tui|self.interpret(to, &src));
|
||||
let widget = thunk(move|to: &mut Tui|self.interpret(to, &src).map(Some));
|
||||
self.size.of(south(title, north(code, widget)))
|
||||
});
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ struct State {
|
|||
/** User-controllable value. */
|
||||
cursor: usize,
|
||||
/** Rendered window size. */
|
||||
size: crate::space::Size,
|
||||
size: Sizer,
|
||||
}
|
||||
|
||||
impl Interpret<Tui, XYWH<u16>> for State {
|
||||
|
|
|
|||
36
src/draw.rs
36
src/draw.rs
|
|
@ -3,32 +3,34 @@ use crate::*;
|
|||
/// Output target.
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::{*, draw::*};
|
||||
///
|
||||
/// struct TestOut<T: Screen<Unit = u16>>(T);
|
||||
///
|
||||
/// impl<T: Screen<Unit = u16>> Screen for TestOut {
|
||||
/// use tengri::*;
|
||||
/// struct TestOut { w: u16, h: u16 };
|
||||
/// impl Wide<u16> for TestOut {}
|
||||
/// impl Tall<u16> for TestOut {}
|
||||
/// impl Xy<u16> for TestOut { fn x (&self) -> u16 { 0 } fn y (&self) -> u16 { 0 } }
|
||||
/// impl Screen for TestOut {
|
||||
/// type Unit = u16;
|
||||
/// fn show <D: Draw<Self> + ?Sized> (&mut self, _: D) {
|
||||
/// fn show <D: Draw<Self>> (&mut self, _: D) -> Drawn<u16> {
|
||||
/// println!("placed");
|
||||
/// ()
|
||||
/// Ok(None)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl_draw!(|self: String, to: TestOut<u16>|{
|
||||
/// to.area_mut().set_w(self.len() as u16);
|
||||
/// impl_draw!(|self: String, to: TestOut|{
|
||||
/// to.w = self.len() as u16;
|
||||
/// Ok(None)
|
||||
/// });
|
||||
/// ```
|
||||
pub trait Screen: Xy<Self::Unit> + Wh<Self::Unit> + Send + Sync + Sized {
|
||||
type Unit: Coord;
|
||||
/// Render drawable in subarea specified by `area`
|
||||
fn show <'t, T: Draw<Self>> (&mut self, content: T) -> Perhaps<XYWH<Self::Unit>>;
|
||||
fn show <T: Draw<Self>> (&mut self, content: T) -> Perhaps<XYWH<Self::Unit>>;
|
||||
}
|
||||
|
||||
/// Implement the [Draw] trait for a particular drawable and [Screen].
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::{*, draw::*, term::*};
|
||||
/// use tengri::*;
|
||||
/// struct MyDrawable;
|
||||
/// impl_draw!(|self: MyDrawable, to: Tui|{
|
||||
/// todo!("your draw logic")
|
||||
|
|
@ -60,7 +62,7 @@ pub trait Screen: Xy<Self::Unit> + Wh<Self::Unit> + Send + Sync + Sized {
|
|||
/// a [Draw]able.
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::{*, draw::*, term::*};
|
||||
/// use tengri::*;
|
||||
/// struct MyWidget(bool);
|
||||
/// impl Draw<Tui> for MyWidget {
|
||||
/// fn draw (self, to: &mut Tui) -> Perhaps<XYWH<u16>> {
|
||||
|
|
@ -106,6 +108,12 @@ pub trait View<T: Screen> {
|
|||
fn view (&self) -> impl Draw<T>;
|
||||
}
|
||||
|
||||
impl<T: Screen> View<T> for () {
|
||||
fn view (&self) -> impl Draw<T> {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Screen, V: View<T>> Draw<T> for &V {
|
||||
fn draw (self, to: &mut T) -> Perhaps<XYWH<T::Unit>> {
|
||||
self.view().draw(to)
|
||||
|
|
@ -114,15 +122,11 @@ impl<T: Screen, V: View<T>> Draw<T> for &V {
|
|||
|
||||
features! {
|
||||
"draw": [
|
||||
align,
|
||||
area,
|
||||
azimuth,
|
||||
color,
|
||||
coord,
|
||||
iter,
|
||||
layout,
|
||||
lrtb,
|
||||
origin,
|
||||
sizer,
|
||||
space,
|
||||
split,
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Align<T>(Option<Azimuth>, T);
|
||||
|
||||
impl_draw!(<S: Screen, T: Draw<S>,>|self: Align<T>, to: S|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = align(None, "unaligned");
|
||||
/// let _ = align(Azimuth::SE, "southeast");
|
||||
/// let _ = align(Some(Azimuth::SE), "southeast");
|
||||
/// ```
|
||||
pub fn align <S: Screen, T: Draw<S>, U: Into<Option<Azimuth>>> (origin: U, it: T) -> Align<T> {
|
||||
Align(origin.into(), it)
|
||||
}
|
||||
|
||||
pub fn align_c <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::C), it) }
|
||||
pub fn align_x <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::X), it) }
|
||||
pub fn align_y <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::Y), it) }
|
||||
|
||||
pub fn align_n <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::N), it) }
|
||||
pub fn align_s <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::S), it) }
|
||||
pub fn align_e <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::E), it) }
|
||||
pub fn align_w <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::W), it) }
|
||||
|
||||
pub fn align_ne <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::NE), it) }
|
||||
pub fn align_se <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::SE), it) }
|
||||
pub fn align_nw <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::NW), it) }
|
||||
pub fn align_sw <S: Screen, T: Draw<S>> (it: T) -> Align<T> { Align(Some(Azimuth::SW), it) }
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = area(None, "unareaed");
|
||||
/// let _ = area([1, 2, 3, 4], "southeast");
|
||||
/// let _ = area(Some([1, 2, 3, 4]), "southeast");
|
||||
/// ```
|
||||
pub fn area <S: Screen, T: Draw<S>, U: Into<Option<XYWH<S::Unit>>>> (
|
||||
origin: U, it: T
|
||||
) -> Area<S, T> {
|
||||
Area(origin.into(), it)
|
||||
}
|
||||
|
||||
pub struct Area<S: Screen, T: Draw<S>>(Option<XYWH<S::Unit>>, T);
|
||||
|
||||
impl_draw!(<S: Screen, T: Draw<S>,>|self: Area<S, T>, to: S|{ todo!() });
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
/// Where is [0, 0] located?
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::draw::Azimuth;
|
||||
/// let _ = Azimuth::NW.align(());
|
||||
/// ```
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
#[derive(Debug, Copy, Clone, Default)] pub enum Azimuth {
|
||||
#[default] C, X, Y, NW, N, NE, E, SE, S, SW, W
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ use super::*;
|
|||
/// FIXME: Use AsRef/AsMut?
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::draw::Coord;
|
||||
/// use tengri::*;
|
||||
/// let a: u16 = Coord::zero();
|
||||
/// let b: u16 = a.plus(1);
|
||||
/// let c: u16 = a.minus(2);
|
||||
|
|
|
|||
|
|
@ -15,15 +15,6 @@ pub fn iter_once <'a, S: Screen, D: 'a, U: Draw<S>> (
|
|||
}
|
||||
|
||||
/// Iterate over a collection of various [Draw]ables:
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::draw::{Origin::*, Split::*};
|
||||
/// let _ = Below.iter([
|
||||
/// NW.align(W(15).max(W(10).min("Leftbar"))),
|
||||
/// NE.align(W(12).max(W(10).min("Rightbar"))),
|
||||
/// Center.align(W(40).max(H(20.max("Center"))))
|
||||
/// ].iter(), |x|x);
|
||||
/// ```
|
||||
pub fn iter_dyn <
|
||||
S: Screen, // Target screen
|
||||
D, // Input doesn't need to be [Draw]able, output does
|
||||
|
|
|
|||
|
|
@ -70,11 +70,96 @@ pub trait Layout<S: Screen>: Draw<S> + Sized {
|
|||
fn push_xy <N: Into<Option<S::Unit>>> (self, x: N, y: N) -> impl Draw<S> {
|
||||
Push::XY(self, x.into(), y.into())
|
||||
}
|
||||
|
||||
fn align (self, azimuth: impl Into<Option<Azimuth>>) -> impl Draw<S> {
|
||||
Align(azimuth.into(), self)
|
||||
}
|
||||
fn align_c (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::C), self)
|
||||
}
|
||||
fn align_x (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::X), self)
|
||||
}
|
||||
fn align_y (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::Y), self)
|
||||
}
|
||||
|
||||
fn align_n (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::N), self)
|
||||
}
|
||||
fn align_s (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::S), self)
|
||||
}
|
||||
fn align_e (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::E), self)
|
||||
}
|
||||
fn align_w (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::W), self)
|
||||
}
|
||||
|
||||
fn align_ne (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::NE), self)
|
||||
}
|
||||
fn align_se (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::SE), self)
|
||||
}
|
||||
fn align_nw (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::NW), self)
|
||||
}
|
||||
fn align_sw (self) -> impl Draw<S> {
|
||||
Align(Some(Azimuth::SW), self)
|
||||
}
|
||||
|
||||
fn origin (self, azimuth: impl Into<Option<Azimuth>>) -> impl Draw<S> {
|
||||
Origin(azimuth.into(), self)
|
||||
}
|
||||
fn origin_c (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::C), self)
|
||||
}
|
||||
fn origin_x (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::X), self)
|
||||
}
|
||||
fn origin_y (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::Y), self)
|
||||
}
|
||||
|
||||
fn origin_n (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::N), self)
|
||||
}
|
||||
fn origin_s (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::S), self)
|
||||
}
|
||||
fn origin_e (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::E), self)
|
||||
}
|
||||
fn origin_w (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::W), self)
|
||||
}
|
||||
|
||||
fn origin_ne (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::NE), self)
|
||||
}
|
||||
fn origin_se (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::SE), self)
|
||||
}
|
||||
fn origin_nw (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::NW), self)
|
||||
}
|
||||
fn origin_sw (self) -> impl Draw<S> {
|
||||
Origin(Some(Azimuth::SW), self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Screen, T: Draw<S>> Layout<S> for T {}
|
||||
|
||||
/// Use whole drawing area along one or both axes.
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::Layout;
|
||||
/// let _ = "".full_w();
|
||||
/// let _ = "".full_h();
|
||||
/// let _ = "".full_wh();
|
||||
/// ```
|
||||
pub enum Full<T: Screen, I: Draw<T>> {
|
||||
__(PhantomData<T>),
|
||||
W(I),
|
||||
|
|
@ -82,14 +167,17 @@ pub enum Full<T: Screen, I: Draw<T>> {
|
|||
WH(I),
|
||||
}
|
||||
|
||||
impl_draw!(<T: Screen, I: Draw<T>,>|self: Full<T, I>, to: T|{
|
||||
impl_draw!(<T: Screen, I: Draw<T>,>|self: Full<T, I>, _to: T|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// Only draw content if area is above a certain size.
|
||||
/// Move content in the positive direction of one or both axes.
|
||||
///
|
||||
/// ```
|
||||
/// let min = tengri::wh_min(3, 5, "Hello"); // 5x5
|
||||
/// use tengri::Layout;
|
||||
/// let _ = "".push_x(1);
|
||||
/// let _ = "".push_y(1);
|
||||
/// let _ = "".push_xy(1, 1);
|
||||
/// ```
|
||||
pub enum Push<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
||||
__(PhantomData<T>),
|
||||
|
|
@ -98,14 +186,17 @@ pub enum Push<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
|||
XY(I, X, X),
|
||||
}
|
||||
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Push<T, I, X>, to: T|{
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Push<T, I, X>, _to: T|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// Only draw content if area is above a certain size.
|
||||
/// Move content in the negative direction of one or both axes.
|
||||
///
|
||||
/// ```
|
||||
/// let min = tengri::wh_min(3, 5, "Hello"); // 5x5
|
||||
/// use tengri::Layout;
|
||||
/// let _ = "".pull_x(1);
|
||||
/// let _ = "".pull_y(1);
|
||||
/// let _ = "".pull_xy(1, 1);
|
||||
/// ```
|
||||
pub enum Pull<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
||||
__(PhantomData<T>),
|
||||
|
|
@ -114,14 +205,17 @@ pub enum Pull<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
|||
XY(I, X, X),
|
||||
}
|
||||
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Pull<T, I, X>, to: T|{
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Pull<T, I, X>, _to: T|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// Only draw content if area is above a certain size.
|
||||
///
|
||||
/// ```
|
||||
/// let min = tengri::wh_min(3, 5, "Hello"); // 5x5
|
||||
/// use tengri::Layout;
|
||||
/// let _ = "".min_w(1);
|
||||
/// let _ = "".min_h(1);
|
||||
/// let _ = "".min_wh(1, 1);
|
||||
/// ```
|
||||
pub enum Min<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
||||
__(PhantomData<T>),
|
||||
|
|
@ -130,16 +224,17 @@ pub enum Min<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
|||
WH(I, X, X),
|
||||
}
|
||||
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Min<T, I, X>, to: T|{
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Min<T, I, X>, _to: T|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// Set maximum size of of drawing area.
|
||||
///
|
||||
/// ```
|
||||
/// let max = tengri::w_max(3, "Hello");
|
||||
/// let max = tengri::w_max(None, "Hello");
|
||||
/// let max = tengri::w_max(Some(3), "Hello");
|
||||
/// use tengri::Layout;
|
||||
/// let _ = "".max_w(1);
|
||||
/// let _ = "".max_h(1);
|
||||
/// let _ = "".max_wh(1, 1);
|
||||
/// ```
|
||||
pub enum Max<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
||||
__(PhantomData<T>),
|
||||
|
|
@ -148,16 +243,17 @@ pub enum Max<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
|||
WH(I, X, X),
|
||||
}
|
||||
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Max<T, I, X>, to: T|{
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Max<T, I, X>, _to: T|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// Set size of of drawing area.
|
||||
///
|
||||
/// ```
|
||||
/// let max = tengri::w_max(3, "Hello");
|
||||
/// let max = tengri::w_max(None, "Hello");
|
||||
/// let max = tengri::w_max(Some(3), "Hello");
|
||||
/// use tengri::Layout;
|
||||
/// let _ = "".exact_w(1);
|
||||
/// let _ = "".exact_h(1);
|
||||
/// let _ = "".exact_wh(1, 1);
|
||||
/// ```
|
||||
pub enum Exact<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
||||
__(PhantomData<T>),
|
||||
|
|
@ -166,16 +262,17 @@ pub enum Exact<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
|||
WH(I, X, X),
|
||||
}
|
||||
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Exact<T, I, X>, to: T|{
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Exact<T, I, X>, _to: T|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// Define inner drawing area.
|
||||
///
|
||||
/// ```
|
||||
/// let max = tengri::w_max(3, "Hello");
|
||||
/// let max = tengri::w_max(None, "Hello");
|
||||
/// let max = tengri::w_max(Some(3), "Hello");
|
||||
/// use tengri::Layout;
|
||||
/// let _ = "".pad_w(1);
|
||||
/// let _ = "".pad_h(1);
|
||||
/// let _ = "".pad_wh(1, 1);
|
||||
/// ```
|
||||
pub enum Pad<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
||||
__(PhantomData<T>),
|
||||
|
|
@ -184,6 +281,59 @@ pub enum Pad<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
|
|||
WH(I, X, X),
|
||||
}
|
||||
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Pad<T, I, X>, to: T|{
|
||||
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Pad<T, I, X>, _to: T|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
pub struct Align<T>(Option<Azimuth>, T);
|
||||
|
||||
impl_draw!(<S: Screen, T: Draw<S>,>|self: Align<T>, _to: S|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// Where is [0, 0] located?
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// use Azimuth::*;
|
||||
/// let _ = "".align(NW);
|
||||
/// ```
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
#[derive(Debug, Copy, Clone, Default)] pub enum Azimuth {
|
||||
#[default] C, X, Y, NW, N, NE, E, SE, S, SW, W
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = area(None, "unareaed");
|
||||
/// let _ = area(XYWH(1, 2, 3, 4), "southeast");
|
||||
/// let _ = area(Some(XYWH(1, 2, 3, 4)), "southeast");
|
||||
/// ```
|
||||
pub fn area <S: Screen, T: Draw<S>, U: Into<Option<XYWH<S::Unit>>>> (
|
||||
origin: U, it: T
|
||||
) -> Area<S, T> {
|
||||
Area(origin.into(), it)
|
||||
}
|
||||
|
||||
pub struct Area<S: Screen, T: Draw<S>>(Option<XYWH<S::Unit>>, T);
|
||||
|
||||
impl_draw!(<S: Screen, T: Draw<S>,>|self: Area<S, T>, _to: S|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
pub struct Origin<T>(Option<Azimuth>, T);
|
||||
|
||||
impl_draw!(<S: Screen, T: Draw<S>,>|self: Origin<T>, _to: S|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// Something that has `[0, 0]` at a particular point.
|
||||
pub trait HasOrigin {
|
||||
fn origin (&self) -> Azimuth;
|
||||
}
|
||||
|
||||
impl<T: AsRef<Azimuth>> HasOrigin for T {
|
||||
fn origin (&self) -> Azimuth {
|
||||
*self.as_ref()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Origin<T>(Option<Azimuth>, T);
|
||||
|
||||
impl_draw!(<S: Screen, T: Draw<S>,>|self: Origin<T>, to: S|{
|
||||
todo!()
|
||||
});
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = origin(None, "origin unspecified");
|
||||
/// let _ = origin(Azimuth::SE, "southeast");
|
||||
/// let _ = origin(Some(Azimuth::SE), "southeast");
|
||||
/// ```
|
||||
pub fn origin <S: Screen, T: Draw<S>, U: Into<Option<Azimuth>>> (origin: U, it: T) -> Origin<T> {
|
||||
Origin(origin.into(), it)
|
||||
}
|
||||
|
||||
pub fn origin_c <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::C), it) }
|
||||
pub fn origin_x <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::X), it) }
|
||||
pub fn origin_y <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::Y), it) }
|
||||
|
||||
pub fn origin_n <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::N), it) }
|
||||
pub fn origin_s <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::S), it) }
|
||||
pub fn origin_e <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::E), it) }
|
||||
pub fn origin_w <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::W), it) }
|
||||
|
||||
pub fn origin_ne <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::NE), it) }
|
||||
pub fn origin_se <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::SE), it) }
|
||||
pub fn origin_nw <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::NW), it) }
|
||||
pub fn origin_sw <S: Screen, T: Draw<S>> (it: T) -> Origin<T> { Origin(Some(Azimuth::SW), it) }
|
||||
|
||||
/// Something that has `[0, 0]` at a particular point.
|
||||
pub trait HasOrigin {
|
||||
fn origin (&self) -> Azimuth;
|
||||
}
|
||||
|
||||
impl<T: AsRef<Azimuth>> HasOrigin for T {
|
||||
fn origin (&self) -> Azimuth {
|
||||
*self.as_ref()
|
||||
}
|
||||
}
|
||||
|
|
@ -39,20 +39,20 @@ pub const fn below <T: Screen> (a: impl Draw<T>, b: impl Draw<T>) -> impl Draw<T
|
|||
impl Split {
|
||||
|
||||
/// ```
|
||||
/// use tengri::draw::Split::*;
|
||||
/// let _ = Above.half("", "");
|
||||
/// let _ = Below.half("", "");
|
||||
/// let _ = North.half("", "");
|
||||
/// let _ = South.half("", "");
|
||||
/// let _ = East.half("", "");
|
||||
/// let _ = West.half("", "");
|
||||
/// use tengri::*;
|
||||
/// let _ = Split::Above.half("", "");
|
||||
/// let _ = Split::Below.half("", "");
|
||||
/// let _ = Split::North.half("", "");
|
||||
/// let _ = Split::South.half("", "");
|
||||
/// let _ = Split::East.half("", "");
|
||||
/// let _ = Split::West.half("", "");
|
||||
/// ```
|
||||
pub const fn half <T: Screen> (&self, a: impl Draw<T>, b: impl Draw<T>) -> impl Draw<T> {
|
||||
thunk(move|to: &mut T|{
|
||||
let (area_a, area_b) = to.xywh().split_half(self);
|
||||
let (origin_a, origin_b) = self.origins();
|
||||
let a = align(origin_a, a);
|
||||
let b = align(origin_b, b);
|
||||
let a = a.align(origin_a);
|
||||
let b = b.align(origin_b);
|
||||
match self {
|
||||
Self::Below => {
|
||||
to.show(area(area_b, b))?;
|
||||
|
|
@ -95,6 +95,21 @@ impl Split {
|
|||
}
|
||||
}
|
||||
|
||||
///// ```
|
||||
///// use tengri::*;
|
||||
///// let _ = Split::Below.iter([
|
||||
///// "Leftbar"
|
||||
///// .min_w(10).max_w(15).align(Azimuth::NW),
|
||||
///// "Rightbar"
|
||||
///// .min_w(10).max_w(12).align(Azimuth::NE),
|
||||
///// "Center"
|
||||
///// .min_w(20).max_w(40).align(Azimuth::C),
|
||||
///// ].iter());
|
||||
///// ```
|
||||
//pub fn iter <S: Screen, T: Draw<S>> (&self, _: impl Iterator<Item = T>) {
|
||||
//todo!()
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! north {
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ impl<T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> Draw<T> for Thunk<T,
|
|||
/// Basic [Draw]able closure.
|
||||
///
|
||||
/// ```
|
||||
/// # use tengri::{draw::*, term::*};
|
||||
/// # fn test () -> impl tengri::draw::Draw<tengri::term::Tui> {
|
||||
/// thunk(|to: &mut Tui|Ok(to.1))
|
||||
/// # use tengri::*;
|
||||
/// # fn test () -> impl Draw<Tui> {
|
||||
/// thunk(|to: &mut Tui|Ok(Some(to.1)))
|
||||
/// # }
|
||||
/// ```
|
||||
pub const fn thunk <T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> (
|
||||
|
|
@ -26,8 +26,8 @@ pub const fn thunk <T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> (
|
|||
/// Only render when condition is true.
|
||||
///
|
||||
/// ```
|
||||
/// # use tengri::{draw::*, term::*};
|
||||
/// # fn test () -> impl tengri::draw::Draw<tengri::term::Tui> {
|
||||
/// # use tengri::*;
|
||||
/// # fn test () -> impl Draw<Tui> {
|
||||
/// when(true, "Yes")
|
||||
/// # }
|
||||
/// ```
|
||||
|
|
@ -38,8 +38,8 @@ pub const fn when <T: Screen> (condition: bool, draw: impl Draw<T>) -> impl Draw
|
|||
/// Render one thing if a condition is true and another false.
|
||||
///
|
||||
/// ```
|
||||
/// # use tengri::{draw::*, term::*};
|
||||
/// # fn test () -> impl tengri::draw::Draw<tengri::term::Tui> {
|
||||
/// # use tengri::*;
|
||||
/// # fn test () -> impl Draw<Tui> {
|
||||
/// either(true, "Yes", "No")
|
||||
/// # }
|
||||
/// ```
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ pub trait Tall<N: Coord> {
|
|||
/// Point with size.
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::space::{XY, XYWH};
|
||||
/// # use tengri::*;
|
||||
/// let xywh = XYWH(0u16, 0, 0, 0);
|
||||
/// assert_eq!(XYWH(10u16, 10, 20, 20).center(), XY(20, 20));
|
||||
/// assert_eq!(XYWH(10u16, 10, 20, 20).center(), (20, 20));
|
||||
/// ```
|
||||
///
|
||||
/// * [ ] TODO: origin field (determines at which corner/side is X0 Y0)
|
||||
|
|
|
|||
124
src/eval.rs
124
src/eval.rs
|
|
@ -63,18 +63,19 @@ macro_rules! eval_enum ((
|
|||
/// Interpret layout operation.
|
||||
///
|
||||
/// ```
|
||||
/// # use tengri::{lang::*, draw::*, eval::*, term::*};
|
||||
/// # use tengri::{*, lang::*};
|
||||
///
|
||||
/// struct State {/*app-specific*/}
|
||||
/// impl<'b> Namespace<'b, bool> for State {}
|
||||
/// impl<'b> Namespace<'b, u16> for State {}
|
||||
/// impl Interpret<Tui, XYWH<u16>> for State {}
|
||||
/// impl<'b> Namespace<'b, bool> for State {}
|
||||
/// impl<'b> Namespace<'b, Option<u16>> for State {}
|
||||
/// impl Interpret<Tui, Option<XYWH<u16>>> for State {}
|
||||
///
|
||||
/// # fn main () -> tengri::Usually<()> {
|
||||
/// let state = State {};
|
||||
/// let mut target = Tui::new(80, 25);
|
||||
/// eval_view(&state, &mut target, &"")?;
|
||||
/// eval_view(&state, &mut target, &"(when true (text hello))")?;
|
||||
/// eval_view(&state, &mut target, &"(whe true (text hello))")?;
|
||||
/// eval_view(&state, &mut target, &"(either true (text hello) (text world))")?;
|
||||
/// // TODO test all
|
||||
/// # Ok(()) }
|
||||
|
|
@ -108,43 +109,33 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
|
|||
|
||||
Some("when") => when(
|
||||
state.namespace(arg0?)?.unwrap(),
|
||||
thunk(move|output: &mut O|{
|
||||
state.interpret(output, &arg1)
|
||||
})
|
||||
thunk(move|output: &mut O|{state.interpret(output, &arg1)})
|
||||
).draw(output),
|
||||
|
||||
Some("either") => either(
|
||||
state.namespace(arg0?)?.unwrap(),
|
||||
thunk(move|output: &mut O|{
|
||||
state.interpret(output, &arg1)
|
||||
}),
|
||||
thunk(move|output: &mut O|{
|
||||
state.interpret(output, &arg2)
|
||||
}),
|
||||
thunk(move|output: &mut O|{state.interpret(output, &arg1)}),
|
||||
thunk(move|output: &mut O|{state.interpret(output, &arg2)}),
|
||||
).draw(output),
|
||||
|
||||
// Second `frags.next()` calls returns the namespace member.
|
||||
Some("bsp") => {
|
||||
let direction = eval_enum!("bsp", output, state, frags.next(), arg0, Split {
|
||||
eval_enum!("bsp", output, state, frags.next(), arg0, Split {
|
||||
"n" => North,
|
||||
"s" => South,
|
||||
"e" => East,
|
||||
"w" => West,
|
||||
"a" => Above,
|
||||
"b" => Below
|
||||
});
|
||||
direction.half(
|
||||
thunk(move|output: &mut O|{
|
||||
state.interpret(output, &arg0)
|
||||
}),
|
||||
thunk(move|output: &mut O|{
|
||||
state.interpret(output, &arg1)
|
||||
}),
|
||||
}).half(
|
||||
thunk(move|output: &mut O|{state.interpret(output, &arg0)}),
|
||||
thunk(move|output: &mut O|{state.interpret(output, &arg1)}),
|
||||
).draw(output)
|
||||
},
|
||||
|
||||
Some("align") => {
|
||||
let alignment = eval_enum!("align", output, state, frags.next(), arg0, Azimuth {
|
||||
let content = thunk(move|output: &mut O|{state.interpret(output, &arg0)});
|
||||
content.align(eval_enum!("align", output, state, frags.next(), arg0, Azimuth {
|
||||
"c" => C,
|
||||
"n" => N,
|
||||
"s" => S,
|
||||
|
|
@ -152,11 +143,7 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
|
|||
"w" => W,
|
||||
"x" => X,
|
||||
"y" => Y
|
||||
});
|
||||
let content = thunk(move|output: &mut O|{
|
||||
state.interpret(output, &arg0)
|
||||
});
|
||||
align(alignment, content).draw(output)
|
||||
})).draw(output)
|
||||
},
|
||||
|
||||
Some("exact") => eval_xy!(
|
||||
|
|
@ -187,21 +174,50 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
|
|||
/// Interpret TUI-specific layout operation.
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::{lang::*, term::*, eval::*, ratatui::prelude::Color};
|
||||
/// use tengri::{*, lang::*, ratatui::prelude::Color};
|
||||
///
|
||||
/// #[namespace(bool {})]
|
||||
/// #[namespace(u8: try_to_u8)]
|
||||
/// #[namespace(u16: try_to_u16)]
|
||||
/// #[namespace(Color: try_to_color)]
|
||||
/// #[interpret(Tui -> Option<XYWH<u16>>: try_eval_tui)]
|
||||
/// struct State;
|
||||
/// impl<'b> Namespace<'b, bool> for State {}
|
||||
/// impl<'b> Namespace<'b, u16> for State {}
|
||||
/// impl<'b> Namespace<'b, Color> for State {}
|
||||
/// impl Interpret<Tui, ()> for State {}
|
||||
/// tengri::lang::primitive!(u8: try_to_u8);
|
||||
/// tengri::lang::primitive!(u16: try_to_u16);
|
||||
/// tengri::lang::namespace!(State: bool {
|
||||
/// });
|
||||
/// tengri::lang::namespace!(State: u8 {
|
||||
/// literal = |x|try_to_u8(x);
|
||||
/// });
|
||||
/// tengri::lang::namespace!(State: u16 {
|
||||
/// literal = |x|try_to_u16(x);
|
||||
/// });
|
||||
/// tengri::lang::namespace!(State: Color {
|
||||
/// expression = |_state| {
|
||||
/// "g" (x: u8) => { ItemTheme::G[x as usize].base.term }
|
||||
/// };
|
||||
/// });
|
||||
/// tengri::lang::interpret!(|self: State, context: Tui, lang|->Option<XYWH<u16>>{
|
||||
/// expression = {
|
||||
/// "text" (...rest) => { todo!() }
|
||||
/// }
|
||||
/// });
|
||||
/// impl Interpret<Tui, Option<XYWH<u16>>> for State {
|
||||
/// fn interpret_expr <'a> (&'a self, _: &mut Tui, lang: &'a impl Expression)
|
||||
/// -> Usually<Option<XYWH<u16>>>
|
||||
/// {
|
||||
/// Ok(None)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # fn main () -> tengri::Usually<()> {
|
||||
/// let state = State;
|
||||
/// let mut out = Tui::default();
|
||||
/// tengri::eval::eval_view_tui(&state, &mut out, "")?;
|
||||
/// tengri::eval::eval_view_tui(&state, &mut out, "text Hello world!")?;
|
||||
/// tengri::eval::eval_view_tui(&state, &mut out, "fg (g 0) (text Hello world!)")?;
|
||||
/// tengri::eval::eval_view_tui(&state, &mut out, "bg (g 2) (text Hello world!)")?;
|
||||
/// tengri::eval::eval_view_tui(&state, &mut out, "(bg (g 3) (fg (g 4) (text Hello world!)))")?;
|
||||
/// let mut out = Tui::new(80, 25);
|
||||
/// eval_view_tui(&state, &mut out, "")?;
|
||||
/// eval_view_tui(&state, &mut out, "text Hello world!")?;
|
||||
/// eval_view_tui(&state, &mut out, "fg (g 0) (text Hello world!)")?;
|
||||
/// eval_view_tui(&state, &mut out, "bg (g 2) (text Hello world!)")?;
|
||||
/// eval_view_tui(&state, &mut out, "(bg (g 3) (fg (g 4) (text Hello world!)))")?;
|
||||
/// # Ok(()) }
|
||||
/// ```
|
||||
pub fn eval_view_tui <'a, S> (
|
||||
|
|
@ -231,22 +247,28 @@ pub fn eval_view_tui <'a, S> (
|
|||
|
||||
Some("fg") => {
|
||||
let arg0 = arg0?.expect("fg: expected arg 0 (color)");
|
||||
let color = Namespace::namespace(state, arg0)?.unwrap_or_else(||panic!("fg: {arg0:?}: not a color"));
|
||||
output.show(fg(color, thunk(move|output: &mut Tui|{
|
||||
state.interpret(output, &arg1)?;
|
||||
// FIXME?: don't max out the used area?
|
||||
Ok(Some(output.area().into()))
|
||||
})))
|
||||
if let Some(color) = Namespace::namespace(state, arg0)? {
|
||||
output.show(fg(color, thunk(move|output: &mut Tui|{
|
||||
state.interpret(output, &arg1)?;
|
||||
// FIXME?: don't max out the used area?
|
||||
Ok(Some(output.area().into()))
|
||||
})))
|
||||
} else {
|
||||
return Err(format!("fg: {arg0:?}: not a color").into())
|
||||
}
|
||||
},
|
||||
|
||||
Some("bg") => {
|
||||
let arg0 = arg0?.expect("bg: expected arg 0 (color)");
|
||||
let color = Namespace::namespace(state, arg0)?.unwrap_or_else(||panic!("bg: {arg0:?}: not a color"));
|
||||
output.show(bg(color, thunk(move|output: &mut Tui|{
|
||||
state.interpret(output, &arg1)?;
|
||||
// FIXME?: don't max out the used area?
|
||||
Ok(Some(output.area().into()))
|
||||
})))
|
||||
if let Some(color) = Namespace::namespace(state, arg0)? {
|
||||
output.show(bg(color, thunk(move|output: &mut Tui|{
|
||||
state.interpret(output, &arg1)?;
|
||||
// FIXME?: don't max out the used area?
|
||||
Ok(Some(output.area().into()))
|
||||
})))
|
||||
} else {
|
||||
return Err(format!("bg: {arg0:?}: not a color").into())
|
||||
}
|
||||
},
|
||||
|
||||
_ => return Ok(None)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ pub type BoxedAudioHandler<'j> =
|
|||
/// Things that can provide a [jack::Client] reference.
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::sing::{Jack, HasJack};
|
||||
/// use tengri::*;
|
||||
///
|
||||
/// let jack: &Jack = Jacked::default().jack();
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{*, sing::*, time::PerfModel};
|
||||
use crate::{*, PerfModel};
|
||||
pub use ::jack::{*, contrib::{*, ClosureProcessHandler}};
|
||||
|
||||
use JackState::*;
|
||||
|
|
@ -6,7 +6,7 @@ use JackState::*;
|
|||
/// Wraps [JackState], and through it [jack::Client] when connected.
|
||||
///
|
||||
/// ```
|
||||
/// let jack = tengri::sing::Jack::default();
|
||||
/// let jack = tengri::Jack::default();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)] pub struct Jack<'j> (
|
||||
pub(crate) Arc<RwLock<JackState<'j>>>
|
||||
|
|
@ -17,7 +17,7 @@ use JackState::*;
|
|||
/// [jack::Client], which you can use to talk to the JACK API.
|
||||
///
|
||||
/// ```
|
||||
/// let state = tengri::sing::JackState::default();
|
||||
/// let state = tengri::JackState::default();
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub enum JackState<'j> {
|
||||
/// Unused
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ pub use ::jack::{*, contrib::{*, ClosureProcessHandler}};
|
|||
/// Event enum for JACK events.
|
||||
///
|
||||
/// ```
|
||||
/// let event = tengri::sing::JackEvent::XRun; // kerpop
|
||||
/// let event = tengri::JackEvent::XRun; // kerpop
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq)] pub enum JackEvent {
|
||||
ThreadInit,
|
||||
|
|
@ -22,7 +22,7 @@ pub use ::jack::{*, contrib::{*, ClosureProcessHandler}};
|
|||
/// Generic notification handler that emits [JackEvent]
|
||||
///
|
||||
/// ```
|
||||
/// let notify = tengri::sing::JackNotify(|_|{});
|
||||
/// let notify = tengri::JackNotify(|_|{});
|
||||
/// ```
|
||||
pub struct JackNotify<T: Fn(JackEvent) + Send>(pub T);
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ impl Tui {
|
|||
/// Implement standard [main] entrypoint for TUI apps.
|
||||
#[macro_export] macro_rules! tui_main {
|
||||
($state:expr) => {
|
||||
pub fn main () -> Usually<()> { tui_run_main($state) }
|
||||
pub fn main () -> Usually<()> { tui_run_main(Arc::new(RwLock::new($state))) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
use crate::{*, lang::*};
|
||||
use crate::*;
|
||||
use ratatui::{prelude::{Style, Position, Backend, Color}};
|
||||
|
||||
/// TUI works in u16 coordinates.
|
||||
impl Coord for u16 { fn plus (self, other: Self) -> Self { self.saturating_add(other) } }
|
||||
impl_draw!(|self: u64, _to: Tui|{ todo!() });
|
||||
impl_draw!(|self: f64, _to: Tui|{ todo!() });
|
||||
|
||||
impl Screen for Tui {
|
||||
type Unit = u16;
|
||||
|
|
@ -37,8 +35,15 @@ impl Screen for Tui {
|
|||
/// Spawn the TUI output thread which writes colored characters to the terminal.
|
||||
///
|
||||
/// ```
|
||||
/// let state = Arc::new(RwLock::new(()));
|
||||
/// Exit::run(|exit|tui_output(exit, state, sleep, stdout()))
|
||||
/// let state = std::sync::Arc::new(std::sync::RwLock::new(()));
|
||||
/// let _ = tengri::Exit::run(|exit|{
|
||||
/// tengri::tui_output(
|
||||
/// exit.as_ref(),
|
||||
/// &state,
|
||||
/// std::time::Duration::from_millis(10),
|
||||
/// std::io::stdout()
|
||||
/// )
|
||||
/// });
|
||||
/// ```
|
||||
pub fn tui_output <
|
||||
W: Write + Send + Sync + 'static, T: View<Tui> + Send + Sync + 'static
|
||||
|
|
@ -68,7 +73,7 @@ pub fn tui_output <
|
|||
})?)
|
||||
}
|
||||
|
||||
use self::colors::*; mod colors {
|
||||
pub use self::colors::*; mod colors {
|
||||
use ratatui::prelude::Color;
|
||||
pub const fn tui_color_bg () -> Color { Color::Rgb(28, 35, 25) }
|
||||
pub const fn tui_bg0 () -> Color { Color::Rgb(20, 20, 20) }
|
||||
|
|
@ -259,7 +264,7 @@ pub fn phat (w: u16, h: u16, [fg, bg, hi, lo]: [Color;4], draw: impl Draw<Tui>)
|
|||
south(top, north(low, draw)).min_wh(w, h)
|
||||
}
|
||||
|
||||
fn x_scroll () -> impl Draw<Tui> {
|
||||
pub fn x_scroll () -> impl Draw<Tui> {
|
||||
thunk(|Tui(buf, XYWH(x1, y1, w, h)): &mut Tui|{
|
||||
let x2 = *x1 + *w;
|
||||
for (i, x) in (*x1..=x2).enumerate() {
|
||||
|
|
@ -287,7 +292,7 @@ fn x_scroll () -> impl Draw<Tui> {
|
|||
})
|
||||
}
|
||||
|
||||
fn y_scroll () -> impl Draw<Tui> {
|
||||
pub fn y_scroll () -> impl Draw<Tui> {
|
||||
thunk(|Tui(buf, XYWH(x1, y1, w, h)): &mut Tui|{
|
||||
let y2 = *y1 + *h;
|
||||
for (i, y) in (*y1..=y2).enumerate() {
|
||||
|
|
@ -315,19 +320,16 @@ fn y_scroll () -> impl Draw<Tui> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn tui_update (
|
||||
Tui(buf, ..): &mut Tui,
|
||||
area: XYWH<u16>,
|
||||
callback: &impl Fn(&mut Cell, u16, u16)
|
||||
) {
|
||||
}
|
||||
|
||||
/// Draw TUI content or its error message.
|
||||
///
|
||||
/// ```
|
||||
/// let _ = tengri::term::catcher(Ok(Some("hello")));
|
||||
/// let _ = tengri::term::catcher(Ok(None));
|
||||
/// let _ = tengri::term::catcher(Err("draw fail".into()));
|
||||
/// for variant in [
|
||||
/// Ok(Some("hello")),
|
||||
/// Ok(None),
|
||||
/// Err("fail".into()),
|
||||
/// ] {
|
||||
/// let _ = tengri::catcher(variant);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn catcher <T: Draw<Tui>> (result: Usually<T>) -> impl Draw<Tui> {
|
||||
thunk(move|to: &mut Tui|match result {
|
||||
|
|
@ -341,3 +343,6 @@ pub fn catcher <T: Draw<Tui>> (result: Usually<T>) -> impl Draw<Tui> {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
impl_draw!(|self: u64, _to: Tui|{ todo!() });
|
||||
impl_draw!(|self: f64, _to: Tui|{ todo!() });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue