use ratatui::{
buffer::Buffer,
layout::Rect,
style::Style,
text::{Line, Span},
widgets::{Paragraph, Widget},
};
use crate::theme::UiColors;
pub struct Keybind<'a> {
pub key: &'a str,
pub desc: &'a str,
}
pub struct HelpBar<'a> {
pub keybinds: &'a [Keybind<'a>],
pub theme_display: &'a str,
pub colors: &'a UiColors,
}
impl<'a> HelpBar<'a> {
pub fn new(keybinds: &'a [Keybind<'a>], theme_display: &'a str, colors: &'a UiColors) -> Self {
Self {
keybinds,
theme_display,
colors,
}
}
pub fn theme_indicator_rect(&self, area: Rect) -> Rect {
let theme_indicator = format!("T: [{}] ", self.theme_display);
let theme_indicator_len = theme_indicator.len() as u16;
let indicator_x = area.x + area.width.saturating_sub(theme_indicator_len);
Rect::new(indicator_x, area.y, theme_indicator_len, 1)
}
fn styled_keybind_spans(&self) -> (Vec<Span<'a>>, u16) {
let mut spans: Vec<Span<'a>> = vec![Span::raw(" ")];
let mut total_len: u16 = 1;
for (i, kb) in self.keybinds.iter().enumerate() {
if i > 0 {
spans.push(Span::raw(" "));
total_len += 2;
}
spans.push(Span::styled(kb.key, Style::default().fg(self.colors.active_border)));
spans.push(Span::raw(" "));
spans.push(Span::styled(kb.desc, Style::default().fg(self.colors.help)));
total_len += (kb.key.chars().count() + 1 + kb.desc.chars().count()) as u16;
}
(spans, total_len)
}
}
impl Widget for HelpBar<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
let theme_indicator = format!("T: [{}] ", self.theme_display);
let theme_indicator_len = theme_indicator.len() as u16;
let (mut spans, keybinds_len) = self.styled_keybind_spans();
let padding_len = area.width.saturating_sub(keybinds_len + theme_indicator_len);
let padding = " ".repeat(padding_len as usize);
spans.push(Span::styled(padding, Style::default()));
spans.push(Span::styled(
theme_indicator,
Style::default().fg(self.colors.active_border).italic(),
));
let paragraph = Paragraph::new(Line::from(spans))
.style(Style::default().bg(self.colors.bar_bg));
paragraph.render(area, buf);
}
}