use crate::Rgb;
#[cfg(feature = "ratatui")]
use crate::{Layout, Splash, presets};
#[derive(Clone, Debug)]
pub struct StartScreenTheme {
pub text_dim: Rgb,
pub text: Rgb,
pub cursor_line_bg: Rgb,
}
impl Default for StartScreenTheme {
fn default() -> Self {
Self {
text_dim: Rgb(0x3b, 0x42, 0x52),
text: Rgb(0xd8, 0xde, 0xe9),
cursor_line_bg: Rgb(0x2e, 0x34, 0x40),
}
}
}
pub struct StartScreen {
pub version: String,
pub palette: StartScreenTheme,
}
impl StartScreen {
pub fn build(version: &str) -> Self {
Self {
version: version.to_string(),
palette: StartScreenTheme::default(),
}
}
}
#[cfg(feature = "ratatui")]
pub fn render(frame: &mut ratatui::Frame, area: ratatui::layout::Rect, screen: &StartScreen) {
use crate::{CellKind, default_trail_color};
use ratatui::{
layout::Rect,
style::{Color, Style},
text::{Line, Span},
widgets::Widget,
};
let splash = Splash::new(presets::hjkl::ART, presets::hjkl::PATH);
let layout = Layout::centered(
area.width,
area.height,
presets::hjkl::ROWS,
presets::hjkl::COLS,
);
let buf = frame.buffer_mut();
for cell in splash.cells(layout) {
let x = area.x + cell.x;
let y = area.y + cell.y;
if x >= area.x + area.width || y >= area.y + area.height {
continue;
}
let buf_cell = buf.cell_mut((x, y)).unwrap_or_else(|| {
panic!("start_screen: cell ({x},{y}) out of buffer bounds");
});
buf_cell.set_char(cell.ch);
let style = match cell.kind {
CellKind::Art => Style::default().fg(Color::from(screen.palette.text_dim)),
CellKind::Trail { age } => {
let trail_rgb = default_trail_color(age);
Style::default().fg(Color::from(trail_rgb))
}
CellKind::Cursor => Style::default()
.fg(Color::from(screen.palette.text))
.bg(Color::from(screen.palette.cursor_line_bg)),
};
buf_cell.set_style(style);
}
let ver_y = area.y + layout.origin_y + presets::hjkl::ROWS + 1;
if ver_y < area.y + area.height {
let ver_line = Line::from(vec![Span::styled(
format!(" hjkl v{}", screen.version),
Style::default().fg(Color::from(screen.palette.text_dim)),
)]);
let ver_area = Rect {
x: area.x + layout.origin_x,
y: ver_y,
width: area.width.saturating_sub(layout.origin_x),
height: 1,
};
ver_line.render(ver_area, buf);
}
let hint_y = ver_y + 1;
if hint_y < area.y + area.height {
let hint_line = Line::from(vec![Span::styled(
" :e <file> to open",
Style::default().fg(Color::from(screen.palette.text_dim)),
)]);
let hint_area = Rect {
x: area.x + layout.origin_x,
y: hint_y,
width: area.width.saturating_sub(layout.origin_x),
height: 1,
};
hint_line.render(hint_area, buf);
}
}