pub mod theme;
pub mod header;
pub mod stations;
pub mod controls;
pub mod search;
pub mod deck;
pub mod help;
pub mod settings;
use ratatui::prelude::*;
use ratatui::widgets::{Block, Paragraph};
use crate::app::{App, InputMode, LayoutMode};
pub fn draw(frame: &mut Frame, app: &App) {
let size = frame.area();
let bg = Block::default().style(Style::default().bg(theme::bg()));
frame.render_widget(bg, size);
let is_searching = app.input_mode == InputMode::Search;
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(1)
.constraints([
Constraint::Length(1), Constraint::Length(1), Constraint::Min(5), Constraint::Length(1), Constraint::Length(2), ])
.split(size);
header::render(frame, chunks[0], app);
render_separator(frame, chunks[1]);
match app.layout_mode {
LayoutMode::Split => {
let content_chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(55), Constraint::Percentage(45)])
.split(chunks[2]);
let left_area = content_chunks[0];
let right_area = content_chunks[1];
deck::render(frame, right_area, app);
if is_searching {
let left_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(1), Constraint::Min(0)])
.split(left_area);
search::render(frame, left_chunks[0], app);
stations::render(frame, left_chunks[1], app);
} else {
stations::render(frame, left_area, app);
}
}
LayoutMode::LeftOnly => {
if is_searching {
let left_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(1), Constraint::Min(0)])
.split(chunks[2]);
search::render(frame, left_chunks[0], app);
stations::render(frame, left_chunks[1], app);
} else {
stations::render(frame, chunks[2], app);
}
}
LayoutMode::RightOnly => {
deck::render(frame, chunks[2], app);
}
}
render_separator(frame, chunks[3]);
controls::render(frame, chunks[4], app);
if app.show_help {
help::render(frame, size, app);
}
if app.show_settings {
settings::render(frame, size, app);
}
}
fn render_separator(frame: &mut Frame, area: Rect) {
let width = area.width as usize;
let line_str = "═".repeat(width);
let sep = Paragraph::new(Line::from(Span::styled(
line_str,
Style::default().fg(theme::accent()).bg(theme::bg()),
)));
frame.render_widget(sep, area);
}
pub fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
let popup_layout = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Percentage((100 - percent_y) / 2),
Constraint::Percentage(percent_y),
Constraint::Percentage((100 - percent_y) / 2),
])
.split(r);
Layout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Percentage((100 - percent_x) / 2),
Constraint::Percentage(percent_x),
Constraint::Percentage((100 - percent_x) / 2),
])
.split(popup_layout[1])[1]
}