use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect};
use ratatui::style::Modifier;
use ratatui::text::{Line, Span};
use ratatui::widgets::Paragraph;
use ratatui::Frame;
use crate::content::Mode;
use crate::ui::theme::Theme;
#[derive(Debug, Clone)]
pub struct MenuState {
pub selected_mode: Mode,
pub selected_language: String,
pub selected_duration: u64,
pub language_options: Vec<String>,
}
impl MenuState {
pub fn new(mode: Mode, language: String, duration: u64) -> Self {
let language_options = mode.languages().iter().map(|&s| s.to_string()).collect();
Self {
selected_mode: mode,
selected_language: language,
selected_duration: duration,
language_options,
}
}
}
pub fn render(f: &mut Frame, state: &MenuState, theme: &Theme, area: Rect) {
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(2)
.constraints([
Constraint::Length(3),
Constraint::Min(10),
Constraint::Length(3),
])
.split(area);
let title = Paragraph::new(vec![
Line::from(Span::styled(" typetui ", theme.style_accent())),
Line::from(Span::styled(" a beautiful terminal typing test ", theme.style_muted())),
])
.alignment(Alignment::Center);
f.render_widget(title, chunks[0]);
let menu_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(6),
Constraint::Length(5),
Constraint::Min(0),
])
.split(chunks[1]);
render_settings_summary(f, state, theme, menu_chunks[0]);
render_start_button(f, theme, menu_chunks[1]);
let help = Paragraph::new(Line::from(vec![
Span::styled("enter ", theme.style_accent()),
Span::styled("start ", theme.style_muted()),
Span::styled("ctrl+m ", theme.style_accent()),
Span::styled("mode ", theme.style_muted()),
Span::styled("ctrl+l ", theme.style_accent()),
Span::styled("lang ", theme.style_muted()),
Span::styled("ctrl+d ", theme.style_accent()),
Span::styled("duration ", theme.style_muted()),
Span::styled("ctrl+t ", theme.style_accent()),
Span::styled("theme ", theme.style_muted()),
Span::styled("ctrl+p ", theme.style_accent()),
Span::styled("profile ", theme.style_muted()),
Span::styled("esc ", theme.style_accent()),
Span::styled("quit", theme.style_muted()),
]))
.alignment(Alignment::Center);
f.render_widget(help, chunks[2]);
}
fn render_settings_summary(f: &mut Frame, state: &MenuState, theme: &Theme, area: Rect) {
let text = vec![
Line::from(vec![
Span::styled("mode: ", theme.style_muted()),
Span::styled(
state.selected_mode.as_str(),
theme.style(theme.accent).add_modifier(Modifier::BOLD),
),
]),
Line::from(vec![
Span::styled("language: ", theme.style_muted()),
Span::styled(
&state.selected_language,
theme.style(theme.accent).add_modifier(Modifier::BOLD),
),
]),
Line::from(vec![
Span::styled("duration: ", theme.style_muted()),
Span::styled(
format!("{}s", state.selected_duration),
theme.style(theme.accent).add_modifier(Modifier::BOLD),
),
]),
];
let paragraph = Paragraph::new(text).alignment(Alignment::Center);
f.render_widget(paragraph, area);
}
fn render_start_button(f: &mut Frame, theme: &Theme, area: Rect) {
let style = theme
.style(theme.success)
.add_modifier(Modifier::BOLD);
let text = vec![
Line::from(""),
Line::from(vec![Span::styled(
" press enter to start ",
style,
)]),
];
let paragraph = Paragraph::new(text).alignment(Alignment::Center);
f.render_widget(paragraph, area);
}