Skip to main content

cui/ui/
mod.rs

1//! Drawing: pure functions from `&AppState` to the frame. The only
2//! state the draw pass writes back is the measured viewport
3//! heights, which the reducer needs for paging.
4
5pub mod bars;
6pub mod cmd;
7pub mod help;
8pub mod list;
9pub mod view;
10
11use ratatui::Frame;
12use ratatui::layout::{Constraint, Layout, Rect};
13use ratatui::style::{Color, Style, Stylize};
14
15use crate::state::{AppState, Mode};
16
17pub fn draw(f: &mut Frame, state: &mut AppState) {
18    let [global, context, main, bottom] = Layout::vertical([
19        Constraint::Length(1),
20        Constraint::Length(1),
21        Constraint::Min(0),
22        Constraint::Length(1),
23    ])
24    .areas(f.area());
25
26    let [left, right] =
27        Layout::horizontal([Constraint::Length(list_width(main)), Constraint::Min(0)]).areas(main);
28
29    bars::draw(f, global, context, state);
30    list::draw(f, left, state);
31    view::draw(f, right, state);
32    cmd::draw(f, bottom, state);
33    if state.mode == Mode::Help {
34        help::draw(f);
35    }
36}
37
38/// ~35% of the frame, clamped to a sane band.
39fn list_width(main: Rect) -> u16 {
40    let w = (u32::from(main.width) * 35 / 100) as u16;
41    w.clamp(24, 44).min(main.width)
42}
43
44pub(crate) fn border_style(focused: bool) -> Style {
45    if focused {
46        Style::new().fg(Color::Cyan)
47    } else {
48        Style::new().dim()
49    }
50}