mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-29 19:20:28 +00:00
Added the ability to view extended metadata by category in the browse
view -- default keyboard shortcut is "6", and will show a dialog to let the user select which field to browse by.
This commit is contained in:
parent
4523c2d28a
commit
2f1c4ebe04
@ -61,10 +61,10 @@ bool AllCategoriesQuery::OnRun(Connection& db) {
|
||||
this->result.reset(new SdkValueList());
|
||||
Statement stmt("SELECT DISTINCT name FROM meta_keys ORDER BY name", db);
|
||||
|
||||
this->result->Add(std::make_shared<SdkValue>("albums", 0, "category"));
|
||||
this->result->Add(std::make_shared<SdkValue>("artists", 0, "category"));
|
||||
this->result->Add(std::make_shared<SdkValue>("album_artists", 0, "category"));
|
||||
this->result->Add(std::make_shared<SdkValue>("genres", 0, "category"));
|
||||
this->result->Add(std::make_shared<SdkValue>("album", 0, "category"));
|
||||
this->result->Add(std::make_shared<SdkValue>("artist", 0, "category"));
|
||||
this->result->Add(std::make_shared<SdkValue>("album_artist", 0, "category"));
|
||||
this->result->Add(std::make_shared<SdkValue>("genre", 0, "category"));
|
||||
|
||||
while (stmt.Step() == db::Row) {
|
||||
this->result->Add(std::make_shared<SdkValue>(
|
||||
|
@ -133,6 +133,32 @@ namespace musik { namespace core { namespace db { namespace local {
|
||||
std::sort(values->begin(), values->end(), compare);
|
||||
}
|
||||
|
||||
Shared Filter(std::function<bool(const SdkValue::Shared&)> keep) {
|
||||
Shared result = std::make_shared<SdkValueList>();
|
||||
for (size_t i = 0; i < values->size(); i++) {
|
||||
SdkValue::Shared value = values->at(i);
|
||||
if (keep(value)) {
|
||||
result->Add(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> Map(std::function<T(const SdkValue::Shared&)> fun) {
|
||||
std::vector<T> result;
|
||||
for (size_t i = 0; i < values->size(); i++) {
|
||||
result.push_back(fun(values->at(i)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Each(std::function<void(const SdkValue::Shared&)> fun) {
|
||||
for (size_t i = 0; i < values->size(); i++) {
|
||||
fun(values->at(i));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SharedValueList values;
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ set (CUBE_SRCS
|
||||
./app/layout/SearchLayout.cpp
|
||||
./app/layout/TrackSearchLayout.cpp
|
||||
./app/model/DirectoryAdapter.cpp
|
||||
./app/overlay/BrowseOverlays.cpp
|
||||
./app/overlay/ColorThemeOverlay.cpp
|
||||
./app/overlay/LocaleOverlay.cpp
|
||||
./app/overlay/PlaybackOverlays.cpp
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <app/util/Playback.h>
|
||||
#include <app/util/Messages.h>
|
||||
#include <app/overlay/PlayQueueOverlays.h>
|
||||
#include <app/overlay/BrowseOverlays.h>
|
||||
|
||||
#include "BrowseLayout.h"
|
||||
|
||||
@ -282,6 +283,14 @@ bool BrowseLayout::KeyPress(const std::string& key) {
|
||||
this->SwitchCategory(constants::Playlists::TABLE_NAME);
|
||||
return true;
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::NavigateLibraryBrowseChooseCategory, key)) {
|
||||
BrowseOverlays::ShowCategoryChooser(
|
||||
this->library,
|
||||
[this](std::string category) {
|
||||
this->SwitchCategory(category);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
else if (ProcessPlaylistOperation(key)) {
|
||||
return true;
|
||||
}
|
||||
|
95
src/musikcube/app/overlay/BrowseOverlays.cpp
Normal file
95
src/musikcube/app/overlay/BrowseOverlays.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2017 musikcube team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "BrowseOverlays.h"
|
||||
#include <core/library/query/local/AllCategoriesQuery.h>
|
||||
#include <cursespp/SimpleScrollAdapter.h>
|
||||
#include <cursespp/ListOverlay.h>
|
||||
#include <cursespp/DialogOverlay.h>
|
||||
#include <cursespp/App.h>
|
||||
#include <set>
|
||||
|
||||
using namespace cursespp;
|
||||
using namespace musik::cube;
|
||||
using namespace musik::core;
|
||||
using namespace musik::core::db;
|
||||
using namespace musik::core::db::local;
|
||||
|
||||
static std::set<std::string> BLACKLIST = { "bitrate", "channels", "lyrics", "path_id" };
|
||||
static std::string LAST_SELECTED;
|
||||
|
||||
void BrowseOverlays::ShowCategoryChooser(
|
||||
musik::core::ILibraryPtr library,
|
||||
std::function<void(std::string)> callback)
|
||||
{
|
||||
using Adapter = cursespp::SimpleScrollAdapter;
|
||||
using ListOverlay = cursespp::ListOverlay;
|
||||
using Value = SdkValue::Shared;
|
||||
|
||||
auto query = std::make_shared<AllCategoriesQuery>();
|
||||
library->Enqueue(query, ILibrary::QuerySynchronous);
|
||||
|
||||
std::shared_ptr<Adapter> adapter(new Adapter());
|
||||
adapter->SetSelectable(true);
|
||||
|
||||
size_t index = 0;
|
||||
auto filtered = query->GetResult()->Filter([&index, adapter](const Value& value) -> bool {
|
||||
auto str = value->ToString();
|
||||
if (BLACKLIST.find(str) == BLACKLIST.end()) {
|
||||
adapter->AddEntry(str);
|
||||
if (LAST_SELECTED == str) {
|
||||
index = adapter->GetEntryCount() - 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
std::shared_ptr<ListOverlay> dialog(new ListOverlay());
|
||||
|
||||
dialog->SetAdapter(adapter)
|
||||
.SetTitle(_TSTR("browse_categories_title"))
|
||||
.SetWidth(_DIMEN("browse_categories_overlay", 35))
|
||||
.SetSelectedIndex(index)
|
||||
.SetItemSelectedCallback(
|
||||
[callback, filtered]
|
||||
(ListOverlay* overlay, IScrollAdapterPtr adapter, size_t index) {
|
||||
LAST_SELECTED = filtered->At(index)->ToString();
|
||||
callback(LAST_SELECTED);
|
||||
});
|
||||
|
||||
cursespp::App::Overlays().Push(dialog);
|
||||
}
|
49
src/musikcube/app/overlay/BrowseOverlays.h
Normal file
49
src/musikcube/app/overlay/BrowseOverlays.h
Normal file
@ -0,0 +1,49 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2017 musikcube team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/library/ILibrary.h>
|
||||
#include <functional>
|
||||
|
||||
namespace musik {
|
||||
namespace cube {
|
||||
class BrowseOverlays {
|
||||
public:
|
||||
static void ShowCategoryChooser(
|
||||
musik::core::ILibraryPtr library,
|
||||
std::function<void(std::string)> callback);
|
||||
};
|
||||
}
|
||||
}
|
@ -70,6 +70,7 @@ static std::unordered_map<std::string, Id> NAME_TO_ID = {
|
||||
{ "navigate_library_browse_genres", Id::NavigateLibraryBrowseGenres },
|
||||
{ "navigate_library_album_artists", Id::NavigateLibraryBrowseAlbumArtists },
|
||||
{ "navigate_library_playlists", Id::NavigateLibraryBrowsePlaylists },
|
||||
{ "navigate_library_choose_category", Id::NavigateLibraryBrowseChooseCategory },
|
||||
{ "navigate_library_filter", Id::NavigateLibraryFilter },
|
||||
{ "navigate_library_tracks", Id::NavigateLibraryTracks },
|
||||
{ "navigate_library_play_queue", Id::NavigateLibraryPlayQueue },
|
||||
@ -130,6 +131,8 @@ static std::unordered_map<Id, std::string, EnumHasher> ID_TO_DEFAULT = {
|
||||
{ Id::NavigateLibraryBrowseGenres, "3" },
|
||||
{ Id::NavigateLibraryBrowseAlbumArtists, "4" },
|
||||
{ Id::NavigateLibraryBrowsePlaylists, "5" },
|
||||
{ Id::NavigateLibraryBrowseChooseCategory, "6" },
|
||||
|
||||
{ Id::NavigateLibraryFilter, "f" },
|
||||
{ Id::NavigateLibraryTracks, "t" },
|
||||
{ Id::NavigateLibraryPlayQueue, "n" },
|
||||
|
@ -61,6 +61,7 @@ namespace musik {
|
||||
NavigateLibraryBrowseGenres,
|
||||
NavigateLibraryBrowseAlbumArtists,
|
||||
NavigateLibraryBrowsePlaylists,
|
||||
NavigateLibraryBrowseChooseCategory,
|
||||
NavigateLibraryFilter,
|
||||
NavigateLibraryTracks,
|
||||
NavigateLibraryPlayQueue,
|
||||
|
@ -80,6 +80,11 @@ void ListOverlay::Layout() {
|
||||
this->GetContentWidth() - 2,
|
||||
this->height - 4); /* top and bottom padding + title */
|
||||
|
||||
auto index = this->listWindow->GetSelectedIndex();
|
||||
if (!this->listWindow->IsEntryVisible(index)) {
|
||||
this->listWindow->ScrollTo(index);
|
||||
}
|
||||
|
||||
this->Redraw();
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
"browse_title_tracks": "tracks",
|
||||
"browse_title_playlists": "playlists",
|
||||
"browse_playlist_modified": "playlist modified. press '%s' to save.",
|
||||
"browse_categories_title": "select category",
|
||||
|
||||
"console_command_output_title": "command output",
|
||||
"console_debug_logs_title": "debug logs",
|
||||
@ -156,6 +157,7 @@
|
||||
"playqueue_playlist_add_to_queue_overlay": 35,
|
||||
"playqueue_playlist_list_overlay": 35,
|
||||
"playqueue_playlist_name_overlay": 35,
|
||||
"browse_categories_overlay": 35,
|
||||
"server_overlay_width": 45,
|
||||
"preamp_overlay_width": 40
|
||||
}
|
||||
|
@ -149,6 +149,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win32\dll\vorbis\*" "$(TargetDir)" /Y /e</
|
||||
<ClCompile Include="app\layout\SettingsLayout.cpp" />
|
||||
<ClCompile Include="app\layout\TrackSearchLayout.cpp" />
|
||||
<ClCompile Include="app\model\DirectoryAdapter.cpp" />
|
||||
<ClCompile Include="app\overlay\BrowseOverlays.cpp" />
|
||||
<ClCompile Include="app\overlay\ColorThemeOverlay.cpp" />
|
||||
<ClCompile Include="app\overlay\LocaleOverlay.cpp" />
|
||||
<ClCompile Include="app\overlay\PlaybackOverlays.cpp" />
|
||||
@ -205,6 +206,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win32\dll\vorbis\*" "$(TargetDir)" /Y /e</
|
||||
<ClInclude Include="app\layout\SettingsLayout.h" />
|
||||
<ClInclude Include="app\layout\TrackSearchLayout.h" />
|
||||
<ClInclude Include="app\model\DirectoryAdapter.h" />
|
||||
<ClInclude Include="app\overlay\BrowseOverlays.h" />
|
||||
<ClInclude Include="app\overlay\ColorThemeOverlay.h" />
|
||||
<ClInclude Include="app\overlay\LocaleOverlay.h" />
|
||||
<ClInclude Include="app\overlay\PlaybackOverlays.h" />
|
||||
|
@ -147,6 +147,9 @@
|
||||
<ClCompile Include="app\overlay\PreampOverlay.cpp">
|
||||
<Filter>app\overlay</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="app\overlay\BrowseOverlays.cpp">
|
||||
<Filter>app\overlay</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h" />
|
||||
@ -346,6 +349,9 @@
|
||||
<ClInclude Include="app\overlay\PreampOverlay.h">
|
||||
<Filter>app\overlay</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="app\overlay\BrowseOverlays.h">
|
||||
<Filter>app\overlay</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="cursespp">
|
||||
|
Loading…
x
Reference in New Issue
Block a user