use std::any::Any;
use crossterm::event::MouseEvent;
use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use ratatui::style::Color;
use crate::{KeyChord, PanelEvent};
#[derive(Debug, Clone, Copy)]
pub struct ThemeColors {
pub fg: Color,
pub bg: Color,
pub selection_bg: Color,
pub selection_fg: Color,
pub border: Color,
pub border_focused: Color,
pub line_numbers: Color,
pub cursor: Color,
pub status_bar_bg: Color,
pub status_bar_fg: Color,
}
impl Default for ThemeColors {
fn default() -> Self {
Self {
fg: Color::White,
bg: Color::Black,
selection_bg: Color::Blue,
selection_fg: Color::White,
border: Color::DarkGray,
border_focused: Color::Cyan,
line_numbers: Color::DarkGray,
cursor: Color::Yellow,
status_bar_bg: Color::DarkGray,
status_bar_fg: Color::White,
}
}
}
pub struct RenderContext<'a> {
pub theme: &'a ThemeColors,
pub is_focused: bool,
pub panel_index: usize,
pub terminal_width: u16,
pub terminal_height: u16,
}
pub trait Panel: Any {
fn name(&self) -> &'static str;
fn title(&self) -> String;
fn render(&mut self, area: Rect, buf: &mut Buffer, ctx: &RenderContext);
fn handle_key(&mut self, chord: KeyChord) -> Vec<PanelEvent>;
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
fn handle_mouse(&mut self, event: MouseEvent, panel_area: Rect) -> Vec<PanelEvent> {
let _ = (event, panel_area);
Vec::new()
}
fn handle_scroll(&mut self, delta: i32, panel_area: Rect) -> Vec<PanelEvent> {
let _ = (delta, panel_area);
Vec::new()
}
fn cursor_position(&self, panel_area: Rect) -> Option<(u16, u16)> {
let _ = panel_area;
None
}
fn apply_action(&mut self, action: crate::Action) -> Option<Vec<PanelEvent>> {
let _ = action;
None
}
fn tick(&mut self) -> Vec<PanelEvent> {
Vec::new()
}
fn captures_escape(&self) -> bool {
false
}
fn needs_close_confirmation(&self) -> Option<String> {
None
}
}