обновление
This commit is contained in:
83
src/ui.rs
Normal file
83
src/ui.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use ratatui::prelude::*;
|
||||
use ratatui::widgets::{Block, Borders, Gauge, List, ListItem, Paragraph};
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
pub fn draw(f: &mut Frame, app: &mut App) {
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([
|
||||
Constraint::Min(1),
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(3),
|
||||
])
|
||||
.split(f.area());
|
||||
|
||||
draw_track_list(f, app, chunks[0]);
|
||||
draw_progress(f, app, chunks[1]);
|
||||
draw_volume(f, app, chunks[2]);
|
||||
draw_status(f, app, chunks[3]);
|
||||
}
|
||||
|
||||
fn draw_track_list(f: &mut Frame, app: &mut App, area: Rect) {
|
||||
let items: Vec<ListItem> = app
|
||||
.tracks
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, t)| {
|
||||
let marker = if Some(i) == app.playing_index { "♪ " } else { " " };
|
||||
ListItem::new(format!("{}{} - {}", marker, t.artist, t.title))
|
||||
})
|
||||
.collect();
|
||||
|
||||
let list = List::new(items)
|
||||
.block(Block::default().borders(Borders::ALL).title(" Треки "))
|
||||
.highlight_style(Style::default().add_modifier(Modifier::REVERSED))
|
||||
.highlight_symbol("> ");
|
||||
|
||||
f.render_stateful_widget(list, area, &mut app.list_state);
|
||||
}
|
||||
|
||||
fn draw_progress(f: &mut Frame, app: &App, area: Rect) {
|
||||
let (pos, total) = app.progress();
|
||||
let ratio = if total.as_secs_f64() > 0.0 {
|
||||
(pos.as_secs_f64() / total.as_secs_f64()).clamp(0.0, 1.0)
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
let gauge = Gauge::default()
|
||||
.block(Block::default().borders(Borders::ALL).title(" Прогресс "))
|
||||
.gauge_style(Style::default().fg(Color::Green))
|
||||
.ratio(ratio)
|
||||
.label(format!(
|
||||
"{:02}:{:02} / {:02}:{:02}",
|
||||
pos.as_secs() / 60, pos.as_secs() % 60,
|
||||
total.as_secs() / 60, total.as_secs() % 60,
|
||||
));
|
||||
|
||||
f.render_widget(gauge, area);
|
||||
}
|
||||
|
||||
fn draw_volume(f: &mut Frame, app: &App, area: Rect) {
|
||||
let vol = app.player.volume();
|
||||
let ratio = (vol as f64 / 2.0).clamp(0.0, 1.0);
|
||||
let color = if vol > 1.0 { Color::Yellow }
|
||||
else if vol > 0.5 { Color::Cyan }
|
||||
else { Color::Blue };
|
||||
|
||||
let gauge = Gauge::default()
|
||||
.block(Block::default().borders(Borders::ALL).title(" Громкость (+/-) "))
|
||||
.gauge_style(Style::default().fg(color))
|
||||
.ratio(ratio)
|
||||
.label(format!("{}%", (vol * 100.0) as u32));
|
||||
|
||||
f.render_widget(gauge, area);
|
||||
}
|
||||
|
||||
fn draw_status(f: &mut Frame, app: &App, area: Rect) {
|
||||
let status = Paragraph::new(app.status.as_str())
|
||||
.block(Block::default().borders(Borders::ALL).title(" Статус "));
|
||||
f.render_widget(status, area);
|
||||
}
|
||||
Reference in New Issue
Block a user