use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::text::{Line, Span};
use ratatui::widgets::Paragraph;
use super::super::app::{App, GLOBAL_CONFIG_ROWS, GlobalConfigRow};
use super::super::theme::{self, Tier};
use super::panes::{highlight_row, section_box};
const KEY_W: usize = 12;
pub(super) fn draw(frame: &mut Frame<'_>, area: Rect, app: &App) {
let block = section_box("settings", true, true);
let inner = block.inner(area);
frame.render_widget(block, area);
let wrap_off = app.config().state.wrap_off;
let cursor = app
.global_config_cursor
.min(GLOBAL_CONFIG_ROWS.len().saturating_sub(1));
let mut lines: Vec<Line<'static>> = Vec::new();
for (i, row) in GLOBAL_CONFIG_ROWS.iter().enumerate() {
let selected = i == cursor;
let line = detail_row(*row, selected, wrap_off);
lines.push(if selected {
highlight_row(line, inner.width as usize)
} else {
line
});
if selected && let Some(tip) = row_hint(*row) {
lines.push(Line::from(vec![
Span::styled(" └ ", theme::faint()),
Span::styled(tip, theme::faint()),
]));
}
}
frame.render_widget(Paragraph::new(lines).style(theme::base()), inner);
}
fn row_hint(row: GlobalConfigRow) -> Option<&'static str> {
match row {
GlobalConfigRow::Theme => None,
GlobalConfigRow::WrapOff => {
Some("default when every fallback member is over its threshold")
}
}
}
fn detail_row(row: GlobalConfigRow, selected: bool, wrap_off: bool) -> Line<'static> {
let arrow = if selected {
Span::styled("❯ ", theme::accent())
} else {
Span::raw(" ")
};
let tier = theme::tier();
match row {
GlobalConfigRow::Theme => cycle_row(
arrow,
"theme",
&[
("full", tier == Tier::Full),
("compatible", tier == Tier::Compatible),
],
selected,
),
GlobalConfigRow::WrapOff => cycle_row(
arrow,
"when spent",
&[("stay on last", !wrap_off), ("switch off all", wrap_off)],
selected,
),
}
}
fn cycle_row(
arrow: Span<'static>,
key: &str,
options: &[(&str, bool)],
row_selected: bool,
) -> Line<'static> {
let pad = KEY_W.saturating_sub(key.chars().count()).max(1);
let mut spans = vec![
arrow,
Span::styled(format!("{key}{}", " ".repeat(pad)), theme::body()),
];
for (i, (label, active)) in options.iter().enumerate() {
if i > 0 {
spans.push(Span::raw(" "));
}
spans.push(cycle_option(label, *active, row_selected));
}
Line::from(spans)
}
fn cycle_option(label: &str, active: bool, row_selected: bool) -> Span<'static> {
if active {
let text = if row_selected {
format!("[{label}]")
} else {
format!(" {label} ")
};
Span::styled(text, theme::accent())
} else {
Span::styled(label.to_string(), theme::faint())
}
}