Beginnings of a hotkey editor implementation.

This commit is contained in:
casey langen 2018-06-02 13:01:00 -07:00
parent 1d4544d399
commit 7260ccf827
12 changed files with 333 additions and 16 deletions

View File

@ -0,0 +1,74 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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 "HotkeysLayout.h"
#include <cursespp/Colors.h>
#include <app/model/HotkeysAdapter.h>
using namespace cursespp;
using namespace musik::cube;
using Entry = IScrollAdapter::EntryPtr;
HotkeysLayout::HotkeysLayout() {
auto adapter = std::make_shared<HotkeysAdapter>();
adapter->SetItemDecorator([this](ScrollableWindow*, size_t index, size_t, Entry) -> int64_t {
if (this->listWindow->GetSelectedIndex() == index) {
return COLOR_PAIR(CURSESPP_HIGHLIGHTED_LIST_ITEM);
}
return -1;
});
this->listWindow = std::make_shared<ListWindow>();
this->listWindow->SetFrameVisible(true);
this->listWindow->SetAdapter(adapter);
this->listWindow->SetFrameTitle(_TSTR("hotkeys_title"));
this->AddWindow(this->listWindow);
this->listWindow->SetFocusOrder(0);
}
HotkeysLayout::~HotkeysLayout() {
}
void HotkeysLayout::SetShortcutsWindow(ShortcutsWindow* shortcuts) {
}
void HotkeysLayout::OnLayout() {
this->listWindow->MoveAndResize(
0, 0, this->GetWidth(), this->GetHeight());
}

View File

@ -0,0 +1,68 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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 <cursespp/LayoutBase.h>
#include <cursespp/ListWindow.h>
#include <vector>
#include "ITopLevelLayout.h"
namespace musik {
namespace cube {
class HotkeysLayout :
public cursespp::LayoutBase,
#if (__clang_major__ == 7 && __clang_minor__ == 3)
public std::enable_shared_from_this<HotkeysLayout>,
#endif
public ITopLevelLayout,
public sigslot::has_slots<>
{
public:
HotkeysLayout();
~HotkeysLayout();
virtual void SetShortcutsWindow(
cursespp::ShortcutsWindow* shortcuts);
protected:
virtual void OnLayout();
private:
std::shared_ptr<cursespp::ListWindow> listWindow;
};
}
}

View File

@ -45,6 +45,7 @@
#include <app/layout/ConsoleLayout.h>
#include <app/layout/LibraryLayout.h>
#include <app/layout/SettingsLayout.h>
#include <app/layout/HotkeysLayout.h>
#include <app/util/Hotkeys.h>
#include <map>
@ -112,9 +113,10 @@ MainLayout::MainLayout(
library->Indexer()->Finished.connect(this, &MainLayout::OnIndexerFinished);
library->Indexer()->Progress.connect(this, &MainLayout::OnIndexerProgress);
this->libraryLayout.reset(new LibraryLayout(playback, library));
this->consoleLayout.reset(new ConsoleLayout(playback.GetTransport(), library));
this->settingsLayout.reset(new SettingsLayout(app, library, playback));
this->libraryLayout = std::make_shared<LibraryLayout>(playback, library);
this->consoleLayout = std::make_shared<ConsoleLayout>(playback.GetTransport(), library);
this->settingsLayout = std::make_shared<SettingsLayout>(app, library, playback);
this->hotkeysLayout = std::make_shared<HotkeysLayout>();
/* take user to settings if they don't have a valid configuration. otherwise,
switch to the library view immediately */
@ -286,6 +288,10 @@ bool MainLayout::KeyPress(const std::string& key) {
this->SetMainLayout(consoleLayout);
return true;
}
else if (Hotkeys::Is(Hotkeys::NavigateHotkeys, key)) {
this->SetMainLayout(hotkeysLayout);
return true;
}
else if (Hotkeys::Is(Hotkeys::NavigateLibrary, key)) {
this->SetMainLayout(libraryLayout);
return true;

View File

@ -100,7 +100,10 @@ namespace musik {
std::shared_ptr<cursespp::ShortcutsWindow> shortcuts;
std::shared_ptr<cursespp::LayoutBase> layout;
std::shared_ptr<cursespp::TextLabel> syncing;
std::shared_ptr<cursespp::LayoutBase> consoleLayout, libraryLayout, settingsLayout;
std::shared_ptr<cursespp::LayoutBase> consoleLayout;
std::shared_ptr<cursespp::LayoutBase> libraryLayout;
std::shared_ptr<cursespp::LayoutBase> settingsLayout;
std::shared_ptr<cursespp::LayoutBase> hotkeysLayout;
std::shared_ptr<cursespp::TextLabel> hotkey;
musik::core::ILibraryPtr library;
cursespp::IWindowPtr lastFocus;

View File

@ -0,0 +1,67 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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 "HotkeysAdapter.h"
#include <app/util/Hotkeys.h>
#include <cursespp/SingleLineEntry.h>
#include <cursespp/Text.h>
using namespace cursespp;
using namespace musik::cube;
using Entry = IScrollAdapter::EntryPtr;
HotkeysAdapter::HotkeysAdapter() {
}
HotkeysAdapter::~HotkeysAdapter() {
}
size_t HotkeysAdapter::GetEntryCount() {
return Hotkeys::COUNT;
}
Entry HotkeysAdapter::GetEntry(ScrollableWindow* window, size_t index) {
auto id = static_cast<Hotkeys::Id>(index);
auto name = Hotkeys::Name(id);
auto key = Hotkeys::Get(id);
int width = window->GetContentWidth();
int avail = std::max(0, width - int(u8cols(name)) - 1 - 1 - 1);
auto value = " " + name + " " + text::Align(key + " ", text::AlignRight, avail);
return IScrollAdapter::EntryPtr(new SingleLineEntry(value));
}

View File

@ -0,0 +1,53 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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 <cursespp/ScrollAdapterBase.h>
#include <cursespp/ScrollableWindow.h>
namespace musik {
namespace cube {
class HotkeysAdapter : public cursespp::ScrollAdapterBase {
public:
static const size_t NO_INDEX = (size_t)-1;
HotkeysAdapter();
virtual ~HotkeysAdapter();
virtual size_t GetEntryCount();
virtual EntryPtr GetEntry(cursespp::ScrollableWindow* window, size_t index);
};
}
}

View File

@ -42,6 +42,8 @@
using namespace musik::cube;
using namespace musik::core;
#define ENSURE_LOADED() { if (!prefs) { loadPreferences(); } }
using Id = Hotkeys::Id;
/* sigh: http://stackoverflow.com/a/24847480 */
@ -77,6 +79,7 @@ static std::unordered_map<std::string, Id> NAME_TO_ID = {
{ "navigate_library_play_queue", Id::NavigateLibraryPlayQueue },
{ "navigate_settings", Id::NavigateSettings },
{ "navigate_console", Id::NavigateConsole },
{ "navigate_hotkeys", Id::NavigateHotkeys},
{ "navigate_jump_to_playing", Id::NavigateJumpToPlaying },
{ "play_queue_move_up", Id::PlayQueueMoveUp },
@ -142,6 +145,7 @@ static std::unordered_map<Id, std::string, EnumHasher> ID_TO_DEFAULT = {
{ Id::NavigateLibraryPlayQueue, "n" },
{ Id::NavigateSettings, "s" },
{ Id::NavigateConsole, "`" },
{ Id::NavigateHotkeys, "?" },
{ Id::NavigateJumpToPlaying, "x" },
#ifdef __APPLE__
@ -264,15 +268,8 @@ bool Hotkeys::Is(Id id, const std::string& kn) {
return false;
}
std::string Hotkeys::Get(Id id) {
if (!prefs) {
loadPreferences();
}
auto custom = customIdToKey.find(id);
if (custom != customIdToKey.end()) {
return custom->second;
}
std::string Hotkeys::Default(Id id) {
ENSURE_LOADED()
auto it = ID_TO_DEFAULT.find(id);
if (it != ID_TO_DEFAULT.end()) {
@ -282,6 +279,30 @@ std::string Hotkeys::Get(Id id) {
return "";
}
std::string Hotkeys::Get(Id id) {
ENSURE_LOADED()
auto custom = customIdToKey.find(id);
if (custom != customIdToKey.end()) {
return custom->second;
}
return Default(id);
}
bool Hotkeys::IsDefault(Id id, const std::string& kn) {
return Default(id) == kn;
}
std::string Hotkeys::Name(Id id) {
for (auto entry : NAME_TO_ID) {
if (entry.second == id) {
return entry.first;
}
}
return "<error>";
}
class NavigationKeysImpl : public cursespp::INavigationKeys {
public:
virtual bool Up(const std::string& key) override { return Up() == key; }

View File

@ -44,7 +44,7 @@ namespace musik {
public:
enum Id {
/* selection */
Up,
Up = 0,
Down,
Left,
Right,
@ -68,6 +68,7 @@ namespace musik {
NavigateLibraryPlayQueue,
NavigateSettings,
NavigateConsole,
NavigateHotkeys,
NavigateJumpToPlaying,
/* views */
@ -109,11 +110,17 @@ namespace musik {
RescanMetadata,
/* general */
ContextMenu
ContextMenu,
/* :3 */
COUNT
};
static bool Is(Id id, const std::string& kn);
static std::string Get(Id id);
static std::string Name(Id id);
static std::string Default(Id id);
static bool IsDefault(Id id, const std::string& kn);
static std::shared_ptr<cursespp::INavigationKeys> NavigationKeys();
private:

View File

@ -233,7 +233,7 @@ namespace cursespp {
}
bool AlreadyRunning() {
return /*!IsDebuggerPresent() &&*/ (runningMutexLastError == ERROR_ALREADY_EXISTS);
return !IsDebuggerPresent() && (runningMutexLastError == ERROR_ALREADY_EXISTS);
}
void ShowOtherInstance(const std::string& title) {

View File

@ -37,6 +37,8 @@
"console_debug_logs_title": "debug logs",
"console_command_title": "command",
"hotkeys_title": "hotkey configuration",
"settings_space_to_add": "browse (SPACE to add)",
"settings_backspace_to_remove": "indexed paths (BACKSPACE to remove)",
"settings_enable_disable_plugins": "configure plugins",

View File

@ -146,6 +146,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win32\font\*.ttf" "$(TargetDir)fonts\" /Y
<ItemGroup>
<ClCompile Include="app\layout\BrowseLayout.cpp" />
<ClCompile Include="app\layout\DirectoryLayout.cpp" />
<ClCompile Include="app\layout\HotkeysLayout.cpp" />
<ClCompile Include="app\layout\LibraryLayout.cpp" />
<ClCompile Include="app\layout\ConsoleLayout.cpp" />
<ClCompile Include="app\layout\NowPlayingLayout.cpp" />
@ -154,6 +155,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win32\font\*.ttf" "$(TargetDir)fonts\" /Y
<ClCompile Include="app\layout\SettingsLayout.cpp" />
<ClCompile Include="app\layout\TrackSearchLayout.cpp" />
<ClCompile Include="app\model\DirectoryAdapter.cpp" />
<ClCompile Include="app\model\HotkeysAdapter.cpp" />
<ClCompile Include="app\overlay\BrowseOverlays.cpp" />
<ClCompile Include="app\overlay\ColorThemeOverlay.cpp" />
<ClCompile Include="app\overlay\LastFmOverlay.cpp" />
@ -206,6 +208,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win32\font\*.ttf" "$(TargetDir)fonts\" /Y
<ItemGroup>
<ClInclude Include="app\layout\BrowseLayout.h" />
<ClInclude Include="app\layout\DirectoryLayout.h" />
<ClInclude Include="app\layout\HotkeysLayout.h" />
<ClInclude Include="app\layout\ITopLevelLayout.h" />
<ClInclude Include="app\layout\LibraryLayout.h" />
<ClInclude Include="app\layout\ConsoleLayout.h" />
@ -215,6 +218,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win32\font\*.ttf" "$(TargetDir)fonts\" /Y
<ClInclude Include="app\layout\SettingsLayout.h" />
<ClInclude Include="app\layout\TrackSearchLayout.h" />
<ClInclude Include="app\model\DirectoryAdapter.h" />
<ClInclude Include="app\model\HotkeysAdapter.h" />
<ClInclude Include="app\overlay\BrowseOverlays.h" />
<ClInclude Include="app\overlay\ColorThemeOverlay.h" />
<ClInclude Include="app\overlay\LastFmOverlay.h" />

View File

@ -162,6 +162,12 @@
<ClCompile Include="cursespp\IMouseHandler.cpp">
<Filter>cursespp</Filter>
</ClCompile>
<ClCompile Include="app\layout\HotkeysLayout.cpp">
<Filter>app\layout</Filter>
</ClCompile>
<ClCompile Include="app\model\HotkeysAdapter.cpp">
<Filter>app\model</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
@ -373,6 +379,12 @@
<ClInclude Include="cursespp\IMouseHandler.h">
<Filter>cursespp</Filter>
</ClInclude>
<ClInclude Include="app\layout\HotkeysLayout.h">
<Filter>app\layout</Filter>
</ClInclude>
<ClInclude Include="app\model\HotkeysAdapter.h">
<Filter>app\model</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="cursespp">