use std::cell::Cell;
use ratatui::{
Frame, layout::Rect, style::Modifier, text::Line, widgets::Paragraph,
};
use super::{chrome, nav, scroll, style};
use crate::theme::Skin;
pub fn render(
frame: &mut Frame,
area: Rect,
skin: &Skin,
rows: Vec<Line<'static>>,
selected: usize,
offset: &Cell<usize>,
) {
let viewport = area.height as usize;
let total = rows.len();
let visible_offset =
nav::keep_visible(offset.get(), selected, viewport, total);
offset.set(visible_offset);
let highlight = if skin.is_fancy() {
style::bg(skin.palette.accent_dark)
.fg(style::to_ratatui(skin.palette.accent))
.add_modifier(Modifier::BOLD)
} else {
style::bg(skin.palette.selection_bg)
};
let visible: Vec<Line> = rows
.into_iter()
.enumerate()
.skip(visible_offset)
.take(viewport)
.map(|(index, line)| {
if index == selected {
line.style(highlight)
} else {
line
}
})
.collect();
frame.render_widget(Paragraph::new(visible), area);
scroll::render_scrollbar(frame, area, total, visible_offset, viewport);
}
#[allow(clippy::too_many_arguments)]
pub fn render_boxed(
frame: &mut Frame,
area: Rect,
skin: &Skin,
rows: Vec<Line<'static>>,
selected: usize,
offset: &Cell<usize>,
decor: &chrome::BoxDecor,
force: bool,
) {
let inner = if force || skin.is_fancy() {
chrome::framed_decor(frame, area, skin, decor, &rows.len().to_string())
} else {
area
};
render(frame, inner, skin, rows, selected, offset);
}