Some UI scaffolding to support category filtering in browse view.

This commit is contained in:
casey langen 2022-07-02 13:42:31 -07:00
parent e7217ca7df
commit cd4bb0da3d
5 changed files with 59 additions and 4 deletions

View File

@ -129,6 +129,7 @@ BrowseLayout::~BrowseLayout() {
} }
void BrowseLayout::OnLayout() { void BrowseLayout::OnLayout() {
const bool showFilter = this->showCategoryListFilter;
const int cx = this->GetWidth(); const int cx = this->GetWidth();
const int x = 0; const int x = 0;
int cy = this->GetHeight(); int cy = this->GetHeight();
@ -136,7 +137,22 @@ void BrowseLayout::OnLayout() {
const int categoryWidth = std::min(kMaxCategoryWidth, cx / 4); const int categoryWidth = std::min(kMaxCategoryWidth, cx / 4);
this->categoryList->MoveAndResize(x, y, categoryWidth, cy); const int categoryListBottomMargin = showFilter ? 1 : 0;
this->categoryList->MoveAndResize(x, y, categoryWidth, cy - categoryListBottomMargin);
if (showFilter) {
bool refocusFilter = !this->categoryListFilter->IsVisible();
this->categoryListFilter->Show();
this->categoryListFilter->MoveAndResize(x + 1, cy - 1, categoryWidth - 2, 1);
if (refocusFilter) {
/* needs to be done during a subsequent tick in the event loop, as the
widget isn't yet visible so can't receive focus. */
this->Post(cube::message::FocusBrowseFilter);
}
}
else {
this->categoryListFilter->Hide();
}
if (this->playlistModified) { if (this->playlistModified) {
this->modifiedLabel->Show(); this->modifiedLabel->Show();
@ -151,7 +167,8 @@ void BrowseLayout::OnLayout() {
this->trackList->MoveAndResize(x + categoryWidth, y, cx - categoryWidth, cy); this->trackList->MoveAndResize(x + categoryWidth, y, cx - categoryWidth, cy);
this->categoryList->SetFocusOrder(0); this->categoryList->SetFocusOrder(0);
this->trackList->SetFocusOrder(1); this->categoryListFilter->SetFocusOrder(1);
this->trackList->SetFocusOrder(2);
} }
void BrowseLayout::InitializeWindows() { void BrowseLayout::InitializeWindows() {
@ -159,6 +176,9 @@ void BrowseLayout::InitializeWindows() {
this->categoryList->MouseEvent.connect(this, &BrowseLayout::OnWindowMouseEvent); this->categoryList->MouseEvent.connect(this, &BrowseLayout::OnWindowMouseEvent);
this->categoryList->SetFrameTitle(_TSTR(DEFAULT_CATEGORY_NAME)); this->categoryList->SetFrameTitle(_TSTR(DEFAULT_CATEGORY_NAME));
this->categoryListFilter = std::make_shared<TextInput>(TextInput::StyleLine);
this->categoryListFilter->SetHint("filter");
this->trackList = std::make_shared<TrackListView>(this->playback, this->library); this->trackList = std::make_shared<TrackListView>(this->playback, this->library);
this->trackList->MouseEvent.connect(this, &BrowseLayout::OnWindowMouseEvent); this->trackList->MouseEvent.connect(this, &BrowseLayout::OnWindowMouseEvent);
this->trackList->Requeried.connect(this, &BrowseLayout::OnRequeried); this->trackList->Requeried.connect(this, &BrowseLayout::OnRequeried);
@ -169,6 +189,7 @@ void BrowseLayout::InitializeWindows() {
this->modifiedLabel->Hide(); this->modifiedLabel->Hide();
this->AddWindow(this->categoryList); this->AddWindow(this->categoryList);
this->AddWindow(this->categoryListFilter);
this->AddWindow(this->trackList); this->AddWindow(this->trackList);
this->AddWindow(this->modifiedLabel); this->AddWindow(this->modifiedLabel);
@ -225,6 +246,11 @@ void BrowseLayout::ProcessMessage(musik::core::runtime::IMessage &message) {
break; break;
} }
case cube::message::FocusBrowseFilter: {
this->SetFocus(this->categoryListFilter);
break;
}
default: default:
break; break;
} }
@ -332,7 +358,16 @@ void BrowseLayout::ShowTrackSortOverlay() {
} }
bool BrowseLayout::KeyPress(const std::string& key) { bool BrowseLayout::KeyPress(const std::string& key) {
if (key == "KEY_ENTER") { if (key == "^[" && this->showCategoryListFilter) {
if (this->GetFocus() == this->categoryList ||
this->GetFocus() == this->categoryListFilter)
{
this->showCategoryListFilter = false;
this->Layout();
return true;
}
}
else if (key == "KEY_ENTER") {
/* if the tracklist is NOT focused (i.e. the focus is on a /* if the tracklist is NOT focused (i.e. the focus is on a
category window), start playback from the top. */ category window), start playback from the top. */
if (this->GetFocus() != this->trackList) { if (this->GetFocus() != this->trackList) {
@ -343,6 +378,15 @@ bool BrowseLayout::KeyPress(const std::string& key) {
} }
} }
} }
else if (Hotkeys::Is(Hotkeys::BrowseCategoryFilter, key)) {
if (this->GetFocus() == this->categoryList ||
this->GetFocus() == this->categoryListFilter)
{
this->showCategoryListFilter = !this->showCategoryListFilter;
this->Layout();
return true;
}
}
else if (Hotkeys::Is(Hotkeys::TrackListChangeSortOrder, key)) { else if (Hotkeys::Is(Hotkeys::TrackListChangeSortOrder, key)) {
this->ShowTrackSortOverlay(); this->ShowTrackSortOverlay();
return true; return true;

View File

@ -36,6 +36,7 @@
#include <cursespp/LayoutBase.h> #include <cursespp/LayoutBase.h>
#include <cursespp/TextLabel.h> #include <cursespp/TextLabel.h>
#include <cursespp/TextInput.h>
#include <app/window/CategoryListView.h> #include <app/window/CategoryListView.h>
#include <app/window/TrackListView.h> #include <app/window/TrackListView.h>
@ -104,11 +105,13 @@ namespace musik {
void ShowModifiedLabel(bool show); void ShowModifiedLabel(bool show);
void ShowTrackSortOverlay(); void ShowTrackSortOverlay();
bool playlistModified; bool playlistModified{ false };
bool showCategoryListFilter{ false };
musik::core::audio::PlaybackService& playback; musik::core::audio::PlaybackService& playback;
musik::core::ILibraryPtr library; musik::core::ILibraryPtr library;
std::shared_ptr<musik::core::Preferences> prefs; std::shared_ptr<musik::core::Preferences> prefs;
std::shared_ptr<CategoryListView> categoryList; std::shared_ptr<CategoryListView> categoryList;
std::shared_ptr<cursespp::TextInput> categoryListFilter;
std::shared_ptr<TrackListView> trackList; std::shared_ptr<TrackListView> trackList;
std::shared_ptr<cursespp::TextLabel> modifiedLabel; std::shared_ptr<cursespp::TextLabel> modifiedLabel;
HeaderClickHandler categoryListHeaderClickHandler; HeaderClickHandler categoryListHeaderClickHandler;

View File

@ -96,6 +96,8 @@ static std::unordered_map<std::string, Id> NAME_TO_ID = {
{ "play_queue_hot_swap", Id::PlayQueueHotSwap }, { "play_queue_hot_swap", Id::PlayQueueHotSwap },
{ "play_queue_clear", Id::PlayQueueClear }, { "play_queue_clear", Id::PlayQueueClear },
{ "browse_category_filter", Id::BrowseCategoryFilter },
{ "browse_playlists_new", Id::BrowsePlaylistsNew }, { "browse_playlists_new", Id::BrowsePlaylistsNew },
{ "browse_playlists_save", Id::BrowsePlaylistsSave }, { "browse_playlists_save", Id::BrowsePlaylistsSave },
{ "browse_playlists_rename", Id::BrowsePlaylistsRename }, { "browse_playlists_rename", Id::BrowsePlaylistsRename },
@ -187,6 +189,8 @@ static std::unordered_map<Id, std::string, EnumHasher> ID_TO_DEFAULT = {
{ Id::PlayQueueHotSwap, "M-a" }, { Id::PlayQueueHotSwap, "M-a" },
{ Id::PlayQueueClear, "X" }, { Id::PlayQueueClear, "X" },
{ Id::BrowseCategoryFilter, "M-f" },
{ Id::BrowsePlaylistsSave, "M-s" }, { Id::BrowsePlaylistsSave, "M-s" },
{ Id::BrowsePlaylistsNew, "M-n" }, { Id::BrowsePlaylistsNew, "M-n" },
{ Id::BrowsePlaylistsRename, "M-r" }, { Id::BrowsePlaylistsRename, "M-r" },

View File

@ -103,6 +103,9 @@ namespace musik {
PlayQueueHotSwap, PlayQueueHotSwap,
PlayQueueClear, PlayQueueClear,
/* browse */
BrowseCategoryFilter,
/* browse -> playlists */ /* browse -> playlists */
BrowsePlaylistsNew, BrowsePlaylistsNew,
BrowsePlaylistsSave, BrowsePlaylistsSave,

View File

@ -69,6 +69,7 @@ namespace musik {
static const int UpdateEqualizer = First + 18; static const int UpdateEqualizer = First + 18;
static const int DebugLog = First + 19; static const int DebugLog = First + 19;
static const int LyricsLoaded = First + 20; static const int LyricsLoaded = First + 20;
static const int FocusBrowseFilter = First + 21;
} }
} }