| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
use makeover_tui::Theme; |
| 14 |
use ratatui::buffer::Buffer; |
| 15 |
use ratatui::layout::Rect; |
| 16 |
use ratatui::style::Style; |
| 17 |
use ratatui::text::{Line, Span}; |
| 18 |
use ratatui::widgets::{Paragraph, Widget}; |
| 19 |
|
| 20 |
|
| 21 |
pub(crate) struct Hint { |
| 22 |
pub(crate) key: &'static str, |
| 23 |
pub(crate) label: &'static str, |
| 24 |
} |
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
pub(crate) const fn hint(key: &'static str, label: &'static str) -> Hint { |
| 29 |
Hint { key, label } |
| 30 |
} |
| 31 |
|
| 32 |
pub(crate) struct StatusBar<'a> { |
| 33 |
theme: &'a Theme, |
| 34 |
hints: Vec<Hint>, |
| 35 |
} |
| 36 |
|
| 37 |
impl<'a> StatusBar<'a> { |
| 38 |
pub(crate) fn new(theme: &'a Theme, hints: impl IntoIterator<Item = Hint>) -> Self { |
| 39 |
Self { |
| 40 |
theme, |
| 41 |
hints: hints.into_iter().collect(), |
| 42 |
} |
| 43 |
} |
| 44 |
} |
| 45 |
|
| 46 |
impl Widget for StatusBar<'_> { |
| 47 |
fn render(self, area: Rect, buf: &mut Buffer) { |
| 48 |
|
| 49 |
|
| 50 |
let base = Style::default().bg(self.theme.surface_sunken); |
| 51 |
Paragraph::new("").style(base).render(area, buf); |
| 52 |
|
| 53 |
let mut spans: Vec<Span> = Vec::with_capacity(self.hints.len() * 3); |
| 54 |
for (i, h) in self.hints.iter().enumerate() { |
| 55 |
if i > 0 { |
| 56 |
spans.push(Span::raw(" ")); |
| 57 |
} |
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
spans.push(Span::styled( |
| 62 |
h.key, |
| 63 |
Style::default().fg(self.theme.action_primary), |
| 64 |
)); |
| 65 |
spans.push(Span::raw(" ")); |
| 66 |
spans.push(Span::styled( |
| 67 |
h.label, |
| 68 |
Style::default().fg(self.theme.content_muted), |
| 69 |
)); |
| 70 |
} |
| 71 |
Paragraph::new(Line::from(spans)) |
| 72 |
.style(base) |
| 73 |
.render(area, buf); |
| 74 |
} |
| 75 |
} |
| 76 |
|