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) } } 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 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 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(ratatui::prelude::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(ratatui::prelude::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(ratatui::prelude::Position::from((x, y))) { cell.set_symbol(&self.0); } } } } /// A phat line pub fn phat_lo (fg: Color, bg: Color) -> impl Content { Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▄"))) } /// A phat line pub fn phat_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))), ) ) } 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, top: Option, middle: Color, bottom: Color ) -> impl Content { let border = Style::default().fg(Color::Rgb(255,255,255)).bg(middle); Either::new(selected, Tui::bg(middle, Outer(border).enclose(Align::w(Bsp::s("", Bsp::n("", Fill::y(field_1)))))), Bsp::s(Fixed::y(1, top.map(|top|phat_lo(middle, top))), Bsp::n(Fixed::y(1, phat_hi(middle, bottom)), Fill::xy(Tui::bg(middle, field_2)), ) ) ) }