1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! `TitledPane` — fills an area with a background colour and renders a bold
//! title row, returning the remaining content [`Rect`].
//!
//! Used by file-selector, command-runner, and any other view that follows the
//! "active/inactive pane with a header" layout pattern.
use ratatui::{
Frame,
layout::Rect,
style::{Color, Modifier, Style},
text::Span,
widgets::{Block, Paragraph},
};
use crate::theme::Theme;
/// Prepares a titled pane: fills background, renders header row, returns content rect.
pub struct TitledPane<'a> {
title: &'a str,
active: bool,
}
impl<'a> TitledPane<'a> {
pub fn new(title: &'a str, active: bool) -> Self {
Self { title, active }
}
/// Background colour for this pane state.
pub fn bg(&self, theme: &Theme) -> Color {
if self.active { theme.bg_active() } else { theme.bg_inactive() }
}
/// Fill `area` with the pane background, render the title on the first row,
/// and return the remaining content area (everything below the title).
pub fn prepare(&self, frame: &mut Frame, area: Rect, theme: &Theme) -> Rect {
let bg = self.bg(theme);
let fg = if self.active { theme.accent() } else { theme.fg_dim() };
frame.render_widget(Block::default().style(Style::new().bg(bg)), area);
let title_area = Rect { height: 1, ..area };
frame.render_widget(
Paragraph::new(Span::styled(
self.title.to_owned(),
Style::new().fg(fg).bg(bg).add_modifier(Modifier::BOLD),
)),
title_area,
);
Rect {
y: area.y + 1,
height: area.height.saturating_sub(1),
..area
}
}
}