mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-07 04:06:48 +01:00
output: more big refactors
This commit is contained in:
parent
194f2f9874
commit
5e6338fad8
68 changed files with 1604 additions and 1016 deletions
|
|
@ -243,7 +243,7 @@ impl<T: FocusGrid + HasEnter> FocusOrder for T {
|
|||
}
|
||||
|
||||
pub trait FocusWrap<T> {
|
||||
fn wrap <W: Content<TuiOut>> (self, focus: T, content: &'_ W) -> impl Render<TuiOut> + '_;
|
||||
fn wrap <W: Content<TuiOut>> (self, focus: T, content: &'_ W) -> impl Draw<TuiOut> + '_;
|
||||
}
|
||||
|
||||
pub fn to_focus_command <T: Send + Sync> (input: &TuiIn) -> Option<FocusCommand<T>> {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Bordered<S, W>(pub bool, pub S, pub W);
|
||||
impl<S: BorderStyle, W: Render<TuiOut>> Content<TuiOut> for Bordered<S, W> {
|
||||
fn content (&self) -> Option<impl Render<TuiOut> + '_> {
|
||||
Some(Fill::xy(
|
||||
lay!(When::new(self.0, Border(self.0, self.1)), Padding::xy(1, 1, &self.2))
|
||||
impl<S: BorderStyle, W: Draw<TuiOut> + Layout<TuiOut>> Content<TuiOut> for Bordered<S, W> {
|
||||
fn content (&self) -> impl Draw<TuiOut> + Layout<TuiOut> + '_ {
|
||||
Fill::xy(lay!(
|
||||
When::new(self.0, Border(self.0, self.1)),
|
||||
Padding::xy(1, 1, &self.2)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Border<S: BorderStyle>(pub bool, pub S);
|
||||
impl<S: BorderStyle> Render<TuiOut> for Border<S> {
|
||||
fn layout (&self, area: [u16;4]) -> [u16;4] {
|
||||
self.1.layout(area)
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
impl<S: BorderStyle> Draw<TuiOut> for Border<S> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
if self.0 {
|
||||
let area = to.area();
|
||||
if area.w() > 0 && area.y() > 0 {
|
||||
|
|
@ -35,15 +31,15 @@ impl<S: BorderStyle> Render<TuiOut> for Border<S> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait BorderStyle: Render<TuiOut> + Copy {
|
||||
pub trait BorderStyle: Draw<TuiOut> + Layout<TuiOut> + Copy {
|
||||
fn enabled (&self) -> bool;
|
||||
fn enclose <W: Render<TuiOut>> (self, w: W) -> impl Render<TuiOut> {
|
||||
fn enclose (self, w: impl Draw<TuiOut> + Layout<TuiOut>) -> impl Draw<TuiOut> + Layout<TuiOut> {
|
||||
Bsp::b(Fill::xy(Border(self.enabled(), self)), w)
|
||||
}
|
||||
fn enclose2 <W: Render<TuiOut>> (self, w: W) -> impl Render<TuiOut> {
|
||||
fn enclose2 (self, w: impl Draw<TuiOut> + Layout<TuiOut>) -> impl Draw<TuiOut> + Layout<TuiOut> {
|
||||
Bsp::b(Margin::xy(1, 1, Fill::xy(Border(self.enabled(), self))), w)
|
||||
}
|
||||
fn enclose_bg <W: Render<TuiOut>> (self, w: W) -> impl Render<TuiOut> {
|
||||
fn enclose_bg (self, w: impl Draw<TuiOut> + Layout<TuiOut>) -> impl Draw<TuiOut> + Layout<TuiOut> {
|
||||
Tui::bg(self.style().unwrap().bg.unwrap_or(Color::Reset),
|
||||
Bsp::b(Fill::xy(Border(self.enabled(), self)), w))
|
||||
}
|
||||
|
|
@ -147,9 +143,10 @@ macro_rules! border {
|
|||
fn enabled (&self) -> bool { self.0 }
|
||||
}
|
||||
#[derive(Copy, Clone)] pub struct $T(pub bool, pub Style);
|
||||
impl Render<TuiOut> for $T {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
if self.enabled() { let _ = self.draw(to); }
|
||||
impl Layout<TuiOut> for $T {}
|
||||
impl Draw<TuiOut> for $T {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
if self.enabled() { let _ = BorderStyle::draw(self, to); }
|
||||
}
|
||||
}
|
||||
)+}
|
||||
|
|
@ -260,11 +257,3 @@ border! {
|
|||
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//impl<S: BorderStyle, R: Content<TuiOut>> Content<TuiOut> for Bordered<S, R> {
|
||||
//fn content (&self) -> impl Render<TuiOut> {
|
||||
//let content: &dyn Content<TuiOut> = &self.1;
|
||||
//lay! { content.padding_xy(1, 1), Border(self.0) }.fill_xy()
|
||||
//}
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1 +1,38 @@
|
|||
//use crate::{*, Color::*};
|
||||
use crate::{*, Color::*};
|
||||
|
||||
pub fn button_2 <'a> (
|
||||
key: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
||||
label: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
||||
editing: bool,
|
||||
) -> impl Draw<TuiOut> + Layout<TuiOut> + 'a {
|
||||
let key = Tui::fg_bg(Tui::orange(), Tui::g(0), Bsp::e(
|
||||
Tui::fg(Tui::g(0), "▐"),
|
||||
Bsp::e(key, Tui::fg(Tui::g(96), "▐"))
|
||||
));
|
||||
let label = When::new(!editing, Tui::fg_bg(Tui::g(255), Tui::g(96), label));
|
||||
Tui::bold(true, Bsp::e(key, label))
|
||||
}
|
||||
|
||||
pub fn button_3 <'a> (
|
||||
key: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
||||
label: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
||||
value: impl Draw<TuiOut> + Layout<TuiOut> + 'a,
|
||||
editing: bool,
|
||||
) -> impl Draw<TuiOut> + Layout<TuiOut> + 'a {
|
||||
let key = Tui::fg_bg(Tui::orange(), Tui::g(0),
|
||||
Bsp::e(Tui::fg(Tui::g(0), "▐"), Bsp::e(key, Tui::fg(if editing {
|
||||
Tui::g(128)
|
||||
} else {
|
||||
Tui::g(96)
|
||||
}, "▐"))));
|
||||
let label = Bsp::e(
|
||||
When::new(!editing, Bsp::e(
|
||||
Tui::fg_bg(Tui::g(255), Tui::g(96), label),
|
||||
Tui::fg_bg(Tui::g(128), Tui::g(96), "▐"),
|
||||
)),
|
||||
Bsp::e(
|
||||
Tui::fg_bg(Tui::g(224), Tui::g(128), value),
|
||||
Tui::fg_bg(Tui::g(128), Reset, "▌"),
|
||||
));
|
||||
Tui::bold(true, Bsp::e(key, label))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,26 +2,28 @@ use crate::*;
|
|||
use ratatui::style::Stylize;
|
||||
|
||||
// Thunks can be natural error boundaries!
|
||||
pub struct ErrorBoundary<O: Output, T: Render<O>>(
|
||||
pub struct ErrorBoundary<O: Out, T: Draw<O>>(
|
||||
std::marker::PhantomData<O>, Perhaps<T>
|
||||
);
|
||||
|
||||
impl<O: Output, T: Render<O>> ErrorBoundary<O, T> {
|
||||
impl<O: Out, T: Draw<O>> ErrorBoundary<O, T> {
|
||||
pub fn new (content: Perhaps<T>) -> Self {
|
||||
Self(Default::default(), content)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Render<TuiOut>> Render<TuiOut> for ErrorBoundary<TuiOut, T> {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
impl<T: Draw<TuiOut>> Draw<TuiOut> for ErrorBoundary<TuiOut, T> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
match self.1.as_ref() {
|
||||
Ok(Some(content)) => content.render(to),
|
||||
Ok(Some(content)) => content.draw(to),
|
||||
Ok(None) => to.blit(&"empty?", 0, 0, Some(Style::default().yellow())),
|
||||
Err(e) => Tui::fg_bg(
|
||||
Color::Rgb(255,224,244), Color::Rgb(96,24,24), Bsp::s(
|
||||
Bsp::e(Tui::bold(true, "oops. "), "rendering failed."),
|
||||
Bsp::e("\"why?\" ", Tui::bold(true, &format!("{e}"))))
|
||||
).render(to)
|
||||
Err(e) => {
|
||||
let err_fg = Color::Rgb(255,224,244);
|
||||
let err_bg = Color::Rgb(96,24,24);
|
||||
let title = Bsp::e(Tui::bold(true, "oops. "), "rendering failed.");
|
||||
let error = Bsp::e("\"why?\" ", Tui::bold(true, format!("{e}")));
|
||||
to.place(&Tui::fg_bg(err_fg, err_bg, Bsp::s(title, error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,34 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct FieldH<T, U>(pub ItemTheme, pub T, pub U);
|
||||
impl<T: Render<TuiOut>, U: Render<TuiOut>> Content<TuiOut> for FieldH<T, U> {
|
||||
fn content (&self) -> Option<impl Render<TuiOut> + '_> {
|
||||
impl<
|
||||
Label: Draw<TuiOut> + Layout<TuiOut>,
|
||||
Value: Draw<TuiOut> + Layout<TuiOut>
|
||||
> Content<TuiOut> for FieldH<ItemTheme, Label, Value> {
|
||||
fn content (&self) -> impl Draw<TuiOut> + Layout<TuiOut> + '_ {
|
||||
let Self(ItemTheme { darkest, dark, lightest, .. }, title, value) = self;
|
||||
Some(row!(
|
||||
row!(
|
||||
Tui::fg_bg(dark.rgb, darkest.rgb, "▐"),
|
||||
Tui::fg_bg(lightest.rgb, dark.rgb, title),
|
||||
Tui::fg_bg(dark.rgb, darkest.rgb, "▌"),
|
||||
Tui::fg_bg(lightest.rgb, darkest.rgb, Tui::bold(true, value)),
|
||||
))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FieldV<T, U>(pub ItemTheme, pub T, pub U);
|
||||
impl<T: Render<TuiOut>, U: Render<TuiOut>> Content<TuiOut> for FieldV<T, U> {
|
||||
fn content (&self) -> Option<impl Render<TuiOut> + '_> {
|
||||
impl<
|
||||
Label: Draw<TuiOut> + Layout<TuiOut>,
|
||||
Value: Draw<TuiOut> + Layout<TuiOut>
|
||||
> Content<TuiOut> for FieldV<ItemTheme, Label, Value> {
|
||||
fn content (&self) -> impl Draw<TuiOut> + Layout<TuiOut> + '_ {
|
||||
let Self(ItemTheme { darkest, dark, lightest, .. }, title, value) = self;
|
||||
Some(Bsp::n(
|
||||
Bsp::n(
|
||||
Align::w(Tui::bg(darkest.rgb, Tui::fg(lightest.rgb, Tui::bold(true, value)))),
|
||||
Fill::x(Align::w(row!(
|
||||
Tui::bg(darkest.rgb, Tui::fg(dark.rgb, "▐")),
|
||||
Tui::bg(dark.rgb, Tui::fg(lightest.rgb, title)),
|
||||
Tui::bg(darkest.rgb, Tui::fg(dark.rgb, "▌")),
|
||||
)))
|
||||
))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -40,9 +44,9 @@ pub struct Field<T, U> {
|
|||
pub value_bg: Option<ItemColor>,
|
||||
pub value_align: Option<Direction>,
|
||||
}
|
||||
impl<T: Render<TuiOut>, U: Render<TuiOut>> Content<TuiOut> for Field<T, U> {
|
||||
fn content (&self) -> Option<impl Render<TuiOut> + '_> {
|
||||
Some("TODO")
|
||||
impl<T: Draw<TuiOut>, U: Draw<TuiOut>> Content<TuiOut> for Field<T, U> {
|
||||
fn content (&self) -> impl Draw<TuiOut> + Layout<TuiOut> + '_ {
|
||||
"TODO"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use crate::*;
|
||||
|
||||
impl Render<TuiOut> for u64 {
|
||||
fn render (&self, _to: &mut TuiOut) {
|
||||
impl Draw<TuiOut> for u64 {
|
||||
fn draw (&self, _to: &mut TuiOut) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render<TuiOut> for f64 {
|
||||
fn render (&self, _to: &mut TuiOut) {
|
||||
impl Draw<TuiOut> for f64 {
|
||||
fn draw (&self, _to: &mut TuiOut) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,28 +8,26 @@ pub struct Phat<T> {
|
|||
pub content: T,
|
||||
pub colors: [Color;4],
|
||||
}
|
||||
|
||||
impl<T> Phat<T> {
|
||||
pub const LO: &'static str = "▄";
|
||||
pub const HI: &'static str = "▀";
|
||||
/// A phat line
|
||||
pub fn lo (fg: Color, bg: Color) -> impl Render<TuiOut> {
|
||||
pub fn lo (fg: Color, bg: Color) -> impl Draw<TuiOut> + Layout<TuiOut> {
|
||||
Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(Self::LO)))
|
||||
}
|
||||
/// A phat line
|
||||
pub fn hi (fg: Color, bg: Color) -> impl Render<TuiOut> {
|
||||
pub fn hi (fg: Color, bg: Color) -> impl Draw<TuiOut> + Layout<TuiOut> {
|
||||
Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(Self::HI)))
|
||||
}
|
||||
}
|
||||
impl<T: Render<TuiOut>> Content<TuiOut> for Phat<T> {
|
||||
fn content (&self) -> Option<impl Render<TuiOut> + '_> {
|
||||
|
||||
impl<T: Layout<TuiOut> + Draw<TuiOut>> Content<TuiOut> for Phat<T> {
|
||||
fn content (&self) -> impl Draw<TuiOut> + Layout<TuiOut> + '_ {
|
||||
let [fg, bg, hi, lo] = self.colors;
|
||||
let top = Fixed::y(1, Self::lo(bg, hi));
|
||||
let low = Fixed::y(1, Self::hi(bg, lo));
|
||||
let content = Tui::fg_bg(fg, bg, &self.content);
|
||||
Some(Min::xy(
|
||||
self.width,
|
||||
self.height,
|
||||
Bsp::s(top, Bsp::n(low, Fill::xy(content)))
|
||||
))
|
||||
Min::xy(self.width, self.height, Bsp::s(top, Bsp::n(low, Fill::xy(content))))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ use crate::*;
|
|||
use ratatui::prelude::Position;
|
||||
|
||||
pub struct Repeat<'a>(pub &'a str);
|
||||
impl Render<TuiOut> for Repeat<'_> {
|
||||
impl Layout<TuiOut> for Repeat<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
to
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
}
|
||||
impl Draw<TuiOut> for Repeat<'_> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let [x, y, w, h] = to.area().xywh();
|
||||
let a = self.0.len();
|
||||
for (_v, y) in (y..y+h).enumerate() {
|
||||
|
|
@ -21,11 +23,13 @@ impl Render<TuiOut> for Repeat<'_> {
|
|||
}
|
||||
|
||||
pub struct RepeatV<'a>(pub &'a str);
|
||||
impl Render<TuiOut> for RepeatV<'_> {
|
||||
impl Layout<TuiOut> for RepeatV<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
to
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
}
|
||||
impl Draw<TuiOut> for RepeatV<'_> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let [x, y, _w, h] = to.area().xywh();
|
||||
for y in y..y+h {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
|
|
@ -36,11 +40,13 @@ impl Render<TuiOut> for RepeatV<'_> {
|
|||
}
|
||||
|
||||
pub struct RepeatH<'a>(pub &'a str);
|
||||
impl Render<TuiOut> for RepeatH<'_> {
|
||||
impl Layout<TuiOut> for RepeatH<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
to
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
}
|
||||
impl Draw<TuiOut> for RepeatH<'_> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let [x, y, w, _h] = to.area().xywh();
|
||||
for x in x..x+w {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ impl ScrollbarH {
|
|||
const ICON_INC: &[char] = &[' ', '🞂', ' '];
|
||||
}
|
||||
|
||||
impl Render<TuiOut> for ScrollbarV {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
impl Draw<TuiOut> for ScrollbarV {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let [x, y1, _w, h] = to.area().xywh();
|
||||
let y2 = y1 + h;
|
||||
for (i, y) in (y1..=y2).enumerate() {
|
||||
|
|
@ -51,8 +51,8 @@ impl Render<TuiOut> for ScrollbarV {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render<TuiOut> for ScrollbarH {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
impl Draw<TuiOut> for ScrollbarH {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let [x1, y, w, _h] = to.area().xywh();
|
||||
let x2 = x1 + w;
|
||||
for (i, x) in (x1..=x2).enumerate() {
|
||||
|
|
|
|||
|
|
@ -2,26 +2,17 @@ use crate::*;
|
|||
use crate::ratatui::prelude::Position;
|
||||
use unicode_width::{UnicodeWidthStr, UnicodeWidthChar};
|
||||
|
||||
impl_content_layout_render!(TuiOut: |self: &str, to|
|
||||
layout = to.center_xy([width_chars_max(to.w(), self), 1]);
|
||||
render = {let [x, y, w, ..] = Render::layout(self, to.area());
|
||||
to.text(self, x, y, w)});
|
||||
tui_layout!(|self: &str, to|to.center_xy([width_chars_max(to.w(), self), 1]));
|
||||
tui_draw!(|self: &str, to|{
|
||||
let [x, y, w, ..] = self.layout(to.area());
|
||||
to.text(&self, x, y, w)
|
||||
});
|
||||
|
||||
impl_content_layout_render!(TuiOut: |self: String, to|
|
||||
layout = Render::<TuiOut>::layout(&self.as_str(), to);
|
||||
render = Render::<TuiOut>::render(&self.as_str(), to));
|
||||
tui_layout!(|self: Arc<str>, to|self.as_ref().layout(to));
|
||||
tui_draw!(|self: Arc<str>, to|self.as_ref().draw(to));
|
||||
|
||||
impl_content_layout_render!(TuiOut: |self: Arc<str>, to|
|
||||
layout = Render::<TuiOut>::layout(&self.as_ref(), to);
|
||||
render = Render::<TuiOut>::render(&self.as_ref(), to));
|
||||
|
||||
impl_content_layout_render!(TuiOut: |self: std::sync::RwLock<String>, to|
|
||||
layout = Render::<TuiOut>::layout(&self.read().unwrap(), to);
|
||||
render = Render::<TuiOut>::render(&self.read().unwrap(), to));
|
||||
|
||||
impl_content_layout_render!(TuiOut: |self: std::sync::RwLockReadGuard<'_, String>, to|
|
||||
layout = Render::<TuiOut>::layout(&**self, to);
|
||||
render = Render::<TuiOut>::render(&**self, to));
|
||||
tui_layout!(|self: String, to|self.as_str().layout(to));
|
||||
tui_draw!(|self: String, to|self.as_str().draw(to));
|
||||
|
||||
fn width_chars_max (max: u16, text: impl AsRef<str>) -> u16 {
|
||||
let mut width: u16 = 0;
|
||||
|
|
@ -61,12 +52,14 @@ impl<'a, T: AsRef<str>> TrimString<T> {
|
|||
TrimStringRef(self.0, &self.1)
|
||||
}
|
||||
}
|
||||
impl<'a, T: AsRef<str>> Render<TuiOut> for TrimString<T> {
|
||||
impl<'a, T: AsRef<str>> Layout<TuiOut> for TrimString<T> {
|
||||
fn layout (&self, to: [u16; 4]) -> [u16;4] {
|
||||
Render::layout(&self.as_ref(), to)
|
||||
Layout::layout(&self.as_ref(), to)
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
Render::render(&self.as_ref(), to)
|
||||
}
|
||||
impl<'a, T: AsRef<str>> Draw<TuiOut> for TrimString<T> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
Draw::draw(&self.as_ref(), to)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -75,11 +68,13 @@ impl<'a, T: AsRef<str>> Render<TuiOut> for TrimString<T> {
|
|||
/// Width is computed using [unicode_width].
|
||||
pub struct TrimStringRef<'a, T: AsRef<str>>(pub u16, pub &'a T);
|
||||
|
||||
impl<T: AsRef<str>> Render<TuiOut> for TrimStringRef<'_, T> {
|
||||
impl<T: AsRef<str>> Layout<TuiOut> for TrimStringRef<'_, T> {
|
||||
fn layout (&self, to: [u16; 4]) -> [u16;4] {
|
||||
[to.x(), to.y(), to.w().min(self.0).min(self.1.as_ref().width() as u16), to.h()]
|
||||
}
|
||||
fn render (&self, target: &mut TuiOut) {
|
||||
}
|
||||
impl<T: AsRef<str>> Draw<TuiOut> for TrimStringRef<'_, T> {
|
||||
fn draw (&self, target: &mut TuiOut) {
|
||||
let area = target.area();
|
||||
let mut width: u16 = 1;
|
||||
let mut chars = self.1.as_ref().chars();
|
||||
|
|
|
|||
|
|
@ -1,70 +1 @@
|
|||
use crate::*;
|
||||
|
||||
pub trait TuiStyle {
|
||||
fn fg <R: Render<TuiOut>> (color: Color, w: R) -> Foreground<R> {
|
||||
Foreground(color, w)
|
||||
}
|
||||
fn bg <R: Render<TuiOut>> (color: Color, w: R) -> Background<R> {
|
||||
Background(color, w)
|
||||
}
|
||||
fn fg_bg <R: Render<TuiOut>> (fg: Color, bg: Color, w: R) -> Background<Foreground<R>> {
|
||||
Background(bg, Foreground(fg, w))
|
||||
}
|
||||
fn modify <R: Render<TuiOut>> (enable: bool, modifier: Modifier, w: R) -> Modify<R> {
|
||||
Modify(enable, modifier, w)
|
||||
}
|
||||
fn bold <R: Render<TuiOut>> (enable: bool, w: R) -> Modify<R> {
|
||||
Self::modify(enable, Modifier::BOLD, w)
|
||||
}
|
||||
fn border <R: Render<TuiOut>, S: BorderStyle> (enable: bool, style: S, w: R) -> Bordered<S, R> {
|
||||
Bordered(enable, style, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl TuiStyle for Tui {}
|
||||
|
||||
pub struct Foreground<R>(pub Color, pub R);
|
||||
impl<R: Render<TuiOut>> Render<TuiOut> for Foreground<R> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
self.1.layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let area = self.layout(to.area());
|
||||
to.fill_fg(area, self.0);
|
||||
to.place(area, &self.1);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Background<R>(pub Color, pub R);
|
||||
impl<R: Render<TuiOut>> Render<TuiOut> for Background<R> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
self.1.layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let area = self.layout(to.area());
|
||||
to.fill_bg(area, self.0);
|
||||
to.place(area, &self.1);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Modify<R: Render<TuiOut>>(pub bool, pub Modifier, pub R);
|
||||
impl<R: Render<TuiOut>> Render<TuiOut> for Modify<R> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
self.2.layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
to.fill_mod(to.area(), self.0, self.1);
|
||||
self.2.render(to)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Styled<R: Render<TuiOut>>(pub Option<Style>, pub R);
|
||||
impl<R: Render<TuiOut>> Render<TuiOut> for Styled<R> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
self.1.layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
to.place(self.1.layout(to.area()), &self.1);
|
||||
// TODO write style over area
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +1,13 @@
|
|||
use crate::*;
|
||||
|
||||
/// A three-column layout.
|
||||
pub struct Tryptich<A, B, C> {
|
||||
pub top: bool,
|
||||
pub h: u16,
|
||||
pub left: (u16, A),
|
||||
pub middle: (u16, B),
|
||||
pub right: (u16, C),
|
||||
}
|
||||
|
||||
impl Tryptich<(), (), ()> {
|
||||
pub fn center (h: u16) -> Self {
|
||||
Self { h, top: false, left: (0, ()), middle: (0, ()), right: (0, ()) }
|
||||
}
|
||||
pub fn top (h: u16) -> Self {
|
||||
Self { h, top: true, left: (0, ()), middle: (0, ()), right: (0, ()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, C> Tryptich<A, B, C> {
|
||||
pub fn left <D> (self, w: u16, content: D) -> Tryptich<D, B, C> {
|
||||
Tryptich { left: (w, content), ..self }
|
||||
}
|
||||
pub fn middle <D> (self, w: u16, content: D) -> Tryptich<A, D, C> {
|
||||
Tryptich { middle: (w, content), ..self }
|
||||
}
|
||||
pub fn right <D> (self, w: u16, content: D) -> Tryptich<A, B, D> {
|
||||
Tryptich { right: (w, content), ..self }
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, C> Content<TuiOut> for Tryptich<A, B, C>
|
||||
where A: Render<TuiOut>, B: Render<TuiOut>, C: Render<TuiOut> {
|
||||
fn content (&self) -> Option<impl Render<TuiOut> + '_> {
|
||||
impl<
|
||||
A: Draw<TuiOut> + Layout<TuiOut>,
|
||||
B: Draw<TuiOut> + Layout<TuiOut>,
|
||||
C: Draw<TuiOut> + Layout<TuiOut>,
|
||||
> Content<TuiOut> for Tryptich<A, B, C> {
|
||||
fn content (&self) -> impl Draw<TuiOut> + Layout<TuiOut> + '_ {
|
||||
let Self { top, h, left: (w_a, ref a), middle: (w_b, ref b), right: (w_c, ref c) } = *self;
|
||||
Some(Fixed::y(h, if top {
|
||||
Fixed::y(h, if top {
|
||||
Bsp::a(
|
||||
Fill::x(Align::n(Fixed::x(w_b, Align::x(Tui::bg(Color::Reset, b))))),
|
||||
Bsp::a(
|
||||
|
|
@ -50,7 +23,7 @@ where A: Render<TuiOut>, B: Render<TuiOut>, C: Render<TuiOut> {
|
|||
Fill::xy(Align::e(Fixed::x(w_c, Tui::bg(Color::Reset, c)))),
|
||||
),
|
||||
)
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue