use std::path::PathBuf;
use crate::{Splash, presets};
#[derive(Clone, Debug)]
pub struct StartScreenTheme {
pub text_dim: crate::Rgb,
pub text: crate::Rgb,
pub cursor_line_bg: crate::Rgb,
}
impl Default for StartScreenTheme {
fn default() -> Self {
Self {
text_dim: crate::Rgb(0x4c, 0x56, 0x6a),
text: crate::Rgb(0xd8, 0xde, 0xe9),
cursor_line_bg: crate::Rgb(0x3b, 0x42, 0x52),
}
}
}
pub struct StartScreen {
pub splash: Splash<'static>,
pub version: String,
pub key_hints: Vec<(String, String)>,
pub recent_files: Vec<PathBuf>,
pub palette: StartScreenTheme,
}
impl StartScreen {
pub fn build(version: &str) -> Self {
Self {
splash: Splash::new(presets::hjkl::ART, presets::hjkl::PATH),
version: version.to_owned(),
key_hints: vec![
(":e <file>".to_owned(), "open a file".to_owned()),
(":q".to_owned(), "quit".to_owned()),
],
recent_files: Vec::new(),
palette: StartScreenTheme::default(),
}
}
}
#[cfg(feature = "ratatui")]
mod tui {
use ratatui::{
Frame,
layout::Rect,
style::{Color, Style},
text::{Line, Span},
widgets::Paragraph,
};
use crate::{CellKind, Layout, default_trail_color, presets};
use super::StartScreen;
pub fn render(frame: &mut Frame, area: Rect, screen: &StartScreen) {
let layout = Layout::centered(
area.width,
area.height,
presets::hjkl::ROWS,
presets::hjkl::COLS,
);
let art_top = area.y + layout.origin_y;
let art_left = area.x + layout.origin_x;
let abs_layout = crate::Layout {
origin_x: art_left,
origin_y: art_top,
..layout
};
let palette = &screen.palette;
let text_dim: Color = palette.text_dim.into();
let text: Color = palette.text.into();
let cursor_bg: Color = palette.cursor_line_bg.into();
let buf = frame.buffer_mut();
for cell in screen.splash.cells(abs_layout) {
if cell.x >= area.x + area.width || cell.y >= area.y + area.height {
continue;
}
match cell.kind {
CellKind::Art => {
if let Some(buf_cell) = buf.cell_mut((cell.x, cell.y)) {
buf_cell.set_char(cell.ch);
buf_cell.set_style(Style::default().fg(text_dim));
}
}
CellKind::Trail { age } => {
let color: Color = default_trail_color(age).into();
if let Some(buf_cell) = buf.cell_mut((cell.x, cell.y)) {
buf_cell.set_char(cell.ch);
buf_cell.set_style(Style::default().fg(color));
}
}
CellKind::Cursor => {
if let Some(buf_cell) = buf.cell_mut((cell.x, cell.y)) {
buf_cell.set_char(cell.ch);
buf_cell.set_style(Style::default().fg(text).bg(cursor_bg));
}
}
}
}
let hint_style = Style::default().fg(text_dim);
let cta = "press any key to start editing";
let cmd_col_width = screen
.key_hints
.iter()
.map(|(cmd, _)| cmd.len())
.max()
.unwrap_or(0);
let gap = 3usize;
let block_width = screen
.key_hints
.iter()
.map(|(_, desc)| cmd_col_width + gap + desc.len())
.max()
.unwrap_or(0) as u16;
let cta_y = art_top + presets::hjkl::ROWS + 1;
if cta_y < area.y + area.height {
let cta_len = cta.len() as u16;
let x = area.x + area.width.saturating_sub(cta_len) / 2;
let rect = Rect {
x,
y: cta_y,
width: cta_len.min(area.width),
height: 1,
};
frame.render_widget(
Paragraph::new(Line::from(vec![Span::styled(cta, hint_style)])),
rect,
);
}
let block_x = area.x + area.width.saturating_sub(block_width) / 2;
for (i, (cmd, desc)) in screen.key_hints.iter().enumerate() {
let y = art_top + presets::hjkl::ROWS + 3 + i as u16;
if y >= area.y + area.height {
break;
}
let line = format!("{cmd:<cmd_col_width$}{:gap$}{desc}", "");
let rect = Rect {
x: block_x,
y,
width: block_width.min(area.width),
height: 1,
};
frame.render_widget(
Paragraph::new(Line::from(vec![Span::styled(line, hint_style)])),
rect,
);
}
}
}
#[cfg(feature = "ratatui")]
pub use tui::render;
#[cfg(feature = "gui")]
pub fn render_gui(_screen: &StartScreen) {
}