cuj-tui 0.1.0

cui — a read-only TUI browser for cuj vaults
Documentation
//! Drawing: pure functions from `&AppState` to the frame. The only
//! state the draw pass writes back is the measured viewport
//! heights, which the reducer needs for paging.

pub mod bars;
pub mod cmd;
pub mod help;
pub mod list;
pub mod view;

use ratatui::Frame;
use ratatui::layout::{Constraint, Layout, Rect};
use ratatui::style::{Color, Style, Stylize};

use crate::state::{AppState, Mode};

pub fn draw(f: &mut Frame, state: &mut AppState) {
    let [global, context, main, bottom] = Layout::vertical([
        Constraint::Length(1),
        Constraint::Length(1),
        Constraint::Min(0),
        Constraint::Length(1),
    ])
    .areas(f.area());

    let [left, right] =
        Layout::horizontal([Constraint::Length(list_width(main)), Constraint::Min(0)]).areas(main);

    bars::draw(f, global, context, state);
    list::draw(f, left, state);
    view::draw(f, right, state);
    cmd::draw(f, bottom, state);
    if state.mode == Mode::Help {
        help::draw(f);
    }
}

/// ~35% of the frame, clamped to a sane band.
fn list_width(main: Rect) -> u16 {
    let w = (u32::from(main.width) * 35 / 100) as u16;
    w.clamp(24, 44).min(main.width)
}

pub(crate) fn border_style(focused: bool) -> Style {
    if focused {
        Style::new().fg(Color::Cyan)
    } else {
        Style::new().dim()
    }
}