add playing condition and time related widgets

This commit is contained in:
figsoda 2020-10-30 16:27:25 -04:00
parent eebd80626a
commit 85ba2e95b5
3 changed files with 69 additions and 30 deletions

View file

@ -12,19 +12,26 @@ Config(
Ratio(4, QueueAlbum), Ratio(4, QueueAlbum),
], ],
)), )),
Fixed(1, Textbox(If(TitleExist, Fixed(1, Textbox(If(Playing, Parts([
Parts([ Plain("["),
CurrentTitle, CurrentElapsed,
If(ArtistExist, Parts([ Plain("/"),
Plain(" - "), CurrentDuration,
CurrentArtist, Plain("] "),
If(AlbumExist, Parts([ If(TitleExist,
Parts([
CurrentTitle,
If(ArtistExist, Parts([
Plain(" - "), Plain(" - "),
CurrentAlbum, CurrentArtist,
If(AlbumExist, Parts([
Plain(" - "),
CurrentAlbum,
])),
])), ])),
])), ]),
]), CurrentFile,
CurrentFile, )
))), ])))),
]), ]),
) )

View file

@ -45,10 +45,13 @@ pub enum Constrained<T> {
pub enum Texts { pub enum Texts {
Empty, Empty,
Plain(String), Plain(String),
CurrentElapsed,
CurrentDuration,
CurrentFile, CurrentFile,
CurrentTitle, CurrentTitle,
CurrentArtist, CurrentArtist,
CurrentAlbum, CurrentAlbum,
QueueDuration,
QueueFile, QueueFile,
QueueTitle, QueueTitle,
QueueArtist, QueueArtist,
@ -59,6 +62,7 @@ pub enum Texts {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub enum Condition { pub enum Condition {
Playing,
TitleExist, TitleExist,
ArtistExist, ArtistExist,
AlbumExist, AlbumExist,
@ -94,10 +98,13 @@ impl<'de> Deserialize<'de> for Texts {
#[serde(field_identifier)] #[serde(field_identifier)]
enum Variant { enum Variant {
Plain, Plain,
CurrentElapsed,
CurrentDuration,
CurrentFile, CurrentFile,
CurrentTitle, CurrentTitle,
CurrentArtist, CurrentArtist,
CurrentAlbum, CurrentAlbum,
QueueDuration,
QueueFile, QueueFile,
QueueTitle, QueueTitle,
QueueArtist, QueueArtist,
@ -166,10 +173,13 @@ impl<'de> Deserialize<'de> for Texts {
match variant { match variant {
Variant::Plain => Ok(Texts::Plain(va.newtype_variant()?)), Variant::Plain => Ok(Texts::Plain(va.newtype_variant()?)),
Variant::CurrentElapsed => unit_variant!(CurrentElapsed),
Variant::CurrentDuration => unit_variant!(CurrentDuration),
Variant::CurrentFile => unit_variant!(CurrentFile), Variant::CurrentFile => unit_variant!(CurrentFile),
Variant::CurrentTitle => unit_variant!(CurrentTitle), Variant::CurrentTitle => unit_variant!(CurrentTitle),
Variant::CurrentArtist => unit_variant!(CurrentArtist), Variant::CurrentArtist => unit_variant!(CurrentArtist),
Variant::CurrentAlbum => unit_variant!(CurrentAlbum), Variant::CurrentAlbum => unit_variant!(CurrentAlbum),
Variant::QueueDuration => unit_variant!(QueueDuration),
Variant::QueueFile => unit_variant!(QueueFile), Variant::QueueFile => unit_variant!(QueueFile),
Variant::QueueTitle => unit_variant!(QueueTitle), Variant::QueueTitle => unit_variant!(QueueTitle),
Variant::QueueArtist => unit_variant!(QueueArtist), Variant::QueueArtist => unit_variant!(QueueArtist),
@ -185,10 +195,13 @@ impl<'de> Deserialize<'de> for Texts {
"Texts", "Texts",
&[ &[
"Plain", "Plain",
"CurrentElapsed",
"CurrentDuration",
"CurrentFile", "CurrentFile",
"CurrentTitle", "CurrentTitle",
"CurrentArtist", "CurrentArtist",
"CurrentAlbum", "CurrentAlbum",
"QueueDuration",
"QueueFile", "QueueFile",
"QueueTitle", "QueueTitle",
"QueueArtist", "QueueArtist",

View file

@ -102,16 +102,13 @@ pub fn render(
} }
Widget::Textbox(xss) => { Widget::Textbox(xss) => {
let mut spans = Vec::new(); let mut spans = Vec::new();
flatten( let (current_elapsed, current_track) = if let Some(Song { pos, elapsed }) = status.song
&mut spans, {
&xss, (Some(elapsed), queue.get(pos))
if let Some(Song { pos, .. }) = status.song { } else {
queue.get(pos) (None, None)
} else { };
None flatten(&mut spans, &xss, current_elapsed, current_track, None);
},
None,
);
frame.render_widget(Paragraph::new(Spans::from(spans)), size); frame.render_widget(Paragraph::new(Spans::from(spans)), size);
} }
Widget::Queue { columns } => { Widget::Queue { columns } => {
@ -128,10 +125,11 @@ pub fn render(
}); });
let len = columns.capacity(); let len = columns.capacity();
let current_track = if let Some(Song { pos, .. }) = status.song { let (current_elapsed, current_track) = if let Some(Song { pos, elapsed }) = status.song
queue.get(pos) {
(Some(elapsed), queue.get(pos))
} else { } else {
None (None, None)
}; };
for column in columns { for column in columns {
match column { match column {
@ -139,7 +137,7 @@ pub fn render(
let mut items = Vec::with_capacity(len); let mut items = Vec::with_capacity(len);
for x in queue { for x in queue {
let mut spans = Vec::new(); let mut spans = Vec::new();
flatten(&mut spans, xs, current_track, Some(x)); flatten(&mut spans, xs, current_elapsed, current_track, Some(x));
items.push(ListItem::new(Spans::from(spans))); items.push(ListItem::new(Spans::from(spans)));
} }
ws.push(List::new(items)); ws.push(List::new(items));
@ -149,7 +147,7 @@ pub fn render(
let mut items = Vec::with_capacity(len); let mut items = Vec::with_capacity(len);
for x in queue { for x in queue {
let mut spans = Vec::new(); let mut spans = Vec::new();
flatten(&mut spans, xs, current_track, Some(x)); flatten(&mut spans, xs, current_elapsed, current_track, Some(x));
items.push(ListItem::new(Spans::from(spans))); items.push(ListItem::new(Spans::from(spans)));
} }
ws.push(List::new(items)); ws.push(List::new(items));
@ -159,7 +157,7 @@ pub fn render(
let mut items = Vec::with_capacity(len); let mut items = Vec::with_capacity(len);
for x in queue { for x in queue {
let mut spans = Vec::new(); let mut spans = Vec::new();
flatten(&mut spans, xs, current_track, Some(x)); flatten(&mut spans, xs, current_elapsed, current_track, Some(x));
items.push(ListItem::new(Spans::from(spans))); items.push(ListItem::new(Spans::from(spans)));
} }
ws.push(List::new(items)); ws.push(List::new(items));
@ -185,12 +183,27 @@ pub fn render(
fn flatten( fn flatten(
spans: &mut Vec<Span>, spans: &mut Vec<Span>,
xs: &Texts, xs: &Texts,
current_elapsed: Option<u16>,
current_track: Option<&Track>, current_track: Option<&Track>,
queue_track: Option<&Track>, queue_track: Option<&Track>,
) { ) {
match xs { match xs {
Texts::Empty => (), Texts::Empty => (),
Texts::Plain(x) => spans.push(Span::raw(x.clone())), Texts::Plain(x) => spans.push(Span::raw(x.clone())),
Texts::CurrentElapsed => {
if let Some(current_elapsed) = current_elapsed {
spans.push(Span::raw(format!(
"{:02}:{:02}",
current_elapsed / 60,
current_elapsed % 60
)))
}
}
Texts::CurrentDuration => {
if let Some(Track { time, .. }) = current_track {
spans.push(Span::raw(format!("{:02}:{:02}", time / 60, time % 60,)))
}
}
Texts::CurrentFile => { Texts::CurrentFile => {
if let Some(Track { file, .. }) = current_track { if let Some(Track { file, .. }) = current_track {
spans.push(Span::raw(file.clone())); spans.push(Span::raw(file.clone()));
@ -221,6 +234,11 @@ fn flatten(
spans.push(Span::raw(album.clone())); spans.push(Span::raw(album.clone()));
} }
} }
Texts::QueueDuration => {
if let Some(Track { time, .. }) = queue_track {
spans.push(Span::raw(format!("{:02}:{:02}", time / 60, time % 60,)))
}
}
Texts::QueueFile => { Texts::QueueFile => {
if let Some(Track { file, .. }) = current_track { if let Some(Track { file, .. }) = current_track {
spans.push(Span::raw(file.clone())); spans.push(Span::raw(file.clone()));
@ -253,11 +271,12 @@ fn flatten(
} }
Texts::Parts(xss) => { Texts::Parts(xss) => {
for xs in xss { for xs in xss {
flatten(spans, xs, current_track, queue_track); flatten(spans, xs, current_elapsed, current_track, queue_track);
} }
} }
Texts::If(cond, box yes, box no) => { Texts::If(cond, box yes, box no) => {
let xs = if match cond { let xs = if match cond {
Condition::Playing => current_track.is_some(),
Condition::TitleExist => { Condition::TitleExist => {
matches!(current_track, Some(Track { title: Some(_), .. })) matches!(current_track, Some(Track { title: Some(_), .. }))
} }
@ -273,7 +292,7 @@ fn flatten(
} else { } else {
no no
}; };
flatten(spans, xs, current_track, queue_track); flatten(spans, xs, current_elapsed, current_track, queue_track);
} }
} }
} }