use ratatui::{ buffer::Buffer, layout::Rect, style::{Color, Modifier, Style}, widgets::{Block, Borders, Widget}, }; use crate::model::Model; use crate::ui::app::AppMode; pub struct ViewPanel<'a> { pub model: &'a Model, pub mode: &'a AppMode, pub cursor: usize, } impl<'a> ViewPanel<'a> { pub fn new(model: &'a Model, mode: &'a AppMode, cursor: usize) -> Self { Self { model, mode, cursor, } } } impl<'a> Widget for ViewPanel<'a> { fn render(self, area: Rect, buf: &mut Buffer) { let is_active = matches!(self.mode, AppMode::ViewPanel); let border_style = if is_active { Style::default().fg(Color::Blue) } else { Style::default().fg(Color::DarkGray) }; let block = Block::default() .borders(Borders::ALL) .border_style(border_style) .title(" Views [Enter] switch [n]ew [d]elete "); let inner = block.inner(area); block.render(area, buf); let view_names: Vec<&str> = self.model.views.keys().map(|s| s.as_str()).collect(); let active = &self.model.active_view; for (i, view_name) in view_names.iter().enumerate() { if inner.y + i as u16 >= inner.y + inner.height { break; } let is_selected = i == self.cursor && is_active; let is_active_view = *view_name == active.as_str(); let style = if is_selected { Style::default() .fg(Color::Black) .bg(Color::Blue) .add_modifier(Modifier::BOLD) } else if is_active_view { Style::default() .fg(Color::Blue) .add_modifier(Modifier::BOLD) } else { Style::default() }; let prefix = if is_active_view { "▶ " } else { " " }; buf.set_string( inner.x, inner.y + i as u16, format!("{prefix}{view_name}"), style, ); } } }