use crate::components::Component;
use crate::app::{AppState, Action};
use crate::errors::ComponentError;
use crate::input::InputEvent;
use crate::ui::style;
use ratatui::Frame;
use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::widgets::Paragraph;
use ratatui::text::Line;
use crossterm::event::{KeyCode, KeyEventKind};
pub struct HelpPane;
impl HelpPane {
pub fn new() -> Self {
Self
}
}
impl Component for HelpPane {
fn handle_event(
&mut self,
event: InputEvent,
_state: &AppState,
) -> Result<Option<Action>, ComponentError> {
if let InputEvent::Key(key) = event {
if key.kind == KeyEventKind::Press && matches!(key.code, KeyCode::Esc | KeyCode::Char('h')) {
return Ok(Some(Action::ToggleHelp));
}
}
Ok(None)
}
fn render(&mut self, frame: &mut Frame, area: Rect, state: &AppState) {
let max_idx = state.key_help.len().saturating_sub(1);
let selected = state.help_selected.min(max_idx);
let help_area = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Percentage(20),
Constraint::Percentage(60),
Constraint::Percentage(20),
])
.split(area)[1];
let theme = &state.theme;
let selection_style = style::selection(theme);
let normal_style = style::text(theme, style::Emphasis::Header);
let lines: Vec<Line> = state
.key_help
.iter()
.enumerate()
.map(|(i, h)| {
let style = if i == selected { selection_style } else { normal_style };
Line::from(format!("{} : {}", h.key, h.desc)).style(style)
})
.collect();
let block = style::pane_block(theme, "Help", true);
let paragraph = Paragraph::new(lines)
.style(style::body_style(theme))
.block(block);
frame.render_widget(paragraph, help_area);
}
fn name(&self) -> &'static str {
"HelpPane"
}
}