mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-14 04:18:36 +00:00
Migrated MainLayout
to use new cursespp AppLayout
.
This commit is contained in:
parent
160262dd7a
commit
f732a87f3d
@ -35,6 +35,7 @@ set (CUBE_SRCS
|
||||
./app/window/TrackListView.cpp
|
||||
./app/window/TransportWindow.cpp
|
||||
./cursespp/App.cpp
|
||||
./cursespp/AppLayout.cpp
|
||||
./cursespp/Checkbox.cpp
|
||||
./cursespp/Colors.cpp
|
||||
./cursespp/DialogOverlay.cpp
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <cursespp/TextInput.h>
|
||||
#include <cursespp/ShortcutsWindow.h>
|
||||
#include <cursespp/ScrollableWindow.h>
|
||||
#include <cursespp/ITopLevelLayout.h>
|
||||
|
||||
#include <app/window/LogWindow.h>
|
||||
#include <app/window/TransportWindow.h>
|
||||
@ -47,8 +48,6 @@
|
||||
|
||||
#include <core/audio/ITransport.h>
|
||||
|
||||
#include "ITopLevelLayout.h"
|
||||
|
||||
namespace musik {
|
||||
namespace cube {
|
||||
class ConsoleLayout :
|
||||
@ -56,7 +55,7 @@ namespace musik {
|
||||
#if (__clang_major__ == 7 && __clang_minor__ == 3)
|
||||
public std::enable_shared_from_this<ConsoleLayout>,
|
||||
#endif
|
||||
public ITopLevelLayout,
|
||||
public cursespp::ITopLevelLayout,
|
||||
public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
|
@ -37,10 +37,9 @@
|
||||
#include <cursespp/LayoutBase.h>
|
||||
#include <cursespp/ListWindow.h>
|
||||
#include <cursespp/ShortcutsWindow.h>
|
||||
#include <cursespp/ITopLevelLayout.h>
|
||||
#include <vector>
|
||||
|
||||
#include "ITopLevelLayout.h"
|
||||
|
||||
namespace musik {
|
||||
namespace cube {
|
||||
class HotkeysLayout :
|
||||
@ -48,7 +47,7 @@ namespace musik {
|
||||
#if (__clang_major__ == 7 && __clang_minor__ == 3)
|
||||
public std::enable_shared_from_this<HotkeysLayout>,
|
||||
#endif
|
||||
public ITopLevelLayout,
|
||||
public cursespp::ITopLevelLayout,
|
||||
public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
|
@ -1,49 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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/ShortcutsWindow.h>
|
||||
|
||||
namespace musik {
|
||||
namespace cube {
|
||||
class ITopLevelLayout {
|
||||
public:
|
||||
virtual ~ITopLevelLayout() { }
|
||||
|
||||
virtual void SetShortcutsWindow(
|
||||
cursespp::ShortcutsWindow* w) = 0;
|
||||
};
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@
|
||||
|
||||
#include <cursespp/LayoutBase.h>
|
||||
#include <cursespp/ShortcutsWindow.h>
|
||||
|
||||
#include <cursespp/ITopLevelLayout.h>
|
||||
#include <app/layout/BrowseLayout.h>
|
||||
#include <app/layout/DirectoryLayout.h>
|
||||
#include <app/layout/NowPlayingLayout.h>
|
||||
@ -49,13 +49,11 @@
|
||||
|
||||
#include <sigslot/sigslot.h>
|
||||
|
||||
#include "ITopLevelLayout.h"
|
||||
|
||||
namespace musik {
|
||||
namespace cube {
|
||||
class LibraryLayout :
|
||||
public cursespp::LayoutBase,
|
||||
public ITopLevelLayout,
|
||||
public cursespp::ITopLevelLayout,
|
||||
public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
|
@ -60,23 +60,6 @@ using namespace musik::core::runtime;
|
||||
using namespace cursespp;
|
||||
|
||||
static UpdateCheck updateCheck;
|
||||
static std::map<ILayout*, int> lastFocusMap;
|
||||
|
||||
#define ENABLE_DEMO_MODE 0
|
||||
|
||||
#if ENABLE_DEMO_MODE
|
||||
static std::string lastKey;
|
||||
static int lastKeyRepeat = 0;
|
||||
#endif
|
||||
|
||||
static int last(ILayout* layout) {
|
||||
auto it = lastFocusMap.find(layout);
|
||||
return (it == lastFocusMap.end()) ? 0 : it->second;
|
||||
}
|
||||
|
||||
static void last(ILayout* layout, int last) {
|
||||
lastFocusMap[layout] = last;
|
||||
}
|
||||
|
||||
static void updateSyncingText(TextLabel* label, int updates) {
|
||||
try {
|
||||
@ -100,12 +83,9 @@ MainLayout::MainLayout(
|
||||
musik::core::audio::PlaybackService& playback,
|
||||
ILibraryPtr library)
|
||||
: shortcutsFocused(false)
|
||||
, topLevelLayout(nullptr)
|
||||
, syncUpdateCount(0)
|
||||
, library(library)
|
||||
, LayoutBase() {
|
||||
this->Initialize();
|
||||
|
||||
, AppLayout(app) {
|
||||
this->prefs = Preferences::ForComponent("settings");
|
||||
|
||||
library->Indexer()->Started.connect(this, &MainLayout::OnIndexerStarted);
|
||||
@ -117,13 +97,17 @@ MainLayout::MainLayout(
|
||||
this->settingsLayout = std::make_shared<SettingsLayout>(app, library, playback);
|
||||
this->hotkeysLayout = std::make_shared<HotkeysLayout>();
|
||||
|
||||
this->syncing.reset(new TextLabel());
|
||||
this->syncing->SetContentColor(Color::Banner);
|
||||
this->syncing->Hide();
|
||||
this->AddWindow(this->syncing);
|
||||
|
||||
/* take user to settings if they don't have a valid configuration. otherwise,
|
||||
switch to the library view immediately */
|
||||
std::vector<std::string> paths;
|
||||
library->Indexer()->GetPaths(paths);
|
||||
this->SetMainLayout(paths.size() > 0 ? libraryLayout : settingsLayout);
|
||||
this->SetLayout(paths.size() > 0 ? libraryLayout : settingsLayout);
|
||||
|
||||
this->EnableDemoModeIfNecessary();
|
||||
this->RunUpdateCheck();
|
||||
}
|
||||
|
||||
@ -132,18 +116,9 @@ MainLayout::~MainLayout() {
|
||||
}
|
||||
|
||||
void MainLayout::OnLayout() {
|
||||
size_t cx = Screen::GetWidth(), cy = Screen::GetHeight();
|
||||
|
||||
#if ENABLE_DEMO_MODE
|
||||
this->hotkey->MoveAndResize(0, cy - 1, cx, 1);
|
||||
--cy;
|
||||
#endif
|
||||
|
||||
int yOffset = 0;
|
||||
|
||||
auto state = this->library->Indexer()->GetState();
|
||||
if (state == IIndexer::StateIndexing) {
|
||||
yOffset = 1;
|
||||
if (this->library->Indexer()->GetState() == IIndexer::StateIndexing) {
|
||||
size_t cx = this->GetContentWidth();
|
||||
this->SetPadding(1, 0, 0, 0);
|
||||
this->syncing->MoveAndResize(0, 0, cx, 1);
|
||||
this->syncing->Show();
|
||||
|
||||
@ -152,180 +127,33 @@ void MainLayout::OnLayout() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->SetPadding(0, 0, 0, 0);
|
||||
this->syncing->Hide();
|
||||
}
|
||||
|
||||
if (this->layout) {
|
||||
this->layout->MoveAndResize(0, yOffset, cx, cy - 1 - yOffset);
|
||||
this->layout->Show();
|
||||
this->layout->BringToTop();
|
||||
|
||||
if (this->shortcutsFocused) {
|
||||
this->layout->SetFocus(IWindowPtr());
|
||||
}
|
||||
}
|
||||
|
||||
this->shortcuts->MoveAndResize(0, cy - 1, cx, 1);
|
||||
}
|
||||
|
||||
void MainLayout::Initialize() {
|
||||
this->shortcuts.reset(new ShortcutsWindow());
|
||||
this->AddWindow(this->shortcuts);
|
||||
|
||||
#if ENABLE_DEMO_MODE
|
||||
this->hotkey.reset(new TextLabel());
|
||||
this->hotkey->SetContentColor(Color::Footer);
|
||||
this->hotkey->SetText("keypress: <none>", text::AlignCenter);
|
||||
this->AddWindow(this->hotkey);
|
||||
#endif
|
||||
|
||||
this->syncing.reset(new TextLabel());
|
||||
this->syncing->SetContentColor(Color::Banner);
|
||||
this->syncing->Hide();
|
||||
this->AddWindow(this->syncing);
|
||||
}
|
||||
|
||||
cursespp::IWindowPtr MainLayout::GetFocus() {
|
||||
if (this->shortcutsFocused) {
|
||||
return this->shortcuts;
|
||||
}
|
||||
|
||||
if (this->layout) {
|
||||
return this->layout->GetFocus();
|
||||
}
|
||||
|
||||
return cursespp::IWindowPtr();
|
||||
}
|
||||
|
||||
IWindowPtr MainLayout::FocusNext() {
|
||||
return (this->shortcutsFocused)
|
||||
? this->BlurShortcuts() : this->layout->FocusNext();
|
||||
}
|
||||
IWindowPtr MainLayout::FocusPrev() {
|
||||
return (this->shortcutsFocused)
|
||||
? this->BlurShortcuts() : this->layout->FocusPrev();
|
||||
}
|
||||
|
||||
void MainLayout::SetMainLayout(std::shared_ptr<cursespp::LayoutBase> layout) {
|
||||
if (layout != this->layout) {
|
||||
if (this->layout) {
|
||||
if (this->lastFocus) {
|
||||
this->layout->SetFocus(this->lastFocus);
|
||||
}
|
||||
|
||||
this->RemoveWindow(this->layout);
|
||||
last(this->layout.get(), this->layout->GetFocusIndex());
|
||||
this->layout->SetFocusIndex(-1);
|
||||
this->layout->Hide();
|
||||
}
|
||||
|
||||
this->lastFocus.reset();
|
||||
|
||||
if (this->topLevelLayout) {
|
||||
this->topLevelLayout->SetShortcutsWindow(nullptr);
|
||||
}
|
||||
|
||||
this->layout = layout;
|
||||
this->shortcuts->RemoveAll();
|
||||
|
||||
if (this->layout) {
|
||||
this->topLevelLayout = dynamic_cast<ITopLevelLayout*>(layout.get());
|
||||
if (this->topLevelLayout) {
|
||||
this->topLevelLayout->SetShortcutsWindow(this->shortcuts.get());
|
||||
}
|
||||
|
||||
this->AddWindow(this->layout);
|
||||
this->layout->SetFocusOrder(0);
|
||||
this->layout->SetFocusIndex(last(this->layout.get()));
|
||||
this->Layout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursespp::IWindowPtr MainLayout::BlurShortcuts() {
|
||||
this->shortcuts->Blur();
|
||||
this->shortcutsFocused = false;
|
||||
|
||||
if (this->layout) {
|
||||
bool refocused = false;
|
||||
if (this->lastFocus) {
|
||||
refocused = this->layout->SetFocus(this->lastFocus);
|
||||
this->lastFocus.reset();
|
||||
}
|
||||
|
||||
if (!refocused) {
|
||||
this->layout->FocusNext();
|
||||
}
|
||||
}
|
||||
|
||||
return this->layout ? this->layout->GetFocus() : IWindowPtr();
|
||||
}
|
||||
|
||||
void MainLayout::FocusShortcuts() {
|
||||
this->shortcuts->Focus();
|
||||
|
||||
if (this->layout) {
|
||||
this->lastFocus = this->layout->GetFocus();
|
||||
|
||||
if (this->lastFocus) {
|
||||
this->lastFocus->Blur();
|
||||
}
|
||||
|
||||
this->layout->SetFocus(IWindowPtr());
|
||||
}
|
||||
|
||||
this->shortcuts->Focus();
|
||||
AppLayout::OnLayout();
|
||||
}
|
||||
|
||||
bool MainLayout::KeyPress(const std::string& key) {
|
||||
/* deal with top-level view switching first. */
|
||||
if (Hotkeys::Is(Hotkeys::NavigateConsole, key)) {
|
||||
this->SetMainLayout(consoleLayout);
|
||||
this->SetLayout(consoleLayout);
|
||||
return true;
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::NavigateHotkeys, key)) {
|
||||
this->SetMainLayout(hotkeysLayout);
|
||||
this->SetLayout(hotkeysLayout);
|
||||
return true;
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::NavigateLibrary, key)) {
|
||||
this->SetMainLayout(libraryLayout);
|
||||
this->SetLayout(libraryLayout);
|
||||
return true;
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::NavigateSettings, key)) {
|
||||
this->SetMainLayout(settingsLayout);
|
||||
this->SetLayout(settingsLayout);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* otherwise, see if the user is monkeying around with the
|
||||
shortcut bar focus... */
|
||||
if (key == "^[" ||
|
||||
(key == "KEY_ENTER" && this->shortcutsFocused) ||
|
||||
(Hotkeys::Is(Hotkeys::Up, key) && this->shortcutsFocused))
|
||||
{
|
||||
this->shortcutsFocused = !this->shortcutsFocused;
|
||||
|
||||
if (this->shortcutsFocused) {
|
||||
this->FocusShortcuts();
|
||||
}
|
||||
else {
|
||||
this->BlurShortcuts();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this->shortcutsFocused) {
|
||||
if (Hotkeys::Is(Hotkeys::Down, key) || Hotkeys::Is(Hotkeys::Left, key) ||
|
||||
Hotkeys::Is(Hotkeys::Up, key) || Hotkeys::Is(Hotkeys::Right, key))
|
||||
{
|
||||
/* layouts allow focusing via TAB and sometimes arrow
|
||||
keys. suppress these from bubbling. */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, pass along to our child layout */
|
||||
return this->layout ? this->layout->KeyPress(key) : false;
|
||||
return AppLayout::KeyPress(key);
|
||||
}
|
||||
|
||||
void MainLayout::Start() {
|
||||
@ -346,16 +174,16 @@ void MainLayout::ProcessMessage(musik::core::runtime::IMessage &message) {
|
||||
int type = message.Type();
|
||||
|
||||
if (type == message::JumpToConsole) {
|
||||
this->SetMainLayout(consoleLayout);
|
||||
this->SetLayout(consoleLayout);
|
||||
}
|
||||
else if (type == message::JumpToSettings) {
|
||||
this->SetMainLayout(settingsLayout);
|
||||
this->SetLayout(settingsLayout);
|
||||
}
|
||||
else if (type == message::JumpToHotkeys) {
|
||||
this->SetMainLayout(hotkeysLayout);
|
||||
this->SetLayout(hotkeysLayout);
|
||||
}
|
||||
else if (type == message::JumpToLibrary) {
|
||||
this->SetMainLayout(libraryLayout);
|
||||
this->SetLayout(libraryLayout);
|
||||
}
|
||||
if (type == message::IndexerStarted) {
|
||||
this->syncUpdateCount = 0;
|
||||
@ -396,32 +224,4 @@ void MainLayout::RunUpdateCheck() {
|
||||
UpdateCheck::ShowUpgradeAvailableOverlay(version, url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainLayout::EnableDemoModeIfNecessary() {
|
||||
#if ENABLE_DEMO_MODE
|
||||
App::Instance().SetKeyHook([this](const std::string& key) -> bool {
|
||||
static std::map<std::string, std::string> SANITIZE = {
|
||||
{ "^I", "TAB" }, { " ", "SPACE" }, { "^[", "ESC" }
|
||||
};
|
||||
|
||||
auto it = SANITIZE.find(key);
|
||||
std::string normalized = (it == SANITIZE.end()) ? key : it->second;
|
||||
|
||||
if (normalized == lastKey) {
|
||||
++lastKeyRepeat;
|
||||
if (lastKeyRepeat >= 2) {
|
||||
normalized = normalized + " (x" + std::to_string(lastKeyRepeat) + ")";
|
||||
}
|
||||
}
|
||||
else {
|
||||
lastKey = normalized;
|
||||
lastKeyRepeat = 1;
|
||||
}
|
||||
|
||||
std::string keypress = "keypress: " + (normalized.size() ? normalized : "<none>");
|
||||
this->hotkey->SetText(keypress, text::AlignCenter);
|
||||
return false;
|
||||
});
|
||||
#endif
|
||||
}
|
@ -35,10 +35,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cursespp/App.h>
|
||||
#include <cursespp/LayoutBase.h>
|
||||
#include <cursespp/AppLayout.h>
|
||||
#include <cursespp/TextInput.h>
|
||||
#include <cursespp/TextLabel.h>
|
||||
#include <cursespp/ShortcutsWindow.h>
|
||||
|
||||
#include <core/audio/PlaybackService.h>
|
||||
#include <core/support/Preferences.h>
|
||||
@ -47,18 +46,15 @@
|
||||
|
||||
#include <core/audio/MasterTransport.h>
|
||||
|
||||
#include "ITopLevelLayout.h"
|
||||
|
||||
#include <sigslot/sigslot.h>
|
||||
|
||||
namespace musik {
|
||||
namespace cube {
|
||||
class MainLayout :
|
||||
public cursespp::LayoutBase,
|
||||
public cursespp::AppLayout
|
||||
#if (__clang_major__ == 7 && __clang_minor__ == 3)
|
||||
public std::enable_shared_from_this<MainLayout>,
|
||||
public std::enable_shared_from_this<MainLayout>
|
||||
#endif
|
||||
public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
MainLayout(
|
||||
@ -73,13 +69,8 @@ namespace musik {
|
||||
|
||||
virtual bool KeyPress(const std::string& key) override;
|
||||
virtual void OnLayout() override;
|
||||
virtual cursespp::IWindowPtr GetFocus() override;
|
||||
virtual cursespp::IWindowPtr FocusNext() override;
|
||||
virtual cursespp::IWindowPtr FocusPrev() override;
|
||||
virtual void ProcessMessage(musik::core::runtime::IMessage &message) override;
|
||||
|
||||
void SetMainLayout(std::shared_ptr<cursespp::LayoutBase> layout);
|
||||
|
||||
private:
|
||||
void OnIndexerStarted();
|
||||
void OnIndexerProgress(int count);
|
||||
@ -88,23 +79,13 @@ namespace musik {
|
||||
void Initialize();
|
||||
void RunUpdateCheck();
|
||||
|
||||
void EnableDemoModeIfNecessary();
|
||||
|
||||
cursespp::IWindowPtr BlurShortcuts();
|
||||
void FocusShortcuts();
|
||||
|
||||
std::shared_ptr<musik::core::Preferences> prefs;
|
||||
std::shared_ptr<cursespp::ShortcutsWindow> shortcuts;
|
||||
std::shared_ptr<cursespp::LayoutBase> layout;
|
||||
std::shared_ptr<cursespp::TextLabel> syncing;
|
||||
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;
|
||||
ITopLevelLayout* topLevelLayout;
|
||||
bool shortcutsFocused;
|
||||
int syncUpdateCount;
|
||||
};
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <cursespp/TextLabel.h>
|
||||
#include <cursespp/TextInput.h>
|
||||
#include <cursespp/DialogOverlay.h>
|
||||
#include <cursespp/ITopLevelLayout.h>
|
||||
|
||||
#include <core/audio/PlaybackService.h>
|
||||
#include <core/audio/MasterTransport.h>
|
||||
@ -56,12 +57,10 @@
|
||||
|
||||
#include <sigslot/sigslot.h>
|
||||
|
||||
#include "ITopLevelLayout.h"
|
||||
|
||||
namespace musik {
|
||||
namespace cube {
|
||||
class SettingsLayout :
|
||||
public ITopLevelLayout,
|
||||
public cursespp::ITopLevelLayout,
|
||||
public cursespp::LayoutBase,
|
||||
#if (__clang_major__ == 7 && __clang_minor__ == 3)
|
||||
public std::enable_shared_from_this<SettingsLayout>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user