diff --git a/src/musikcube/app/layout/MainLayout.cpp b/src/musikcube/app/layout/MainLayout.cpp index 4f79f09d0..841a586c2 100755 --- a/src/musikcube/app/layout/MainLayout.cpp +++ b/src/musikcube/app/layout/MainLayout.cpp @@ -47,6 +47,7 @@ #include <app/layout/ConsoleLayout.h> #include <app/layout/LyricsLayout.h> #include <app/layout/LibraryLayout.h> +#include <app/layout/LibraryNotConnectedLayout.h> #include <app/layout/SettingsLayout.h> #include <app/layout/HotkeysLayout.h> #include <app/util/Hotkeys.h> @@ -91,15 +92,19 @@ MainLayout::MainLayout( : shortcutsFocused(false) , syncUpdateCount(0) , library(library) +, playback(playback) , AppLayout(app) { this->prefs = Preferences::ForComponent("settings"); + library->ConnectionStateChanged.connect(this, &MainLayout::OnLibraryConnectionStateChanged); library->Indexer()->Started.connect(this, &MainLayout::OnIndexerStarted); library->Indexer()->Finished.connect(this, &MainLayout::OnIndexerFinished); library->Indexer()->Progress.connect(this, &MainLayout::OnIndexerProgress); playback.TrackChanged.connect(this, &MainLayout::OnTrackChanged); - this->libraryLayout = std::make_shared<LibraryLayout>(playback, library); + /* note we don't create `libraryLayout` here; instead we do it lazily once we're sure + it has been connected. see SwitchToLibraryLayout() */ + this->libraryNotConnectedLayout = std::make_shared<LibraryNotConnectedLayout>(library); this->lyricsLayout = std::make_shared<LyricsLayout>(playback, library); this->consoleLayout = std::make_shared<ConsoleLayout>(logger); this->settingsLayout = std::make_shared<SettingsLayout>(app, library, playback); @@ -112,7 +117,7 @@ MainLayout::MainLayout( /* take user to settings if they don't have a valid configuration. otherwise, switch to the library view immediately */ - this->SetLayout(library->IsConfigured() ? libraryLayout : settingsLayout); + this->SetInitialLayout(); this->SetAutoHideCommandBar(this->prefs->GetBool(prefs::keys::AutoHideCommandBar, false)); this->RunUpdateCheck(); @@ -195,12 +200,10 @@ void MainLayout::ProcessMessage(musik::core::runtime::IMessage &message) { this->SetLayout(hotkeysLayout); } else if (type == message::JumpToLibrary) { - this->SetLayout(libraryLayout); + this->SwitchToLibraryLayout(); } else if (type == message::JumpToPlayQueue) { - this->SetLayout(libraryLayout); - libraryLayout->KeyPress(Hotkeys::Get( - Hotkeys::NavigateLibraryPlayQueue)); + this->SwitchToPlayQueue(); } else if (type == message::IndexerStarted) { this->syncUpdateCount = 0; @@ -219,6 +222,51 @@ void MainLayout::ProcessMessage(musik::core::runtime::IMessage &message) { } } +bool MainLayout::IsLibraryConnected() { + using State = ILibrary::ConnectionState; + auto state = library->GetConnectionState(); + return state == State::Connected || state == State::NotApplicable; +} + +void MainLayout::SetInitialLayout() { + if (library->IsConfigured()) { + this->SwitchToLibraryLayout(); + } + else { + this->SetLayout(settingsLayout); + } +} + +void MainLayout::SwitchToPlayQueue() { + if (IsLibraryConnected()) { + this->SetLayout(libraryLayout); + libraryLayout->KeyPress(Hotkeys::Get(Hotkeys::NavigateLibraryPlayQueue)); + } +} + +void MainLayout::SwitchToLibraryLayout() { + if (IsLibraryConnected()) { + if (!this->libraryLayout) { + this->libraryLayout.reset(new LibraryLayout(playback, library)); + } + this->SetLayout(libraryLayout); + } + else { + this->libraryLayout.reset(); + this->SetLayout(this->libraryNotConnectedLayout); + } +} + +void MainLayout::OnLibraryConnectionStateChanged(ILibrary::ConnectionState state) { + auto currentLayout = this->GetLayout(); + + if (currentLayout == this->libraryLayout || + currentLayout == this->libraryNotConnectedLayout) + { + this->SwitchToLibraryLayout(); + } +} + void MainLayout::OnIndexerStarted() { this->Post(message::IndexerStarted); } diff --git a/src/musikcube/app/layout/MainLayout.h b/src/musikcube/app/layout/MainLayout.h index 38992245a..8b20618e7 100755 --- a/src/musikcube/app/layout/MainLayout.h +++ b/src/musikcube/app/layout/MainLayout.h @@ -74,17 +74,24 @@ namespace musik { void OnIndexerProgress(int count); void OnIndexerFinished(int count); void OnTrackChanged(size_t index, musik::core::TrackPtr track); + void OnLibraryConnectionStateChanged(musik::core::ILibrary::ConnectionState state); + + bool IsLibraryConnected(); - void Initialize(); void RunUpdateCheck(); + void SetInitialLayout(); + void SwitchToLibraryLayout(); + void SwitchToPlayQueue(); std::shared_ptr<musik::core::Preferences> prefs; std::shared_ptr<cursespp::TextLabel> syncing; std::shared_ptr<cursespp::LayoutBase> consoleLayout; std::shared_ptr<cursespp::LayoutBase> libraryLayout; + std::shared_ptr<cursespp::LayoutBase> libraryNotConnectedLayout; std::shared_ptr<cursespp::LayoutBase> settingsLayout; std::shared_ptr<cursespp::LayoutBase> hotkeysLayout; std::shared_ptr<cursespp::LayoutBase> lyricsLayout; + musik::core::audio::PlaybackService& playback; musik::core::ILibraryPtr library; bool shortcutsFocused; int syncUpdateCount; diff --git a/src/musikcube/cursespp/App.cpp b/src/musikcube/cursespp/App.cpp index 9ba87c5b9..a2c984ff7 100755 --- a/src/musikcube/cursespp/App.cpp +++ b/src/musikcube/cursespp/App.cpp @@ -405,7 +405,7 @@ void App::Run(ILayoutPtr layout) { timeout(IDLE_TIMEOUT_MS); - if (this->state.input) { + if (this->state.input && this->state.focused->GetContent()) { /* if the focused window is an input, allow it to draw a cursor */ WINDOW *c = this->state.focused->GetContent(); keypad(c, TRUE); diff --git a/src/musikcube/cursespp/Window.cpp b/src/musikcube/cursespp/Window.cpp index a1f7be0d3..6ede17ff0 100755 --- a/src/musikcube/cursespp/Window.cpp +++ b/src/musikcube/cursespp/Window.cpp @@ -75,16 +75,15 @@ mention wbkgd() was changed, but it's unclear what exactly happened... */ static inline void DrawCursor(IInput* input) { if (input) { Window* inputWindow = dynamic_cast<Window*>(input); - if (inputWindow) { + if (inputWindow && inputWindow->GetContent()) { WINDOW* content = inputWindow->GetContent(); curs_set(1); wtimeout(content, IDLE_TIMEOUT_MS); wmove(content, 0, input->Position()); + return; } } - else { - curs_set(0); - } + curs_set(0); } static inline void DrawTooSmall() { diff --git a/src/musikcube/cursespp/cursespp/AppLayout.h b/src/musikcube/cursespp/cursespp/AppLayout.h index cab26cf13..2caf80e93 100644 --- a/src/musikcube/cursespp/cursespp/AppLayout.h +++ b/src/musikcube/cursespp/cursespp/AppLayout.h @@ -60,6 +60,7 @@ namespace cursespp { virtual cursespp::IWindowPtr FocusPrev() override; void SetLayout(std::shared_ptr<cursespp::LayoutBase> layout); + std::shared_ptr<cursespp::LayoutBase> GetLayout() { return this->layout; } void SetAutoHideCommandBar(bool autoHide); bool GetAutoHideCommandBar();