use crate::core::buffer::Buffer;
use crate::core::color::Color;
use crate::core::rect::Rect;
use crate::style::Style;
use crate::widgets::Widget;
#[derive(Debug, Clone)]
pub struct Cell {
pub content: String,
pub style: Style,
}
impl Cell {
pub fn new(content: &str) -> Self {
Self {
content: content.to_string(),
style: Style::new(),
}
}
pub fn with_style(mut self, style: Style) -> Self {
self.style = style;
self
}
}
#[derive(Debug, Clone)]
pub struct Row {
pub cells: Vec<Cell>,
pub style: Style,
}
impl Row {
pub fn new(cells: Vec<Cell>) -> Self {
Self {
cells,
style: Style::new(),
}
}
pub fn with_style(mut self, style: Style) -> Self {
self.style = style;
self
}
}
#[derive(Debug, Clone)]
pub struct Table<'a> {
pub rows: &'a [Row],
pub widths: &'a [u16],
pub header: Option<&'a Row>,
pub selected: Option<usize>,
pub header_style: Style,
pub selected_style: Style,
}
impl<'a> Table<'a> {
pub fn new(rows: &'a [Row], widths: &'a [u16]) -> Self {
Self {
rows,
widths,
header: None,
selected: None,
header_style: Style::new().bold().fg(Color::rgb(88, 166, 255)),
selected_style: Style::new().fg(Color::WHITE).bg(Color::rgb(31, 111, 235)),
}
}
pub fn with_header(mut self, header: &'a Row) -> Self {
self.header = Some(header);
self
}
pub fn with_selected(mut self, selected: usize) -> Self {
self.selected = Some(selected);
self
}
}
impl<'a> Widget for Table<'a> {
fn render(&self, buffer: &mut Buffer, area: Rect) {
let mut current_y = area.y as usize;
let _header_offset = if self.header.is_some() { 1 } else { 0 };
if let Some(header) = self.header {
if current_y < area.bottom() as usize {
let mut x = area.x as usize;
for (i, cell) in header.cells.iter().enumerate() {
let w = self.widths.get(i).copied().unwrap_or(10) as usize;
let display: String = cell.content.chars().take(w).collect();
buffer.set_str(
x,
current_y,
&display,
self.header_style.fg_or_default(),
self.header_style.bg,
);
x += w + 1;
}
current_y += 1;
}
}
for (row_idx, row) in self.rows.iter().enumerate() {
if current_y >= area.bottom() as usize {
break;
}
let is_selected = self.selected == Some(row_idx);
let mut x = area.x as usize;
for (i, cell) in row.cells.iter().enumerate() {
let w = self.widths.get(i).copied().unwrap_or(10) as usize;
let display: String = cell.content.chars().take(w).collect();
let (fg, bg) = if is_selected {
(self.selected_style.fg_or_default(), self.selected_style.bg)
} else {
(cell.style.fg_or_default(), cell.style.bg)
};
buffer.set_str(x, current_y, &display, fg, bg);
x += w + 1;
}
current_y += 1;
}
}
}