diff --git a/NEWS b/NEWS index 340bacf4..0a644fe5 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,7 @@ ncmpcpp-0.8 (????-??-??) * Wide character version of ncurses is now required. * Added 'statusbar_time_color' and 'player_state_color' configuration variables for further customization of statusbar. * Format information can now be attached to selected color variables in the configuration file. Because of that variable 'progressbar_boldness' is now deprecated in favor of extended 'progressbar_color' and 'progressbar_elapsed_color' (for more information see example configuration file). +* Lyrics and last_fm can now be startup screens and are lockable. ncmpcpp-0.7.7 (2016-10-31) * Fixed compilation on 32bit platforms. diff --git a/doc/config b/doc/config index 6575fcab..90e5ac1a 100644 --- a/doc/config +++ b/doc/config @@ -392,8 +392,9 @@ ## - "previous" - switch between the current and previous screen. ## - "screen1,...,screenN" - switch between given sequence of screens. ## -## Screens available for use: help, playlist, browser, search_engine, -## media_library, playlist_editor, tag_editor, outputs, visualizer, clock. +## Screens available for use: help, playlist, browser, +## search_engine, media_library, playlist_editor, tag_editor, +## outputs, visualizer, clock, lyrics, last_fm. ## #screen_switcher_mode = playlist, browser # diff --git a/src/actions.cpp b/src/actions.cpp index eb91709f..cf866295 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -97,6 +97,22 @@ bool findSelectedRangeAndPrintInfoIfNot(Iterator &first, Iterator &last) return success; } +template +Iterator nextScreenTypeInSequence(Iterator first, Iterator last, ScreenType type) +{ + auto it = std::find(first, last, type); + if (it == last) + return first; + else + { + ++it; + if (it == last) + return first; + else + return it; + } +} + } namespace Actions { @@ -2393,7 +2409,8 @@ void ShowArtistInfo::run() if (!artist.empty()) { myLastfm->queueJob(new LastFm::ArtistInfo(artist, Config.lastfm_preferred_language)); - myLastfm->switchTo(); + if (!isVisible(myLastfm)) + myLastfm->switchTo(); } } @@ -2415,7 +2432,8 @@ void ShowLyrics::run() { if (m_song != nullptr) myLyrics->fetch(*m_song); - myLyrics->switchTo(); + if (myScreen == myLyrics || !isVisible(myLyrics)) + myLyrics->switchTo(); } void Quit::run() @@ -2432,12 +2450,11 @@ void NextScreen::run() } else if (!Config.screen_sequence.empty()) { - const auto &seq = Config.screen_sequence; - auto screen_type = std::find(seq.begin(), seq.end(), myScreen->type()); - if (++screen_type == seq.end()) - toScreen(seq.front())->switchTo(); - else - toScreen(*screen_type)->switchTo(); + auto screen = nextScreenTypeInSequence( + Config.screen_sequence.begin(), + Config.screen_sequence.end(), + myScreen->type()); + toScreen(*screen)->switchTo(); } } @@ -2450,12 +2467,11 @@ void PreviousScreen::run() } else if (!Config.screen_sequence.empty()) { - const auto &seq = Config.screen_sequence; - auto screen_type = std::find(seq.begin(), seq.end(), myScreen->type()); - if (screen_type == seq.begin()) - toScreen(seq.back())->switchTo(); - else - toScreen(*--screen_type)->switchTo(); + auto screen = nextScreenTypeInSequence( + Config.screen_sequence.rbegin(), + Config.screen_sequence.rend(), + myScreen->type()); + toScreen(*screen)->switchTo(); } } diff --git a/src/lastfm_service.h b/src/lastfm_service.h index 31d40a9b..a886ba5a 100644 --- a/src/lastfm_service.h +++ b/src/lastfm_service.h @@ -36,7 +36,7 @@ struct Service typedef std::pair Result; Service(Arguments args) : m_arguments(args) { } - + virtual const char *name() = 0; virtual Result fetch(); diff --git a/src/screens/lastfm.cpp b/src/screens/lastfm.cpp index 6d7464a9..fd138213 100644 --- a/src/screens/lastfm.cpp +++ b/src/screens/lastfm.cpp @@ -33,7 +33,8 @@ using Global::MainStartY; Lastfm *myLastfm; Lastfm::Lastfm() -: Screen(NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::Border())) + : Screen(NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::Border())) + , m_refresh_window(false) { } void Lastfm::resize() @@ -47,13 +48,36 @@ void Lastfm::resize() std::wstring Lastfm::title() { - return m_title; + if (m_title.empty()) + return L"Last.fm"; + else + return m_title; } void Lastfm::update() { if (m_worker.valid() && m_worker.is_ready()) - getResult(); + { + auto result = m_worker.get(); + if (result.first) + { + w.clear(); + w << Charset::utf8ToLocale(result.second); + m_service->beautifyOutput(w); + } + else + w << " " << NC::Color::Red << result.second << NC::Color::End; + // reset m_worker so it's no longer valid + m_worker = boost::BOOST_THREAD_FUTURE(); + m_refresh_window = true; + } + + if (m_refresh_window) + { + m_refresh_window = false; + w.flush(); + w.refresh(); + } } void Lastfm::switchTo() @@ -67,20 +91,3 @@ void Lastfm::switchTo() else switchToPreviousScreen(); } - -void Lastfm::getResult() -{ - auto result = m_worker.get(); - if (result.first) - { - w.clear(); - w << Charset::utf8ToLocale(result.second); - m_service->beautifyOutput(w); - } - else - w << " " << NC::Color::Red << result.second << NC::Color::End; - w.flush(); - w.refresh(); - // reset m_worker so it's no longer valid - m_worker = boost::BOOST_THREAD_FUTURE(); -} diff --git a/src/screens/lastfm.h b/src/screens/lastfm.h index f810e5dc..32e36ea3 100644 --- a/src/screens/lastfm.h +++ b/src/screens/lastfm.h @@ -43,7 +43,7 @@ struct Lastfm: Screen, Tabbable virtual void update() override; - virtual bool isLockable() override { return false; } + virtual bool isLockable() override { return true; } virtual bool isMergable() override { return true; } template @@ -61,14 +61,13 @@ struct Lastfm: Screen, Tabbable w.clear(); w << "Fetching information..."; - w.flush(); + m_refresh_window = true; m_title = ToWString(m_service->name()); } private: - void getResult(); - std::wstring m_title; + bool m_refresh_window; std::shared_ptr m_service; boost::BOOST_THREAD_FUTURE m_worker; diff --git a/src/screens/lyrics.cpp b/src/screens/lyrics.cpp index a96d81db..7c98439b 100644 --- a/src/screens/lyrics.cpp +++ b/src/screens/lyrics.cpp @@ -259,13 +259,17 @@ void Lyrics::switchTo() std::wstring Lyrics::title() { - std::wstring result = L"Lyrics: "; - result += Scroller( - Format::stringify(Format::parse(L"{%a - %t}|{%f}"), &m_song), - m_scroll_begin, - COLS - result.length() - (Config.design == Design::Alternative - ? 2 - : Global::VolumeState.length())); + std::wstring result = L"Lyrics"; + if (!m_song.empty()) + { + result += L": "; + result += Scroller( + Format::stringify(Format::parse(L"{%a - %t}|{%f}"), &m_song), + m_scroll_begin, + COLS - result.length() - (Config.design == Design::Alternative + ? 2 + : Global::VolumeState.length())); + } return result; } diff --git a/src/screens/lyrics.h b/src/screens/lyrics.h index 4901d8a0..f94c7b7f 100644 --- a/src/screens/lyrics.h +++ b/src/screens/lyrics.h @@ -46,7 +46,7 @@ struct Lyrics: Screen, Tabbable virtual void update() override; - virtual bool isLockable() override { return false; } + virtual bool isLockable() override { return true; } virtual bool isMergable() override { return true; } // other members diff --git a/src/screens/screen_type.cpp b/src/screens/screen_type.cpp index 1d5cae3a..eec2acec 100644 --- a/src/screens/screen_type.cpp +++ b/src/screens/screen_type.cpp @@ -123,6 +123,10 @@ ScreenType stringtoStartupScreenType(const std::string &s) else if (s == "visualizer") result = ScreenType::Visualizer; # endif // ENABLE_VISUALIZER + else if (s == "lyrics") + result = ScreenType::Lyrics; + else if (s == "last_fm") + result = ScreenType::Lastfm; return result; }