use ratatui::{ prelude::*, widgets::{block::Title, *}, }; use super::app::App; pub fn draw(f: &mut Frame, app: &mut App) { let chunks = Layout::default() .constraints([Constraint::Min(3), Constraint::Length(2)].as_ref()) .split(f.size()); draw_playlist(f, app, chunks[0]); draw_player(f, app, chunks[1]); } static PRIMARY_COLOR: Color = Color::Rgb(200, 150, 70); static SECONDARY_COLOR: Color = Color::Rgb(200, 200, 200); static PRIMARY_CONTRAST: Color = Color::Black; static CLEAR_CONTRAST: Color = Color::Rgb(100, 100, 100); fn draw_playlist(f: &mut Frame, app: &App, area: Rect) { let tracks: Vec<_> = app .queue_playlist .playlist .items .iter() .enumerate() .map(|(index, path)| { let selected = app .queue_playlist .playlist .state .selected() .map_or(false, |selected| index == selected); // let playing = app // .player_state // .currently_playing // .clone() // .map_or(false, |currently_playing| currently_playing == *path); let playing = false; let mut style = Style::default(); match (selected, playing) { (true, false) => { style.fg = Some(Color::Black); style.bg = Some(PRIMARY_COLOR); } (false, true) => style.fg = Some(PRIMARY_COLOR), (true, true) => { style.fg = None; style.bg = Some(PRIMARY_COLOR); } (_, _) => (), } let content = Span::from(path.to_string_lossy().to_string()); ListItem::new(content).set_style(style) }) .collect(); let playlist = List::new(tracks) .block( Block::default() .borders(Borders::ALL) .border_style(Style::default().fg(SECONDARY_COLOR)), ) .start_corner(Corner::TopLeft); f.render_widget(playlist, area); } fn draw_player(f: &mut Frame, app: &App, area: Rect) { fn decorate_bool(span: Span, value: bool) -> Span { match value { true => span.bg(PRIMARY_COLOR).fg(PRIMARY_CONTRAST), false => span.fg(CLEAR_CONTRAST), } } let track_title = vec![ Span::from("[ "), Span::from("??").fg(PRIMARY_COLOR), Span::from(" ]"), ]; let mut block = Block::default() .borders(Borders::TOP) .border_style(Style::default().fg(SECONDARY_COLOR)) .title(track_title); // Horrible to look at, worse to write let param_titles: Vec = vec![ ( app.track_change_options.next, vec![ Span::from("NE"), Span::from("X").underlined(), Span::from("T"), ], ), ( app.track_change_options.shuffle, vec![Span::from("S").underlined(), Span::from("HUFFLE")], ), ( app.track_change_options.repeat, vec![Span::from("R").underlined(), Span::from("EPEAT")], ), ] .iter() .map(|(value, spans)| { spans .iter() .map(|span| decorate_bool(span.clone(), *value)) .collect::<Vec<_>>() }) .map(|spans| Title::from([&[Span::from(" ")], spans.as_slice(), &[Span::from(" ")]].concat())) .collect(); for title in param_titles { block = block.title(title); } let block = block.title_position(block::Position::Top); let player = Gauge::default() .block(block) .gauge_style(Style::default().fg(PRIMARY_COLOR)) .ratio(0.25) .label("[ PAUSED ]"); f.render_widget(player, area) }