diff --git a/src/musikbox/app/layout/BrowseLayout.cpp b/src/musikbox/app/layout/BrowseLayout.cpp index c2217a192..b9982be5e 100755 --- a/src/musikbox/app/layout/BrowseLayout.cpp +++ b/src/musikbox/app/layout/BrowseLayout.cpp @@ -101,7 +101,7 @@ void BrowseLayout::InitializeWindows() { } void BrowseLayout::ScrollTo(const std::string& fieldType, DBID fieldId) { - this->categoryList->SetFieldName(fieldType); + this->categoryList->RequeryWithField(fieldType, "", fieldId); } IWindowPtr BrowseLayout::GetFocus() { diff --git a/src/musikbox/app/layout/SearchLayout.cpp b/src/musikbox/app/layout/SearchLayout.cpp index 53df7f359..a9fbe9376 100755 --- a/src/musikbox/app/layout/SearchLayout.cpp +++ b/src/musikbox/app/layout/SearchLayout.cpp @@ -113,6 +113,20 @@ void SearchLayout::OnInputChanged(cursespp::TextInput* sender, std::string value void SearchLayout::OnVisibilityChanged(bool visible) { LayoutBase::OnVisibilityChanged(visible); + + if (visible) { + if (this->input->Length()) { + /* clear, which will trigger a requery */ + this->input->SetText(""); + } + + this->SetFocus(this->input); + } + else { + this->albums->Reset(); + this->artists->Reset(); + this->genres->Reset(); + } } bool SearchLayout::KeyPress(const std::string& key) { diff --git a/src/musikbox/app/query/CategoryListViewQuery.cpp b/src/musikbox/app/query/CategoryListViewQuery.cpp index cb5b5841f..b70e16169 100755 --- a/src/musikbox/app/query/CategoryListViewQuery.cpp +++ b/src/musikbox/app/query/CategoryListViewQuery.cpp @@ -128,6 +128,16 @@ CategoryListViewQuery::ResultList CategoryListViewQuery::GetResult() { return this->result; } +int CategoryListViewQuery::GetIndexOf(DBID id) { + auto result = this->GetResult(); + for (size_t i = 0; i < result->size(); i++) { + if (id == (*result)[i]->id) { + return i; + } + } + return -1; +} + bool CategoryListViewQuery::OnRun(Connection& db) { RESET_RESULT(result); diff --git a/src/musikbox/app/query/CategoryListViewQuery.h b/src/musikbox/app/query/CategoryListViewQuery.h index 26495e935..bd8c4e8a3 100755 --- a/src/musikbox/app/query/CategoryListViewQuery.h +++ b/src/musikbox/app/query/CategoryListViewQuery.h @@ -59,6 +59,7 @@ namespace musik { std::string Name() { return "CategoryListViewQuery"; } virtual ResultList GetResult(); + virtual int GetIndexOf(DBID id); protected: virtual bool OnRun(musik::core::db::Connection &db); diff --git a/src/musikbox/app/window/CategoryListView.cpp b/src/musikbox/app/window/CategoryListView.cpp index bd47bc160..cadb979d5 100755 --- a/src/musikbox/app/window/CategoryListView.cpp +++ b/src/musikbox/app/window/CategoryListView.cpp @@ -57,6 +57,7 @@ using cursespp::SingleLineEntry; CategoryListView::CategoryListView(LibraryPtr library, const std::string& fieldName) : ListWindow(NULL) { this->SetContentColor(BOX_COLOR_WHITE_ON_BLACK); + this->selectAfterQuery = 0; this->library = library; this->library->QueryCompleted.connect(this, &CategoryListView::OnQueryCompleted); this->fieldName = fieldName; @@ -67,15 +68,30 @@ CategoryListView::~CategoryListView() { delete adapter; } -void CategoryListView::Requery(const std::string& filter) { +void CategoryListView::RequeryWithField( + const std::string& fieldName, + const std::string& filter, + const DBID selectAfterQuery) +{ if (this->activeQuery) { this->activeQuery->Cancel(); } + this->fieldName = fieldName; + this->selectAfterQuery = selectAfterQuery; this->activeQuery.reset(new CategoryListViewQuery(this->fieldName, filter)); this->library->Enqueue(activeQuery); } +void CategoryListView::Requery(const std::string& filter, const DBID selectAfterQuery) { + this->RequeryWithField(this->fieldName, filter, selectAfterQuery); +} + +void CategoryListView::Reset() { + this->metadata.reset(new std::vector >()); /* ugh */ + this->OnAdapterChanged(); +} + DBID CategoryListView::GetSelectedId() { size_t index = this->GetSelectedIndex(); if (index != NO_SELECTION && this->metadata && index < this->metadata->size()) { @@ -102,7 +118,12 @@ void CategoryListView::SetFieldName(const std::string& fieldName) { void CategoryListView::OnQueryCompleted(IQueryPtr query) { if (query == this->activeQuery) { - this->PostMessage(WINDOW_MESSAGE_QUERY_COMPLETED); + int selectIndex = -1; + if (this->selectAfterQuery != 0) { + selectIndex = this->activeQuery->GetIndexOf(this->selectAfterQuery); + } + + this->PostMessage(WINDOW_MESSAGE_QUERY_COMPLETED, selectIndex); } } @@ -111,6 +132,14 @@ void CategoryListView::ProcessMessage(IMessage &message) { if (this->activeQuery && this->activeQuery->GetStatus() == IQuery::Finished) { this->metadata = activeQuery->GetResult(); activeQuery.reset(); + + /* UserData1 will be the index of the item we should select. if + the value is -1, we won't go out of our way to select anything. */ + if (message.UserData1() > 0) { + this->SetSelectedIndex((int) message.UserData1()); + this->ScrollTo((int) message.UserData1()); + } + this->OnAdapterChanged(); this->OnInvalidated(); } diff --git a/src/musikbox/app/window/CategoryListView.h b/src/musikbox/app/window/CategoryListView.h index 6598d54cd..0d8f5924b 100755 --- a/src/musikbox/app/window/CategoryListView.h +++ b/src/musikbox/app/window/CategoryListView.h @@ -65,7 +65,16 @@ namespace musik { CategoryListView(LibraryPtr library, const std::string& fieldName); virtual ~CategoryListView(); - void Requery(const std::string& filter = ""); + void RequeryWithField( + const std::string& fieldName, + const std::string& filter = "", + const DBID selectAfterQuery = 0); + + void Requery( + const std::string& filter = "", + const DBID selectAfterQuery = 0); + + void Reset(); virtual void ProcessMessage(IMessage &message); @@ -92,6 +101,7 @@ namespace musik { private: LibraryPtr library; Adapter *adapter; + DBID selectAfterQuery; std::string fieldName; std::shared_ptr activeQuery; diff --git a/src/musikbox/cursespp/LayoutBase.cpp b/src/musikbox/cursespp/LayoutBase.cpp index 7e67d31cc..22de1cc79 100755 --- a/src/musikbox/cursespp/LayoutBase.cpp +++ b/src/musikbox/cursespp/LayoutBase.cpp @@ -225,6 +225,17 @@ IWindowPtr LayoutBase::GetWindowAt(size_t position) { return this->children.at(position); } +bool LayoutBase::SetFocus(IWindowPtr focus) { + for (size_t i = 0; i < this->focusable.size(); i++) { + if (this->focusable[i] == focus) { + adjustFocus(GetFocus(), focus); + this->focused = i; + return true; + } + } + return false; +} + IWindowPtr LayoutBase::FocusNext() { IWindowPtr oldFocus = GetFocus(); if (++this->focused >= (int) this->focusable.size()) { diff --git a/src/musikbox/cursespp/LayoutBase.h b/src/musikbox/cursespp/LayoutBase.h index cfdd2e50b..eca69f46d 100755 --- a/src/musikbox/cursespp/LayoutBase.h +++ b/src/musikbox/cursespp/LayoutBase.h @@ -73,6 +73,9 @@ namespace cursespp { virtual size_t GetWindowCount(); virtual IWindowPtr GetWindowAt(size_t position); + protected: + bool SetFocus(IWindowPtr window); + private: void AddFocusable(IWindowPtr window); void RemoveFocusable(IWindowPtr window); diff --git a/src/musikbox/cursespp/TextInput.cpp b/src/musikbox/cursespp/TextInput.cpp index 9b3f91d9b..8b56c9cb8 100755 --- a/src/musikbox/cursespp/TextInput.cpp +++ b/src/musikbox/cursespp/TextInput.cpp @@ -62,7 +62,8 @@ inline static void removeUtf8Char(std::string& value) { } TextInput::TextInput() -: Window() { +: Window() +, bufferLength(0) { } TextInput::~TextInput() {