use ratatui::{ buffer::Buffer, layout::{Constraint, Rect}, style::{Color, Modifier, Style}, widgets::{Block, Cell, Row, StatefulWidget, Table, TableState}, }; use crate::types::{ModConfig, RootConfig}; #[derive(Debug)] pub struct ListItem<'a> { mod_config: &'a ModConfig, id: &'a str, } #[derive(Debug)] pub struct ModList<'a> { items: Vec>, block: Option>, } impl<'a> ModList<'a> { pub fn new(root_config: &'a RootConfig) -> Self { let mut items: Vec<_> = root_config .mods() .iter() .map(|(id, config)| ListItem { id, mod_config: config, }) .collect(); items.sort_by_key(|item| item.id); Self { items, block: None } } pub fn block(mut self, block: Block<'a>) -> Self { self.block = Some(block); self } } impl<'a> StatefulWidget for ModList<'a> { type State = TableState; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { let rows: Vec = self .items .iter() .map(|item| { Row::new(vec![ Cell::from(item.mod_config.name().unwrap_or(item.id)), Cell::from(item.id), ]) }) .collect(); let table = Table::new(rows, [Constraint::Fill(1), Constraint::Fill(1)]) .row_highlight_style( Style::default() .fg(Color::Yellow) .bg(Color::DarkGray) .add_modifier(Modifier::BOLD), ) .highlight_symbol(">> "); let table = match self.block { Some(b) => table.block(b), None => table, }; StatefulWidget::render(table, area, buf, state); } }