rmp/src/ui.rs

131 lines
3.9 KiB
Rust

use ratatui::{
prelude::*,
widgets::{block::Title, *},
};
use super::app::App;
pub fn draw<B: Backend>(f: &mut Frame<B>, 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<B: Backend>(f: &mut Frame<B>, 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<B: Backend>(f: &mut Frame<B>, 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<Title> = 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)
}