From cec104c47e08a2491feffab0367ecd385611f547 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 11 Sep 2024 14:09:44 +0200 Subject: [PATCH] screen: click on progress bar seeks current song Closes https://github.com/MusicPlayerDaemon/ncmpc/issues/135 --- NEWS | 1 + src/ProgressBar.hxx | 9 +++++++++ src/screen.cxx | 37 +++++++++++++++++++++++++++++++++++++ src/screen.hxx | 2 ++ 4 files changed, 49 insertions(+) diff --git a/NEWS b/NEWS index 727c1131..f8f6027f 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ ncmpc 0.50 - not yet released * lyrics/google: fix partial loading of lyrics * support MPD 0.22 tag "label" (requires libmpdclient 2.17) * fix config file overriding MPD_HOST environment variable +* click on progress bar seeks current song ncmpc 0.49 - (2023-08-04) * fix UI freeze if lyrics plugin is stuck diff --git a/src/ProgressBar.hxx b/src/ProgressBar.hxx index bed61875..30e2f678 100644 --- a/src/ProgressBar.hxx +++ b/src/ProgressBar.hxx @@ -20,6 +20,15 @@ public: bool Set(unsigned current, unsigned max) noexcept; + int ValueAtX(int x) const noexcept { + if (max == 0 || x < 0) + return -1; + + const unsigned ux = static_cast(x); + const unsigned window_width = window.GetWidth(); + return ux * max / window_width; + } + void Paint() const noexcept; private: diff --git a/src/screen.cxx b/src/screen.cxx index 039a6932..0f91248d 100644 --- a/src/screen.cxx +++ b/src/screen.cxx @@ -305,6 +305,33 @@ ScreenManager::OnCommand(struct mpdclient &c, DelayedSeek &seek, Command cmd) #ifdef HAVE_GETMOUSE +inline void +ScreenManager::OnProgressBarMouse(struct mpdclient &c, DelayedSeek &seek, + int x, mmask_t bstate) +{ + if (bstate & BUTTON1_CLICKED) { + if (!c.IsReady() || !c.playing_or_paused) + return; + + const int time = progress_bar.ValueAtX(x); + if (time < 0) + return; + + const int id = c.GetCurrentSongId(); + if (id < 0) + return; + + seek.Cancel(); + + struct mpd_connection *connection = c.GetConnection(); + if (connection == nullptr) + return; + + if (!mpd_run_seek_id(connection, id, time)) + c.HandleError(); + } +} + void ScreenManager::OnMouse(struct mpdclient &c, DelayedSeek &seek, Point p, mmask_t bstate) @@ -318,6 +345,16 @@ ScreenManager::OnMouse(struct mpdclient &c, DelayedSeek &seek, p.y -= title_height; } + if (int main_height = main_window.GetSize().height; p.y >= main_height) { + p.y -= main_height; + + if (p.y == 0) { + OnProgressBarMouse(c, seek, p.x, bstate); + } + + return; + } + if (GetCurrentPage().OnMouse(c, p, bstate)) return; diff --git a/src/screen.hxx b/src/screen.hxx index d654552f..d71ed9bb 100644 --- a/src/screen.hxx +++ b/src/screen.hxx @@ -123,6 +123,8 @@ public: void OnCommand(struct mpdclient &c, DelayedSeek &seek, Command cmd); #ifdef HAVE_GETMOUSE + void OnProgressBarMouse(struct mpdclient &c, DelayedSeek &seek, + int x, mmask_t bstate); void OnMouse(struct mpdclient &c, DelayedSeek &seek, Point p, mmask_t bstate); #endif