diff --git a/tui/src/tui_content.rs b/tui/src/tui_content.rs index f6048e6..88014ca 100644 --- a/tui/src/tui_content.rs +++ b/tui/src/tui_content.rs @@ -1,41 +1,18 @@ use crate::*; use ratatui::prelude::Position; -mod tui_color; pub use self::tui_color::*; -mod tui_file; pub use self::tui_file::*; -mod tui_scroll; pub use self::tui_scroll::*; -mod tui_string; pub use self::tui_string::*; -mod tui_border; pub use self::tui_border::*; - macro_rules! impl_content_layout_render { - ($Output:ty: |$self:ident: $Struct:ty, $to:ident| layout = $layout:expr; render = $render:expr) => { + ( + $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, to| - layout = Content::::layout(&self.read().unwrap(), to); - render = Content::::render(&self.read().unwrap(), to)); - -impl_content_layout_render!(TuiOut: |self: std::sync::RwLockReadGuard<'_, String>, to| - layout = Content::::layout(&**self, to); - render = Content::::render(&**self, to)); - -impl_content_layout_render!(TuiOut: |self: Arc, to| - layout = to.center_xy([self.chars().count() as u16, 1]); - render = to.blit(self, to.area.x(), to.area.y(), None)); impl> Content for std::sync::Arc { fn layout (&self, to: [u16;4]) -> [u16;4] { @@ -46,158 +23,12 @@ impl> Content for std::sync::Arc { } } -pub struct FieldH(pub ItemPalette, pub T, pub U); -impl, U: Content> Content for FieldH { - fn content (&self) -> impl Render { - 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(pub ItemPalette, pub T, pub U); -impl, U: Content> Content for FieldV { - fn content (&self) -> impl Render { - 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 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 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 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); - } - } - } -} - - -/// A cell that takes up 3 rows on its own, -/// but stacks, giving (N+1)*2 rows per N cells. -pub struct Phat { - pub width: u16, - pub height: u16, - pub content: T, - pub colors: [Color;4], -} -impl Phat { - /// A phat line - pub fn lo (fg: Color, bg: Color) -> impl Content { - Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▄"))) - } - /// A phat line - pub fn hi (fg: Color, bg: Color) -> impl Content { - Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▀"))) - } -} -impl> Content for Phat { - fn content (&self) -> impl Render { - 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 > (color: Color, w: R) -> Foreground { - Foreground(color, w) - } - fn bg > (color: Color, w: R) -> Background { - Background(color, w) - } - fn fg_bg > (fg: Color, bg: Color, w: R) -> Background> { - Background(bg, Foreground(fg, w)) - } - fn modify > (enable: bool, modifier: Modifier, w: R) -> Modify { - Modify(enable, modifier, w) - } - fn bold > (enable: bool, w: R) -> Modify { - Self::modify(enable, Modifier::BOLD, w) - } - fn border , S: BorderStyle> (enable: bool, style: S, w: R) -> Bordered { - Bordered(enable, style, w) - } -} - -impl TuiStyle for Tui {} - -pub struct Foreground>(pub Color, pub R); -impl> Content for Foreground { - fn content (&self) -> impl Render { &self.1 } - fn render (&self, to: &mut TuiOut) { - to.fill_fg(to.area(), self.0); - self.1.render(to) - } -} - -pub struct Background>(pub Color, pub R); -impl> Content for Background { - fn content (&self) -> impl Render { &self.1 } - fn render (&self, to: &mut TuiOut) { - to.fill_bg(to.area(), self.0); - self.1.render(to) - } -} - -pub struct Modify>(pub bool, pub Modifier, pub R); -impl> Content for Modify { - fn content (&self) -> impl Render { &self.2 } - fn render (&self, to: &mut TuiOut) { - to.fill_mod(to.area(), self.0, self.1); - self.2.render(to) - } -} - -pub struct Styled>(pub Option