diff --git a/tui/src/tui_content.rs b/tui/src/tui_content.rs index f5fce2dd..043a5b66 100644 --- a/tui/src/tui_content.rs +++ b/tui/src/tui_content.rs @@ -1,25 +1,29 @@ use crate::*; - -impl Content for &str { - fn layout (&self, to: [u16;4]) -> [u16;4] { - to.center_xy([self.chars().count() as u16, 1]) - } - fn render (&self, to: &mut TuiOut) { - let [x, y, ..] = Content::layout(self, to.area()); - to.blit(self, x, y, None) +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 for String { - fn layout (&self, to: [u16;4]) -> [u16;4] { - to.center_xy([self.chars().count() as u16, 1]) - } - fn render (&self, to: &mut TuiOut) { - let [x, y, ..] = Content::layout(self, to.area()); - to.blit(self, x, y, None) - } -} - +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] { Content::::layout(&**self, to) @@ -29,32 +33,6 @@ impl> Content for std::sync::Arc { } } -impl Content for std::sync::RwLock { - fn layout (&self, to: [u16;4]) -> [u16;4] { - Content::::layout(&self.read().unwrap(), to) - } - fn render (&self, to: &mut TuiOut) { - Content::::render(&self.read().unwrap(), to) - } -} - -impl Content for std::sync::RwLockReadGuard<'_, String> { - fn layout (&self, to: [u16;4]) -> [u16;4] { - Content::::layout(&**self, to) - } - fn render (&self, to: &mut TuiOut) { - Content::::render(&**self, to) - } -} - -impl Content for Arc { - fn layout (&self, to: [u16;4]) -> [u16;4] { - to.center_xy([self.chars().count() as u16, 1]) - } - fn render (&self, to: &mut TuiOut) { - to.blit(self, to.area.x(), to.area.y(), None) - } -} pub struct FieldH(pub ItemPalette, pub T, pub U); impl, U: Content> Content for FieldH { @@ -130,32 +108,34 @@ impl Content for RepeatH<'_> { } } -/// A phat line -pub fn phat_lo (fg: Color, bg: Color) -> impl Content { - Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▄"))) +/// 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 top: Option, + pub mid: Option, + pub low: Option, } -/// A phat line -pub fn phat_hi (fg: Color, bg: Color) -> impl Content { - Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▀"))) +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(&"▀"))) + } } -/// A cell that is 3-row on its own, but stacks, giving (N+1)*2 rows per N cells. -pub fn phat_cell > ( - color: ItemPalette, last: ItemPalette, field: T -) -> impl Content { - Bsp::s(phat_lo(color.base.rgb, last.base.rgb), - Bsp::n(phat_hi(color.base.rgb, last.base.rgb), - Fixed::y(1, Fill::x(Tui::fg_bg(color.lightest.rgb, color.base.rgb, field))), +impl> for Phat { + fn content () -> impl Render { + Bsp::s(Self::lo(color.base.rgb, last.base.rgb), + Bsp::n(Self::hi(color.base.rgb, last.base.rgb), + Fixed::y(1, Fill::x(Tui::fg_bg(color.lightest.rgb, color.base.rgb, field))), + ) ) - ) -} -pub fn phat_cell_3 > ( - field: T, top: Color, middle: Color, bottom: Color -) -> impl Content { - Bsp::s(phat_lo(middle, top), - Bsp::n(phat_hi(middle, bottom), - Fill::y(Fill::x(Tui::bg(middle, field))), - ) - ) + } } pub fn phat_sel_3 > ( selected: bool, field_1: T, field_2: T, @@ -166,15 +146,13 @@ pub fn phat_sel_3 > ( let border = Style::default().fg(Color::Rgb(255,255,255)).bg(mid); let top = top.map(|top|phat_lo(mid, top)); let low = low.map(|low|phat_hi(mid, low)); - Either::new( - selected, - Tui::bg(mid, Outer(true, border).enclose( - Align::w(Bsp::s("", Bsp::n("", Fill::y(field_1)))) - )), - Bsp::s(Fixed::y(1, top), Bsp::n(Fixed::y(1, low), - Fill::xy(Tui::bg(mid, field_2)) - )), - ) + let a = Tui::bg(mid, Outer(true, border).enclose(Align::w(Bsp::s("", Bsp::n("", Fill::y(field_1)))))); + let b = Bsp::s(Fixed::y(1, top), Bsp::n(Fixed::y(1, low), Fill::xy(Tui::bg(mid, field_2)))); + Either::new(selected, a, b) +} +pub struct PhatOverlapIterator, I: Iterator> { + items: I, + color: Color } pub trait TuiStyle {