From 2856d5cd782ae9d1832a6274ca88c2bb053bf105 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Fri, 20 Feb 2009 15:30:30 +0100 Subject: [PATCH] make playlist's stats scrollable, also display remaining time on demand --- doc/config | 2 + src/ncmpcpp.cpp | 3 +- src/playlist.cpp | 116 +++++++++++++++++++++++++++++------------------ src/playlist.h | 14 +++++- src/settings.cpp | 5 ++ src/settings.h | 1 + src/status.cpp | 7 +++ 7 files changed, 102 insertions(+), 46 deletions(-) diff --git a/doc/config b/doc/config index 75b63539..8a09b9de 100644 --- a/doc/config +++ b/doc/config @@ -104,6 +104,8 @@ # ##### various settings ##### # +#playlist_show_remaining_time = "no" +# #playlist_display_mode = "classic" (classic/columns) # #browser_display_mode = "classic" (classic/columns) diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 9e0e4c9c..a217afd4 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -206,7 +206,7 @@ int main(int argc, char *argv[]) // header stuff gettimeofday(&past, 0); if (((past.tv_sec == now.tv_sec && past.tv_usec >= now.tv_usec+500000) || past.tv_sec > now.tv_sec) - && (myScreen == myBrowser || myScreen == myLyrics) + && (myScreen == myPlaylist || myScreen == myBrowser || myScreen == myLyrics) ) { redraw_header = 1; @@ -1451,6 +1451,7 @@ int main(int argc, char *argv[]) { time(&timer); myPlaylist->Main()->Highlighting(1); + Playlist::ReloadTotalLength = 1; redraw_header = 1; } } diff --git a/src/playlist.cpp b/src/playlist.cpp index aea7ad28..68657dca 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -34,6 +34,9 @@ using std::vector; Playlist *myPlaylist = new Playlist; +bool Playlist::ReloadTotalLength = 0; +bool Playlist::ReloadRemaining = 0; + bool Playlist::BlockNowPlayingUpdate = 0; bool Playlist::BlockUpdate = 0; bool Playlist::BlockRefreshing = 0; @@ -81,6 +84,8 @@ void Playlist::SwitchTo() if (myScreen == this) return; + itsScrollBegin = 0; + if (hasToBeResized) Resize(); @@ -101,7 +106,9 @@ void Playlist::Resize() std::string Playlist::Title() { std::string result = "Playlist "; - result += TotalLength(); + if (ReloadTotalLength || ReloadRemaining) + itsBufferedStats = TotalLength(); + result += TO_STRING(Scroller(itsBufferedStats, w->GetWidth()-result.length()-volume_state.length(), itsScrollBegin)); return result; } @@ -266,14 +273,20 @@ std::string Playlist::TotalLength() { std::ostringstream result; - const int MINUTE = 60; - const int HOUR = 60*MINUTE; - const int DAY = 24*HOUR; - const int YEAR = 365*DAY; - int length = 0; - - for (size_t i = 0; i < w->Size(); i++) - length += w->at(i).GetTotalLength(); + if (ReloadTotalLength) + { + itsTotalLength = 0; + for (size_t i = 0; i < w->Size(); i++) + itsTotalLength += (*w)[i].GetTotalLength(); + ReloadTotalLength = 0; + } + if (Config.playlist_show_remaining_time && ReloadRemaining && !w->isFiltered()) + { + itsRemainingTime = 0; + for (size_t i = NowPlaying; i < w->Size(); i++) + itsRemainingTime += (*w)[i].GetTotalLength(); + ReloadRemaining = 0; + } result << '(' << w->Size() << (w->Size() == 1 ? " item" : " items"); @@ -286,48 +299,63 @@ std::string Playlist::TotalLength() result << " (out of " << Mpd->GetPlaylistLength() << ")"; } - if (length) + if (itsTotalLength) { result << ", length: "; - int years = length/YEAR; - if (years) - { - result << years << (years == 1 ? " year" : " years"); - length -= years*YEAR; - if (length) - result << ", "; - } - int days = length/DAY; - if (days) - { - result << days << (days == 1 ? " day" : " days"); - length -= days*DAY; - if (length) - result << ", "; - } - int hours = length/HOUR; - if (hours) - { - result << hours << (hours == 1 ? " hour" : " hours"); - length -= hours*HOUR; - if (length) - result << ", "; - } - int minutes = length/MINUTE; - if (minutes) - { - result << minutes << (minutes == 1 ? " minute" : " minutes"); - length -= minutes*MINUTE; - if (length) - result << ", "; - } - if (length) - result << length << (length == 1 ? " second" : " seconds"); + ShowTime(result, itsTotalLength); + } + if (Config.playlist_show_remaining_time && itsRemainingTime && !w->isFiltered() && w->Size() > 1) + { + result << " :: remaining: "; + ShowTime(result, itsRemainingTime); } result << ')'; return result.str(); } +void Playlist::ShowTime(std::ostringstream &result, size_t length) +{ + const int MINUTE = 60; + const int HOUR = 60*MINUTE; + const int DAY = 24*HOUR; + const int YEAR = 365*DAY; + + int years = length/YEAR; + if (years) + { + result << years << (years == 1 ? " year" : " years"); + length -= years*YEAR; + if (length) + result << ", "; + } + int days = length/DAY; + if (days) + { + result << days << (days == 1 ? " day" : " days"); + length -= days*DAY; + if (length) + result << ", "; + } + int hours = length/HOUR; + if (hours) + { + result << hours << (hours == 1 ? " hour" : " hours"); + length -= hours*HOUR; + if (length) + result << ", "; + } + int minutes = length/MINUTE; + if (minutes) + { + result << minutes << (minutes == 1 ? " minute" : " minutes"); + length -= minutes*MINUTE; + if (length) + result << ", "; + } + if (length) + result << length << (length == 1 ? " second" : " seconds"); +} + const MPD::Song *Playlist::NowPlayingSong() { bool was_filtered = w->isFiltered(); diff --git a/src/playlist.h b/src/playlist.h index 28a0fb99..7cadfe54 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -21,6 +21,8 @@ #ifndef _PLAYLIST_H #define _PLAYLIST_H +#include + #include "ncmpcpp.h" #include "screen.h" #include "song.h" @@ -28,7 +30,7 @@ class Playlist : public Screen< Menu > { public: - Playlist() : NowPlaying(-1), OldPlaying(-1) { } + Playlist() : NowPlaying(-1), OldPlaying(-1), itsTotalLength(0), itsRemainingTime(0), itsScrollBegin(0) { } ~Playlist() { } virtual void Init(); @@ -61,6 +63,9 @@ class Playlist : public Screen< Menu > int NowPlaying; int OldPlaying; + static bool ReloadTotalLength; + static bool ReloadRemaining; + static bool BlockNowPlayingUpdate; static bool BlockUpdate; static bool BlockRefreshing; @@ -68,6 +73,13 @@ class Playlist : public Screen< Menu > protected: std::string TotalLength(); + std::string itsBufferedStats; + + size_t itsTotalLength; + size_t itsRemainingTime; + size_t itsScrollBegin; + + static void ShowTime(std::ostringstream &, size_t); static bool Sorting(MPD::Song *a, MPD::Song *b); static Menu< std::pair > *SortDialog; diff --git a/src/settings.cpp b/src/settings.cpp index a430d067..76110b70 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -247,6 +247,7 @@ void DefaultConfiguration(ncmpcpp_config &conf) conf.media_lib_primary_tag = MPD_TAG_ITEM_ARTIST; conf.colors_enabled = true; conf.fancy_scrolling = true; + conf.playlist_show_remaining_time = false; conf.columns_in_playlist = false; conf.columns_in_browser = false; conf.columns_in_search_engine = false; @@ -564,6 +565,10 @@ void ReadConfiguration(ncmpcpp_config &conf) { conf.fancy_scrolling = v == "yes"; } + else if (cl.find("playlist_show_remaining_time") != string::npos) + { + conf.playlist_show_remaining_time = v == "yes"; + } else if (cl.find("playlist_display_mode") != string::npos) { conf.columns_in_playlist = v == "columns"; diff --git a/src/settings.h b/src/settings.h index b5916888..7a423213 100644 --- a/src/settings.h +++ b/src/settings.h @@ -138,6 +138,7 @@ struct ncmpcpp_config bool colors_enabled; bool fancy_scrolling; + bool playlist_show_remaining_time; bool columns_in_playlist; bool columns_in_browser; bool columns_in_search_engine; diff --git a/src/status.cpp b/src/status.cpp index 6753fe61..bcb58bea 100644 --- a/src/status.cpp +++ b/src/status.cpp @@ -231,6 +231,9 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *) FreeSongList(list); } + Playlist::ReloadTotalLength = 1; + Playlist::ReloadRemaining = 1; + if (myScreen == myPlaylist) redraw_header = 1; @@ -284,6 +287,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *) { player_state = "Playing: "; myPlaylist->Main()->BoldOption(myPlaylist->NowPlaying, 1); + Playlist::ReloadRemaining = 1; changed.ElapsedTime = 1; break; } @@ -303,6 +307,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *) myPlaylist->Main()->BoldOption(myPlaylist->OldPlaying, 0); } catch (std::out_of_range) { } + Playlist::ReloadRemaining = 1; myPlaylist->NowPlaying = -1; player_state.clear(); break; @@ -342,6 +347,8 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *) if (Config.now_playing_lyrics && !Config.repeat_one_mode && myScreen == myLyrics && myOldScreen == myPlaylist) Lyrics::Reload = 1; } + Playlist::ReloadRemaining = 1; + playing_song_scroll_begin = 0; if (Mpd->GetState() == psPlay)