mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-01-31 10:56:41 +01:00
Compare commits
2 commits
3ebdf9e71f
...
41fa55fa6c
| Author | SHA1 | Date | |
|---|---|---|---|
| 41fa55fa6c | |||
| 90fc869e14 |
13 changed files with 86 additions and 91 deletions
3
.editorconfig
Normal file
3
.editorconfig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
root = true
|
||||
[*]
|
||||
max_line_length = 132
|
||||
|
|
@ -35,3 +35,11 @@ pub trait Eval<Args, RetVal> {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn wrap_inc (index: usize, count: usize) -> usize {
|
||||
if count > 0 { (index + 1) % count } else { 0 }
|
||||
}
|
||||
|
||||
pub fn wrap_dec (index: usize, count: usize) -> usize {
|
||||
if count > 0 { index.overflowing_sub(1).0.min(count.saturating_sub(1)) } else { 0 }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ 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() }
|
||||
|
|
|
|||
|
|
@ -2,28 +2,30 @@ use crate::*;
|
|||
|
||||
/// A widget that tracks its render width and height
|
||||
#[derive(Default)]
|
||||
pub struct Measure<E: Out> {
|
||||
_engine: PhantomData<E>,
|
||||
pub struct Measure<O: Out> {
|
||||
_engine: PhantomData<O>,
|
||||
pub x: 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 {
|
||||
self.x.load(Relaxed) == other.x.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
|
||||
impl<E: Out> Draw<E> for Measure<E> {
|
||||
fn draw (&self, to: &mut E) {
|
||||
impl<O: Out> Draw<O> for Measure<O> {
|
||||
fn draw (&self, to: &mut O) {
|
||||
self.x.store(to.area().w().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 {
|
||||
Self {
|
||||
_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> {
|
||||
f.debug_struct("Measure")
|
||||
.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 {
|
||||
Self {
|
||||
_engine: PhantomData::default(),
|
||||
|
|
@ -75,7 +77,7 @@ impl<E: Out> Measure<E> {
|
|||
pub fn format (&self) -> Arc<str> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ pub(crate) fn write_quote_to (out: &mut TokenStream2, quote: TokenStream2) {
|
|||
//#[tengri_proc::view(SomeOut)]
|
||||
//impl SomeView {
|
||||
//#[tengri::view(":view-1")]
|
||||
//fn view_1 (&self) -> impl Draw<SomeOut> + use<'_> {
|
||||
//fn view_1 (&self) -> impl Content<SomeOut> + use<'_> {
|
||||
//"view-1"
|
||||
//}
|
||||
//}
|
||||
|
|
@ -114,13 +114,13 @@ pub(crate) fn write_quote_to (out: &mut TokenStream2, quote: TokenStream2) {
|
|||
//let written = quote! { #parsed };
|
||||
//assert_eq!(format!("{written}"), format!("{}", quote! {
|
||||
//impl SomeView {
|
||||
//fn view_1 (&self) -> impl Draw<SomeOut> + use<'_> {
|
||||
//fn view_1 (&self) -> impl Content<SomeOut> + use<'_> {
|
||||
//"view-1"
|
||||
//}
|
||||
//}
|
||||
///// Generated by [tengri_proc].
|
||||
//impl ::tengri::output::Content<SomeOut> for SomeView {
|
||||
//fn content (&self) -> impl Draw<SomeOut> {
|
||||
//fn content (&self) -> impl Content<SomeOut> {
|
||||
//self.size.of(::tengri::output::View(self, self.config.view))
|
||||
//}
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -12,25 +12,25 @@ fn main () {}
|
|||
|
||||
//#[tengri_proc::view(TuiOut)]
|
||||
//impl Example {
|
||||
//pub fn title (&self) -> impl Draw<TuiOut> + use<'_> {
|
||||
//pub fn title (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
//Tui::bg(Color::Rgb(60, 10, 10), Push::y(1, Align::n(format!("Example {}/{}:", self.0 + 1, VIEWS.len())))).boxed()
|
||||
//}
|
||||
//pub fn code (&self) -> impl Draw<TuiOut> + use<'_> {
|
||||
//pub fn code (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
//Tui::bg(Color::Rgb(10, 60, 10), Push::y(2, Align::n(format!("{}", VIEWS[self.0])))).boxed()
|
||||
//}
|
||||
//pub fn hello (&self) -> impl Draw<TuiOut> + use<'_> {
|
||||
//pub fn hello (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
//Tui::bg(Color::Rgb(10, 100, 10), "Hello").boxed()
|
||||
//}
|
||||
//pub fn world (&self) -> impl Draw<TuiOut> + use<'_> {
|
||||
//pub fn world (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
//Tui::bg(Color::Rgb(100, 10, 10), "world").boxed()
|
||||
//}
|
||||
//pub fn hello_world (&self) -> impl Draw<TuiOut> + use<'_> {
|
||||
//pub fn hello_world (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
//"Hello world!".boxed()
|
||||
//}
|
||||
//pub fn map_e (&self) -> impl Draw<TuiOut> + use<'_> {
|
||||
//pub fn map_e (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
//Map::east(5u16, ||0..5u16, |n, _i|format!("{n}")).boxed()
|
||||
//}
|
||||
//pub fn map_s (&self) -> impl Draw<TuiOut> + use<'_> {
|
||||
//pub fn map_s (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
//Map::south(5u16, ||0..5u16, |n, _i|format!("{n}")).boxed()
|
||||
//}
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -18,31 +18,31 @@ mod tui_scroll; pub use self::tui_scroll::*;
|
|||
mod tui_string; pub use self::tui_string::*;
|
||||
mod tui_number; //pub use self::tui_number::*;
|
||||
mod tui_tryptich; //pub use self::tui_tryptich::*;
|
||||
impl<T: Content<TuiOut>> Draw<TuiOut> for Foreground<Color, T> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let area = self.layout(to.area());
|
||||
to.fill_fg(area, self.0);
|
||||
to.place_at(area, &self.1);
|
||||
}
|
||||
}
|
||||
impl<T: Content<TuiOut>> Draw<TuiOut> for Background<Color, T> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let area = self.layout(to.area());
|
||||
to.fill_bg(area, self.0);
|
||||
to.place_at(area, &self.1);
|
||||
}
|
||||
}
|
||||
pub struct Modify<T>(pub bool, pub Modifier, pub T);
|
||||
pub struct Styled<T>(pub Option<Style>, pub T);
|
||||
impl<T: Draw<TuiOut>> Draw<TuiOut> for Foreground<Color, T> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let area = self.layout(to.area());
|
||||
to.fill_fg(area, self.0.0);
|
||||
to.place_at(area, &self.0.1);
|
||||
}
|
||||
}
|
||||
impl<T: Draw<TuiOut>> Draw<TuiOut> for Background<Color, T> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let area = self.layout(to.area());
|
||||
to.fill_bg(area, self.0.0);
|
||||
to.place_at(area, &self.0.1);
|
||||
}
|
||||
}
|
||||
impl<T: Draw<TuiOut>> Layout<TuiOut> for Modify<T> {}
|
||||
impl<T: Draw<TuiOut>> Draw<TuiOut> for Modify<T> {
|
||||
impl<T: Content<TuiOut>> Layout<TuiOut> for Modify<T> {}
|
||||
impl<T: Content<TuiOut>> Draw<TuiOut> for Modify<T> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
to.fill_mod(to.area(), self.0, self.1);
|
||||
self.2.draw(to)
|
||||
}
|
||||
}
|
||||
impl<T: Draw<TuiOut>> Layout<TuiOut> for Styled<T> {}
|
||||
impl<T: Draw<TuiOut>> Draw<TuiOut> for Styled<T> {
|
||||
pub struct Styled<T>(pub Option<Style>, pub T);
|
||||
impl<T: Content<TuiOut>> Layout<TuiOut> for Styled<T> {}
|
||||
impl<T: Content<TuiOut>> Draw<TuiOut> for Styled<T> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
to.place(&self.1);
|
||||
// TODO write style over area
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ impl<S: BorderStyle, W: Content<TuiOut>> HasContent<TuiOut> for Bordered<S, W> {
|
|||
|
||||
impl<S: BorderStyle> Draw<TuiOut> for Border<S> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let Border(enabled, style) = self.0;
|
||||
if enabled {
|
||||
let Border(enabled, style) = self;
|
||||
if *enabled {
|
||||
let area = to.area();
|
||||
if area.w() > 0 && area.y() > 0 {
|
||||
to.blit(&style.border_nw(), area.x(), area.y(), style.style());
|
||||
|
|
@ -31,13 +31,13 @@ impl<S: BorderStyle> Draw<TuiOut> for Border<S> {
|
|||
|
||||
pub trait BorderStyle: Content<TuiOut> + Copy {
|
||||
fn enabled (&self) -> bool;
|
||||
fn enclose (self, w: impl Draw<TuiOut>) -> impl Draw<TuiOut> {
|
||||
fn enclose (self, w: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
||||
Bsp::b(Fill::XY(Border(self.enabled(), self)), w)
|
||||
}
|
||||
fn enclose2 (self, w: impl Draw<TuiOut>) -> impl Draw<TuiOut> {
|
||||
fn enclose2 (self, w: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
||||
Bsp::b(Pad::XY(1, 1, Fill::XY(Border(self.enabled(), self))), w)
|
||||
}
|
||||
fn enclose_bg (self, w: impl Draw<TuiOut>) -> impl Draw<TuiOut> {
|
||||
fn enclose_bg (self, w: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
||||
Tui::bg(self.style().unwrap().bg.unwrap_or(Color::Reset),
|
||||
Bsp::b(Fill::XY(Border(self.enabled(), self)), w))
|
||||
}
|
||||
|
|
@ -141,6 +141,7 @@ macro_rules! border {
|
|||
fn enabled (&self) -> bool { self.0 }
|
||||
}
|
||||
#[derive(Copy, Clone)] pub struct $T(pub bool, pub Style);
|
||||
impl Layout<TuiOut> for $T {}
|
||||
impl Draw<TuiOut> for $T {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
if self.enabled() { let _ = BorderStyle::draw(self, to); }
|
||||
|
|
|
|||
|
|
@ -1,38 +1,18 @@
|
|||
use crate::{*, Color::*};
|
||||
|
||||
pub fn button_2 <'a> (
|
||||
key: impl Draw<TuiOut> + 'a,
|
||||
label: impl Draw<TuiOut> + 'a,
|
||||
editing: bool,
|
||||
) -> impl Draw<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_2 <'a> (key: impl Content<TuiOut>, label: impl Content<TuiOut>, editing: bool) -> impl Content<TuiOut> {
|
||||
Tui::bold(true, Bsp::e(
|
||||
Tui::fg_bg(Tui::orange(), Tui::g(0), Bsp::e(Tui::fg(Tui::g(0), &"▐"), Bsp::e(key, Tui::fg(Tui::g(96), &"▐")))),
|
||||
When::new(!editing, Tui::fg_bg(Tui::g(255), Tui::g(96), label))))
|
||||
}
|
||||
|
||||
pub fn button_3 <'a> (
|
||||
key: impl Draw<TuiOut> + 'a,
|
||||
label: impl Draw<TuiOut> + 'a,
|
||||
value: impl Draw<TuiOut> + 'a,
|
||||
editing: bool,
|
||||
) -> impl Draw<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), &"▐"),
|
||||
)),
|
||||
key: impl Content<TuiOut>, label: impl Content<TuiOut>, value: impl Content<TuiOut>, editing: bool,
|
||||
) -> impl Content<TuiOut> {
|
||||
Tui::bold(true, Bsp::e(
|
||||
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) }, "▐")))),
|
||||
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))
|
||||
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, &"▌"), ))))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,20 +13,16 @@ 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 Content<TuiOut> {
|
||||
Fixed::Y(1, Tui::fg_bg(fg, bg, RepeatH(Self::LO)))
|
||||
}
|
||||
pub fn lo (fg: Color, bg: Color) -> impl Content<TuiOut> { Fixed::Y(1, Tui::fg_bg(fg, bg, RepeatH(Self::LO))) }
|
||||
/// A phat line
|
||||
pub fn hi (fg: Color, bg: Color) -> impl Content<TuiOut> {
|
||||
Fixed::Y(1, Tui::fg_bg(fg, bg, RepeatH(Self::HI)))
|
||||
}
|
||||
pub fn hi (fg: Color, bg: Color) -> impl Content<TuiOut> { Fixed::Y(1, Tui::fg_bg(fg, bg, RepeatH(Self::HI))) }
|
||||
}
|
||||
|
||||
impl<T: Content<TuiOut>> HasContent<TuiOut> for Phat<T> {
|
||||
fn content (&self) -> impl Content<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 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);
|
||||
Min::XY(self.width, self.height, Bsp::s(top, Bsp::n(low, Fill::XY(content))))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ impl Draw<TuiOut> for Repeat<'_> {
|
|||
}
|
||||
|
||||
pub struct RepeatV<'a>(pub &'a str);
|
||||
impl Layout<TuiOut> for RepeatV<'_> {}
|
||||
impl Draw<TuiOut> for RepeatV<'_> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let [x, y, _w, h] = to.area().xywh();
|
||||
|
|
@ -30,6 +31,7 @@ impl Draw<TuiOut> for RepeatV<'_> {
|
|||
}
|
||||
|
||||
pub struct RepeatH<'a>(pub &'a str);
|
||||
impl Layout<TuiOut> for RepeatH<'_> {}
|
||||
impl Draw<TuiOut> for RepeatH<'_> {
|
||||
fn draw (&self, to: &mut TuiOut) {
|
||||
let [x, y, w, _h] = to.area().xywh();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
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 &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) } }
|
||||
|
||||
fn width_chars_max (max: u16, text: impl AsRef<str>) -> u16 {
|
||||
let mut width: u16 = 0;
|
||||
|
|
|
|||
|
|
@ -7,20 +7,20 @@ impl<
|
|||
> HasContent<TuiOut> for Tryptich<A, B, C> {
|
||||
fn content (&self) -> impl Content<TuiOut> {
|
||||
let Self { top, h, left: (w_a, ref a), middle: (w_b, ref b), right: (w_c, ref c) } = *self;
|
||||
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))))),
|
||||
Fill::X(Align::n(Fixed::X(w_b, Align::x(Tui::bg(Color::Reset, b))))),
|
||||
Bsp::a(
|
||||
Fill::x(Align::nw(Fixed::x(w_a, Tui::bg(Color::Reset, a)))),
|
||||
Fill::x(Align::ne(Fixed::x(w_c, Tui::bg(Color::Reset, c)))),
|
||||
Fill::X(Align::nw(Fixed::X(w_a, Tui::bg(Color::Reset, a)))),
|
||||
Fill::X(Align::ne(Fixed::X(w_c, Tui::bg(Color::Reset, c)))),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
Bsp::a(
|
||||
Fill::XY(Align::c(Fixed::x(w_b, Align::x(Tui::bg(Color::Reset, b))))),
|
||||
Fill::XY(Align::c(Fixed::X(w_b, Align::x(Tui::bg(Color::Reset, b))))),
|
||||
Bsp::a(
|
||||
Fill::XY(Align::w(Fixed::x(w_a, Tui::bg(Color::Reset, a)))),
|
||||
Fill::XY(Align::e(Fixed::x(w_c, Tui::bg(Color::Reset, c)))),
|
||||
Fill::XY(Align::w(Fixed::X(w_a, Tui::bg(Color::Reset, a)))),
|
||||
Fill::XY(Align::e(Fixed::X(w_c, Tui::bg(Color::Reset, c)))),
|
||||
),
|
||||
)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue