Skip to content

Commit

Permalink
actually fixing floating lyrics
Browse files Browse the repository at this point in the history
  • Loading branch information
feois committed Jun 24, 2024
1 parent 07cfdf8 commit 436400e
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 90 deletions.
97 changes: 48 additions & 49 deletions src/lyrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ pub trait LyricsTrait {
type Error;

fn new(layout: LyricsLayout) -> std::result::Result<Self, Self::Error> where Self: Sized;
fn is_showing(&self) -> Result<bool, Self::Error> { Ok(false) }
fn reset(&mut self) -> Result<(), Self::Error> { Ok(()) }
fn start(&mut self, _lyrics: Vec<(u32, String)>) -> Result<(), Self::Error> { Ok(()) }
fn begin(&mut self, _lyrics: impl IntoIterator<Item = (Duration, String)>) -> Result<(), Self::Error> { Ok(()) }
fn end(&mut self) -> Result<(), Self::Error> { Ok(()) }
fn update(&mut self, _time: Duration) -> Result<(), Self::Error> { Ok(()) }
fn set_layout(&mut self, _layout: LyricsLayout) -> Result<(), Self::Error> { Ok(()) }
}
Expand Down Expand Up @@ -87,7 +86,7 @@ mod xosd {

let (o1, o2, o3) = match v {
VerticalAlign::Top => (0, small, small + big),
VerticalAlign::Center => (big, 0, -big),
VerticalAlign::Center => ((small + big) / 2, 0, -(small + big) / 2),
VerticalAlign::Bottom => (small + big, small, 0),
};

Expand All @@ -100,7 +99,12 @@ mod xosd {

#[inline(always)]
fn show(xosd: &mut Xosd, string: Option<String>) -> Result<()> {
xosd.display(0, Command::String(string.unwrap_or_default()))?;
if let Some(string) = string {
xosd.display(0, Command::String(string))?;
}
else if xosd.onscreen()? {
xosd.hide()?;
}

Ok(())
}
Expand All @@ -125,16 +129,35 @@ mod xosd {
}

pub struct XosdLyrics {
lines: Vec<(u32, String)>,
index: usize,
showing: bool,
hidden: bool,
lines: Vec<(Duration, String)>,
index: Option<usize>,
layout: LyricsLayout,
prev: Xosd,
curr: Xosd,
next: Xosd,
}

impl XosdLyrics {
#[inline(always)]
fn update_text(&mut self) -> Result<()> {
if self.layout.visible {
if let Some(index) = self.index {
show(&mut self.prev, (index > 1).then(|| self.lines[index - 2].1[1..].to_string()))?;
show(&mut self.curr, (index > 0).then(|| self.lines[index - 1].1[1..].to_string()))?;
show(&mut self.next, (index < self.lines.len()).then(|| self.lines[index].1[1..].to_string()))?;

return Ok(());
}
}

show(&mut self.prev, None)?;
show(&mut self.curr, None)?;
show(&mut self.next, None)?;

Ok(())
}
}

impl LyricsTrait for XosdLyrics {
type Error = Error;

Expand All @@ -144,9 +167,7 @@ mod xosd {

Ok(Self {
lines: Vec::new(),
index: usize::MAX,
showing: false,
hidden: false,
index: None,
layout,
prev,
curr,
Expand All @@ -155,7 +176,7 @@ mod xosd {
}

#[inline(always)]
fn set_layout(&mut self, layout: LyricsLayout) -> std::result::Result<(), Self::Error> {
fn set_layout(&mut self, layout: LyricsLayout) -> Result<()> {
if self.layout.visible != layout.visible {
self.layout.visible = layout.visible;
}
Expand All @@ -168,59 +189,37 @@ mod xosd {
self.next = next;

self.layout = layout;
self.index = usize::MAX;
self.update_text()?;
}

Ok(())
}

#[inline(always)]
fn is_showing(&self) -> std::result::Result<bool, Self::Error> {
Ok(self.showing)
}

#[inline(always)]
fn reset(&mut self) -> std::result::Result<(), Self::Error> {
if self.showing {
show(&mut self.prev, None)?;
show(&mut self.curr, None)?;
show(&mut self.next, None)?;

self.showing = false;
}
fn begin(&mut self, lyrics: impl IntoIterator<Item = (Duration, String)>) -> Result<()> {
self.lines = lyrics.into_iter().collect();
self.lines.sort_by_key(|&(t, _)| t);
self.index = Some(0);
self.update_text()?;

Ok(())
}

#[inline(always)]
fn start(&mut self, lyrics: Vec<(u32, String)>) -> std::result::Result<(), Self::Error> {
self.lines = lyrics;
self.lines.sort_by_key(|&(t, _)| t);
self.index = usize::MAX;
fn end(&mut self) -> Result<()> {
self.index = None;
self.update_text()?;

Ok(())
}

#[inline(always)]
fn update(&mut self, time: Duration) -> Result<()> {
if self.layout.visible {
let i = self.lines.partition_point(|&(t, _)| time.as_millis() > t as u128);

if self.hidden || i != self.index {
self.index = i;
self.hidden = false;

show(&mut self.prev, (i > 1).then(|| self.lines[i - 2].1[1..].to_string()))?;
show(&mut self.curr, (i > 0).then(|| self.lines[i - 1].1[1..].to_string()))?;
show(&mut self.next, (i < self.lines.len()).then(|| self.lines[i].1[1..].to_string()))?;
}
}
else if !self.hidden {
show(&mut self.prev, None)?;
show(&mut self.curr, None)?;
show(&mut self.next, None)?;

self.hidden = true;
let i = self.lines.partition_point(|&(t, _)| time > t);

if self.index.is_some_and(|index| i != index) {
self.index.replace(i);
self.update_text()?;
}

Ok(())
Expand Down
55 changes: 14 additions & 41 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,44 +244,15 @@ impl App {
}
}
PlayerState::Finished => {
if let Some(lyrics) = &mut app.lyrics {
if let Err(e) = lyrics.reset() {
println!("RUST-ERROR: Failed to reset lyrics {}", e)
}
}

app.player.idle();

if app.stop_next {
if app.stop_next || app.playlist.poll().map(str::to_string).map(|s| app.play(&s)).is_none() {
app.stop_next = false;
["STOP"].gui_write_if(&mut app);

println!("STATUS: Idle");
}
else {
app.poll();
}

if let PlayerState::Idle = app.player.get_state() {
if let Some(lyrics) = &mut app.lyrics {
match lyrics.is_showing() {
Ok(true) => if let Err(e) = lyrics.reset() {
println!("RUST-ERROR: Failed to reset lyrics {}", e)
}
Ok(false) => {}
Err(e) => println!("RUST-ERROR: Failed to retrieve lyrics status {}", e)
}
}
}
}
PlayerState::Idle => {
if let Some(lyrics) = &mut app.lyrics {
match lyrics.is_showing() {
Ok(true) => if let Err(e) = lyrics.reset() {
println!("RUST-ERROR: Failed to reset lyrics {}", e)
}
Ok(false) => {}
Err(e) => println!("RUST-ERROR: Failed to retrieve lyrics status {}", e)
}

app.end_lyrics();
}
}
_ => {}
Expand Down Expand Up @@ -336,7 +307,7 @@ impl App {
self.request_duration = true;
self.show_lyrics(song);
}
"STOP" => self.player.stop(),
"STOP" => { self.player.stop(); self.end_lyrics() }
"REPLAY" => if let Some(song) = self.playlist.get_history().get_current().cloned() { self.play(&song) }
"PREV" => if let Some(song) = self.playlist.look_back() { self.play(&song); }
"SKIP" => self.player.skip(),
Expand Down Expand Up @@ -411,6 +382,7 @@ impl App {
if comb == self.stop_player {
["STOP"].gui_write_if(self);
self.player.stop();
self.end_lyrics();
}

if comb == self.volume_increase {
Expand Down Expand Up @@ -624,7 +596,7 @@ impl App {
match Tag::read_from_path(path) {
Ok(tag) => {
if let Some(l) = tag.synchronised_lyrics().find(|l| l.lang == "eng") {
if let Err(e) = lyrics.start(l.content.clone()) {
if let Err(e) = lyrics.begin(l.content.iter().map(|(t, s)| (Duration::from_millis((*t).into()), s.clone()))) {
println!("RUST-ERROR: Failed to display lyrics {}", e)
}
}
Expand All @@ -635,12 +607,13 @@ impl App {
}

#[inline(always)]
fn poll(&mut self) {
if let Some(song) = self.playlist.poll().map(str::to_string) {
self.play(&song);
}
else {
println!("STATUS: Idle");
fn end_lyrics(&mut self) {
println!("ended");

if let Some(lyrics) = &mut self.lyrics {
if let Err(e) = lyrics.end() {
println!("RUST-ERROR: Failed to reset lyrics {}", e)
}
}
}
}
Expand Down

0 comments on commit 436400e

Please sign in to comment.