diff --git a/mmtc.ron b/mmtc.ron index fbb1016..20a1305 100644 --- a/mmtc.ron +++ b/mmtc.ron @@ -12,19 +12,26 @@ Config( Ratio(4, QueueAlbum), ], )), - Fixed(1, Textbox(If(TitleExist, - Parts([ - CurrentTitle, - If(ArtistExist, Parts([ - Plain(" - "), - CurrentArtist, - If(AlbumExist, Parts([ + Fixed(1, Textbox(If(Playing, Parts([ + Plain("["), + CurrentElapsed, + Plain("/"), + CurrentDuration, + Plain("] "), + If(TitleExist, + Parts([ + CurrentTitle, + If(ArtistExist, Parts([ Plain(" - "), - CurrentAlbum, + CurrentArtist, + If(AlbumExist, Parts([ + Plain(" - "), + CurrentAlbum, + ])), ])), - ])), - ]), - CurrentFile, - ))), + ]), + CurrentFile, + ) + ])))), ]), ) diff --git a/src/config.rs b/src/config.rs index 8cc2ddc..c64c8cb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -45,10 +45,13 @@ pub enum Constrained { pub enum Texts { Empty, Plain(String), + CurrentElapsed, + CurrentDuration, CurrentFile, CurrentTitle, CurrentArtist, CurrentAlbum, + QueueDuration, QueueFile, QueueTitle, QueueArtist, @@ -59,6 +62,7 @@ pub enum Texts { #[derive(Debug, Deserialize)] pub enum Condition { + Playing, TitleExist, ArtistExist, AlbumExist, @@ -94,10 +98,13 @@ impl<'de> Deserialize<'de> for Texts { #[serde(field_identifier)] enum Variant { Plain, + CurrentElapsed, + CurrentDuration, CurrentFile, CurrentTitle, CurrentArtist, CurrentAlbum, + QueueDuration, QueueFile, QueueTitle, QueueArtist, @@ -166,10 +173,13 @@ impl<'de> Deserialize<'de> for Texts { match 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::CurrentTitle => unit_variant!(CurrentTitle), Variant::CurrentArtist => unit_variant!(CurrentArtist), Variant::CurrentAlbum => unit_variant!(CurrentAlbum), + Variant::QueueDuration => unit_variant!(QueueDuration), Variant::QueueFile => unit_variant!(QueueFile), Variant::QueueTitle => unit_variant!(QueueTitle), Variant::QueueArtist => unit_variant!(QueueArtist), @@ -185,10 +195,13 @@ impl<'de> Deserialize<'de> for Texts { "Texts", &[ "Plain", + "CurrentElapsed", + "CurrentDuration", "CurrentFile", "CurrentTitle", "CurrentArtist", "CurrentAlbum", + "QueueDuration", "QueueFile", "QueueTitle", "QueueArtist", diff --git a/src/layout.rs b/src/layout.rs index 7015104..a8c787f 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -102,16 +102,13 @@ pub fn render( } Widget::Textbox(xss) => { let mut spans = Vec::new(); - flatten( - &mut spans, - &xss, - if let Some(Song { pos, .. }) = status.song { - queue.get(pos) - } else { - None - }, - None, - ); + let (current_elapsed, current_track) = if let Some(Song { pos, elapsed }) = status.song + { + (Some(elapsed), queue.get(pos)) + } else { + (None, None) + }; + flatten(&mut spans, &xss, current_elapsed, current_track, None); frame.render_widget(Paragraph::new(Spans::from(spans)), size); } Widget::Queue { columns } => { @@ -128,10 +125,11 @@ pub fn render( }); let len = columns.capacity(); - let current_track = if let Some(Song { pos, .. }) = status.song { - queue.get(pos) + let (current_elapsed, current_track) = if let Some(Song { pos, elapsed }) = status.song + { + (Some(elapsed), queue.get(pos)) } else { - None + (None, None) }; for column in columns { match column { @@ -139,7 +137,7 @@ pub fn render( let mut items = Vec::with_capacity(len); for x in queue { 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))); } ws.push(List::new(items)); @@ -149,7 +147,7 @@ pub fn render( let mut items = Vec::with_capacity(len); for x in queue { 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))); } ws.push(List::new(items)); @@ -159,7 +157,7 @@ pub fn render( let mut items = Vec::with_capacity(len); for x in queue { 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))); } ws.push(List::new(items)); @@ -185,12 +183,27 @@ pub fn render( fn flatten( spans: &mut Vec, xs: &Texts, + current_elapsed: Option, current_track: Option<&Track>, queue_track: Option<&Track>, ) { match xs { Texts::Empty => (), 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 => { if let Some(Track { file, .. }) = current_track { spans.push(Span::raw(file.clone())); @@ -221,6 +234,11 @@ fn flatten( 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 => { if let Some(Track { file, .. }) = current_track { spans.push(Span::raw(file.clone())); @@ -253,11 +271,12 @@ fn flatten( } Texts::Parts(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) => { let xs = if match cond { + Condition::Playing => current_track.is_some(), Condition::TitleExist => { matches!(current_track, Some(Track { title: Some(_), .. })) } @@ -273,7 +292,7 @@ fn flatten( } else { no }; - flatten(spans, xs, current_track, queue_track); + flatten(spans, xs, current_elapsed, current_track, queue_track); } } }