mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-09 05:06:44 +01:00
tabula rasa
This commit is contained in:
commit
47b3413d7d
76 changed files with 7000 additions and 0 deletions
522
tui/src/tui_content.rs
Normal file
522
tui/src/tui_content.rs
Normal file
|
|
@ -0,0 +1,522 @@
|
|||
use crate::*;
|
||||
use crate::Color::*;
|
||||
use ratatui::prelude::Position;
|
||||
macro_rules! impl_content_layout_render {
|
||||
($Output:ty: |$self:ident: $Struct:ty, $to:ident| layout = $layout:expr; render = $render:expr) => {
|
||||
impl Content<$Output> for $Struct {
|
||||
fn layout (&$self, $to: [u16;4]) -> [u16;4] { $layout }
|
||||
fn render (&$self, $to: &mut $Output) { $render }
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_content_layout_render!(TuiOut: |self: &str, to|
|
||||
layout = to.center_xy([self.chars().count() as u16, 1]);
|
||||
render = {let [x, y, ..] = Content::layout(self, to.area());
|
||||
to.blit(self, x, y, None)});
|
||||
impl_content_layout_render!(TuiOut: |self: String, to|
|
||||
layout = to.center_xy([self.chars().count() as u16, 1]);
|
||||
render = {let [x, y, ..] = Content::layout(self, to.area());
|
||||
to.blit(self, x, y, None)});
|
||||
impl_content_layout_render!(TuiOut: |self: std::sync::RwLock<String>, to|
|
||||
layout = Content::<TuiOut>::layout(&self.read().unwrap(), to);
|
||||
render = Content::<TuiOut>::render(&self.read().unwrap(), to));
|
||||
impl_content_layout_render!(TuiOut: |self: std::sync::RwLockReadGuard<'_, String>, to|
|
||||
layout = Content::<TuiOut>::layout(&**self, to);
|
||||
render = Content::<TuiOut>::render(&**self, to));
|
||||
impl_content_layout_render!(TuiOut: |self: Arc<str>, to|
|
||||
layout = to.center_xy([self.chars().count() as u16, 1]);
|
||||
render = to.blit(self, to.area.x(), to.area.y(), None));
|
||||
impl<T: Content<TuiOut>> Content<TuiOut> for std::sync::Arc<T> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
Content::<TuiOut>::layout(&**self, to)
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
Content::<TuiOut>::render(&**self, to)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FieldH<T, U>(pub ItemPalette, pub T, pub U);
|
||||
impl<T: Content<TuiOut>, U: Content<TuiOut>> Content<TuiOut> for FieldH<T, U> {
|
||||
fn content (&self) -> impl Render<TuiOut> {
|
||||
let Self(ItemPalette { darkest, dark, lighter, lightest, .. }, title, value) = self;
|
||||
row!(
|
||||
Tui::fg_bg(dark.rgb, darkest.rgb, "▐"),
|
||||
Tui::fg_bg(lighter.rgb, dark.rgb, Tui::bold(true, title)),
|
||||
Tui::fg_bg(dark.rgb, darkest.rgb, "▌"),
|
||||
Tui::fg_bg(lightest.rgb, darkest.rgb, value),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FieldV<T, U>(pub ItemPalette, pub T, pub U);
|
||||
impl<T: Content<TuiOut>, U: Content<TuiOut>> Content<TuiOut> for FieldV<T, U> {
|
||||
fn content (&self) -> impl Render<TuiOut> {
|
||||
let Self(ItemPalette { darkest, dark, lighter, lightest, .. }, title, value) = self;
|
||||
let sep1 = Tui::bg(darkest.rgb, Tui::fg(dark.rgb, "▐"));
|
||||
let sep2 = Tui::bg(darkest.rgb, Tui::fg(dark.rgb, "▌"));
|
||||
let title = Tui::bg(dark.rgb, Tui::fg(lighter.rgb, Tui::bold(true, title)));
|
||||
let value = Tui::bg(darkest.rgb, Tui::fg(lightest.rgb, value));
|
||||
Bsp::e(Bsp::s(row!(sep1, title, sep2), value), " ")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Repeat<'a>(pub &'a str);
|
||||
impl Content<TuiOut> for Repeat<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] { to }
|
||||
fn render (&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() {
|
||||
for (u, x) in (x..x+w).enumerate() {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
let u = u % a;
|
||||
cell.set_symbol(&self.0[u..u+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RepeatV<'a>(pub &'a str);
|
||||
impl Content<TuiOut> for RepeatV<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] { to }
|
||||
fn render (&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))) {
|
||||
cell.set_symbol(&self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RepeatH<'a>(pub &'a str);
|
||||
impl Content<TuiOut> for RepeatH<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] { to }
|
||||
fn render (&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))) {
|
||||
cell.set_symbol(&self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScrollbarV {
|
||||
pub offset: usize,
|
||||
pub length: usize,
|
||||
pub total: usize,
|
||||
}
|
||||
impl ScrollbarV {
|
||||
const ICON_DEC: &[char] = &['▲'];
|
||||
const ICON_INC: &[char] = &['▼'];
|
||||
}
|
||||
impl Content<TuiOut> for ScrollbarV {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let [x, y1, _w, h] = to.area().xywh();
|
||||
let y2 = y1 + h;
|
||||
for (i, y) in (y1..=y2).enumerate() {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
if (i as usize) < (Self::ICON_DEC.len()) {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Rgb(0, 0, 0));
|
||||
cell.set_char(Self::ICON_DEC[i as usize]);
|
||||
} else if (i as usize) > (h as usize - Self::ICON_INC.len()) {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Rgb(0, 0, 0));
|
||||
cell.set_char(Self::ICON_INC[h as usize - i]);
|
||||
} else if false {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Reset);
|
||||
cell.set_char('‖'); // ━
|
||||
} else {
|
||||
cell.set_fg(Rgb(0, 0, 0));
|
||||
cell.set_bg(Reset);
|
||||
cell.set_char('╎'); // ━
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScrollbarH {
|
||||
pub offset: usize,
|
||||
pub length: usize,
|
||||
pub total: usize,
|
||||
}
|
||||
impl ScrollbarH {
|
||||
const ICON_DEC: &[char] = &[' ', '🞀', ' '];
|
||||
const ICON_INC: &[char] = &[' ', '🞂', ' '];
|
||||
}
|
||||
impl Content<TuiOut> for ScrollbarH {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let [x1, y, w, _h] = to.area().xywh();
|
||||
let x2 = x1 + w;
|
||||
for (i, x) in (x1..=x2).enumerate() {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
if i < (Self::ICON_DEC.len()) {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Rgb(0, 0, 0));
|
||||
cell.set_char(Self::ICON_DEC[x as usize]);
|
||||
} else if i > (w as usize - Self::ICON_INC.len()) {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Rgb(0, 0, 0));
|
||||
cell.set_char(Self::ICON_INC[w as usize - i]);
|
||||
} else if false {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Reset);
|
||||
cell.set_char('━');
|
||||
} else {
|
||||
cell.set_fg(Rgb(0, 0, 0));
|
||||
cell.set_bg(Reset);
|
||||
cell.set_char('╌');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A cell that takes up 3 rows on its own,
|
||||
/// but stacks, giving (N+1)*2 rows per N cells.
|
||||
pub struct Phat<T> {
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
pub content: T,
|
||||
pub colors: [Color;4],
|
||||
}
|
||||
impl<T> Phat<T> {
|
||||
/// A phat line
|
||||
pub fn lo (fg: Color, bg: Color) -> impl Content<TuiOut> {
|
||||
Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▄")))
|
||||
}
|
||||
/// A phat line
|
||||
pub fn hi (fg: Color, bg: Color) -> impl Content<TuiOut> {
|
||||
Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▀")))
|
||||
}
|
||||
}
|
||||
impl<T: Content<TuiOut>> Content<TuiOut> for Phat<T> {
|
||||
fn content (&self) -> impl Render<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);
|
||||
Min::xy(self.width, self.height, Bsp::s(top, Bsp::n(low, Fill::xy(content))))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TuiStyle {
|
||||
fn fg <R: Content<TuiOut>> (color: Color, w: R) -> Foreground<R> {
|
||||
Foreground(color, w)
|
||||
}
|
||||
fn bg <R: Content<TuiOut>> (color: Color, w: R) -> Background<R> {
|
||||
Background(color, w)
|
||||
}
|
||||
fn fg_bg <R: Content<TuiOut>> (fg: Color, bg: Color, w: R) -> Background<Foreground<R>> {
|
||||
Background(bg, Foreground(fg, w))
|
||||
}
|
||||
fn bold <R: Content<TuiOut>> (enable: bool, w: R) -> Bold<R> {
|
||||
Bold(enable, w)
|
||||
}
|
||||
fn border <R: Content<TuiOut>, S: BorderStyle> (enable: bool, style: S, w: R) -> Bordered<S, R> {
|
||||
Bordered(enable, style, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl TuiStyle for Tui {}
|
||||
|
||||
pub struct Bold<R: Content<TuiOut>>(pub bool, R);
|
||||
impl<R: Content<TuiOut>> Content<TuiOut> for Bold<R> {
|
||||
fn content (&self) -> impl Render<TuiOut> { &self.1 }
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
to.fill_bold(to.area(), self.0);
|
||||
self.1.render(to)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Foreground<R: Content<TuiOut>>(pub Color, R);
|
||||
impl<R: Content<TuiOut>> Content<TuiOut> for Foreground<R> {
|
||||
fn content (&self) -> impl Render<TuiOut> { &self.1 }
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
to.fill_fg(to.area(), self.0);
|
||||
self.1.render(to)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Background<R: Content<TuiOut>>(pub Color, R);
|
||||
impl<R: Content<TuiOut>> Content<TuiOut> for Background<R> {
|
||||
fn content (&self) -> impl Render<TuiOut> { &self.1 }
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
to.fill_bg(to.area(), self.0);
|
||||
self.1.render(to)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Styled<R: Content<TuiOut>>(pub Option<Style>, pub R);
|
||||
impl<R: Content<TuiOut>> Content<TuiOut> for Styled<R> {
|
||||
fn content (&self) -> impl Render<TuiOut> { &self.1 }
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
to.place(self.content().layout(to.area()), &self.content());
|
||||
// TODO write style over area
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Bordered<S: BorderStyle, W: Content<TuiOut>>(pub bool, pub S, pub W);
|
||||
content!(TuiOut: |self: Bordered<S: BorderStyle, W: Content<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);
|
||||
render!(TuiOut: |self: Border<S: BorderStyle>, to| {
|
||||
if self.0 {
|
||||
let area = to.area();
|
||||
if area.w() > 0 && area.y() > 0 {
|
||||
to.blit(&self.1.nw(), area.x(), area.y(), self.1.style());
|
||||
to.blit(&self.1.ne(), area.x() + area.w() - 1, area.y(), self.1.style());
|
||||
to.blit(&self.1.sw(), area.x(), area.y() + area.h() - 1, self.1.style());
|
||||
to.blit(&self.1.se(), area.x() + area.w() - 1, area.y() + area.h() - 1, self.1.style());
|
||||
for x in area.x()+1..area.x()+area.w()-1 {
|
||||
to.blit(&self.1.n(), x, area.y(), self.1.style());
|
||||
to.blit(&self.1.s(), x, area.y() + area.h() - 1, self.1.style());
|
||||
}
|
||||
for y in area.y()+1..area.y()+area.h()-1 {
|
||||
to.blit(&self.1.w(), area.x(), y, self.1.style());
|
||||
to.blit(&self.1.e(), area.x() + area.w() - 1, y, self.1.style());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
pub trait BorderStyle: Send + Sync + Copy {
|
||||
fn enabled (&self) -> bool;
|
||||
fn enclose <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
||||
Bsp::b(Fill::xy(Border(self.enabled(), self)), w)
|
||||
}
|
||||
fn enclose2 <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
||||
Bsp::b(Margin::xy(1, 1, Fill::xy(Border(self.enabled(), self))), w)
|
||||
}
|
||||
fn enclose_bg <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
||||
Tui::bg(self.style().unwrap().bg.unwrap_or(Color::Reset),
|
||||
Bsp::b(Fill::xy(Border(self.enabled(), self)), w))
|
||||
}
|
||||
const NW: &'static str = "";
|
||||
const N: &'static str = "";
|
||||
const NE: &'static str = "";
|
||||
const E: &'static str = "";
|
||||
const SE: &'static str = "";
|
||||
const S: &'static str = "";
|
||||
const SW: &'static str = "";
|
||||
const W: &'static str = "";
|
||||
|
||||
const N0: &'static str = "";
|
||||
const S0: &'static str = "";
|
||||
const W0: &'static str = "";
|
||||
const E0: &'static str = "";
|
||||
|
||||
fn n (&self) -> &str { Self::N }
|
||||
fn s (&self) -> &str { Self::S }
|
||||
fn e (&self) -> &str { Self::E }
|
||||
fn w (&self) -> &str { Self::W }
|
||||
fn nw (&self) -> &str { Self::NW }
|
||||
fn ne (&self) -> &str { Self::NE }
|
||||
fn sw (&self) -> &str { Self::SW }
|
||||
fn se (&self) -> &str { Self::SE }
|
||||
#[inline] fn draw <'a> (
|
||||
&self, to: &mut TuiOut
|
||||
) -> Usually<()> {
|
||||
if self.enabled() {
|
||||
self.draw_horizontal(to, None)?;
|
||||
self.draw_vertical(to, None)?;
|
||||
self.draw_corners(to, None)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[inline] fn draw_horizontal (
|
||||
&self, to: &mut TuiOut, style: Option<Style>
|
||||
) -> Usually<[u16;4]> {
|
||||
let area = to.area();
|
||||
let style = style.or_else(||self.style_horizontal());
|
||||
let [x, x2, y, y2] = area.lrtb();
|
||||
for x in x..x2.saturating_sub(1) {
|
||||
to.blit(&Self::N, x, y, style);
|
||||
to.blit(&Self::S, x, y2.saturating_sub(1), style)
|
||||
}
|
||||
Ok(area)
|
||||
}
|
||||
#[inline] fn draw_vertical (
|
||||
&self, to: &mut TuiOut, style: Option<Style>
|
||||
) -> Usually<[u16;4]> {
|
||||
let area = to.area();
|
||||
let style = style.or_else(||self.style_vertical());
|
||||
let [x, x2, y, y2] = area.lrtb();
|
||||
let h = y2 - y;
|
||||
if h > 1 {
|
||||
for y in y..y2.saturating_sub(1) {
|
||||
to.blit(&Self::W, x, y, style);
|
||||
to.blit(&Self::E, x2.saturating_sub(1), y, style);
|
||||
}
|
||||
} else if h > 0 {
|
||||
to.blit(&Self::W0, x, y, style);
|
||||
to.blit(&Self::E0, x2.saturating_sub(1), y, style);
|
||||
}
|
||||
Ok(area)
|
||||
}
|
||||
#[inline] fn draw_corners (
|
||||
&self, to: &mut TuiOut, style: Option<Style>
|
||||
) -> Usually<[u16;4]> {
|
||||
let area = to.area();
|
||||
let style = style.or_else(||self.style_corners());
|
||||
let [x, y, width, height] = area.xywh();
|
||||
if width > 1 && height > 1 {
|
||||
to.blit(&Self::NW, x, y, style);
|
||||
to.blit(&Self::NE, x + width - 1, y, style);
|
||||
to.blit(&Self::SW, x, y + height - 1, style);
|
||||
to.blit(&Self::SE, x + width - 1, y + height - 1, style);
|
||||
}
|
||||
Ok(area)
|
||||
}
|
||||
#[inline] fn style (&self) -> Option<Style> { None }
|
||||
#[inline] fn style_horizontal (&self) -> Option<Style> { self.style() }
|
||||
#[inline] fn style_vertical (&self) -> Option<Style> { self.style() }
|
||||
#[inline] fn style_corners (&self) -> Option<Style> { self.style() }
|
||||
}
|
||||
|
||||
macro_rules! border {
|
||||
($($T:ident {
|
||||
$nw:literal $n:literal $ne:literal $w:literal $e:literal $sw:literal $s:literal $se:literal
|
||||
$($x:tt)*
|
||||
}),+) => {$(
|
||||
impl BorderStyle for $T {
|
||||
const NW: &'static str = $nw;
|
||||
const N: &'static str = $n;
|
||||
const NE: &'static str = $ne;
|
||||
const W: &'static str = $w;
|
||||
const E: &'static str = $e;
|
||||
const SW: &'static str = $sw;
|
||||
const S: &'static str = $s;
|
||||
const SE: &'static str = $se;
|
||||
$($x)*
|
||||
fn enabled (&self) -> bool { false }
|
||||
}
|
||||
#[derive(Copy, Clone)] pub struct $T(pub bool, pub Style);
|
||||
impl Content<TuiOut> for $T {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
if self.enabled() { let _ = self.draw(to); }
|
||||
}
|
||||
}
|
||||
)+}
|
||||
}
|
||||
|
||||
border! {
|
||||
Square {
|
||||
"┌" "─" "┐"
|
||||
"│" "│"
|
||||
"└" "─" "┘" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
SquareBold {
|
||||
"┏" "━" "┓"
|
||||
"┃" "┃"
|
||||
"┗" "━" "┛" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
TabLike {
|
||||
"╭" "─" "╮"
|
||||
"│" "│"
|
||||
"│" " " "│" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Lozenge {
|
||||
"╭" "─" "╮"
|
||||
"│" "│"
|
||||
"╰" "─" "╯" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Brace {
|
||||
"╭" "" "╮"
|
||||
"│" "│"
|
||||
"╰" "" "╯" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
LozengeDotted {
|
||||
"╭" "┅" "╮"
|
||||
"┇" "┇"
|
||||
"╰" "┅" "╯" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Quarter {
|
||||
"▎" "▔" "🮇"
|
||||
"▎" "🮇"
|
||||
"▎" "▁" "🮇" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
QuarterV {
|
||||
"▎" "" "🮇"
|
||||
"▎" "🮇"
|
||||
"▎" "" "🮇" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Chamfer {
|
||||
"🭂" "▔" "🭍"
|
||||
"▎" "🮇"
|
||||
"🭓" "▁" "🭞" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Corners {
|
||||
"🬆" "" "🬊" // 🬴 🬸
|
||||
"" ""
|
||||
"🬱" "" "🬵" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
CornersTall {
|
||||
"🭽" "" "🭾"
|
||||
"" ""
|
||||
"🭼" "" "🭿" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Outer {
|
||||
"🭽" "▔" "🭾"
|
||||
"▏" "▕"
|
||||
"🭼" "▁" "🭿"
|
||||
const W0: &'static str = "[";
|
||||
const E0: &'static str = "]";
|
||||
const N0: &'static str = "⎴";
|
||||
const S0: &'static str = "⎵";
|
||||
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Thick {
|
||||
"▄" "▄" "▄"
|
||||
"█" "█"
|
||||
"▀" "▀" "▀"
|
||||
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Rugged {
|
||||
"▄" "▂" "▄"
|
||||
"▐" "▌"
|
||||
"▀" "🮂" "▀"
|
||||
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Skinny {
|
||||
"▗" "▄" "▖"
|
||||
"▐" "▌"
|
||||
"▝" "▀" "▘"
|
||||
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Brackets {
|
||||
"⎡" "" "⎤"
|
||||
"" ""
|
||||
"⎣" "" "⎦"
|
||||
const W0: &'static str = "[";
|
||||
const E0: &'static str = "]";
|
||||
const N0: &'static str = "⎴";
|
||||
const S0: &'static str = "⎵";
|
||||
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||
},
|
||||
Reticle {
|
||||
"⎡" "" "⎤"
|
||||
"" ""
|
||||
"⎣" "" "⎦"
|
||||
const W0: &'static str = "╟";
|
||||
const E0: &'static str = "╢";
|
||||
const N0: &'static str = "┯";
|
||||
const S0: &'static str = "┷";
|
||||
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()
|
||||
//}
|
||||
//}
|
||||
Loading…
Add table
Add a link
Reference in a new issue