mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-05 18:39:55 +00:00
- Moved the hotkey tester to an InputOverlay so it takes up less space
- Fixed bug where overlays may become obscured if a layout change happens in the background while one is visible. - Added "SyncOnStartup" setting to SettingsLayout
This commit is contained in:
parent
ccee62cca5
commit
b8a220e1dd
@ -37,6 +37,7 @@
|
||||
#include <cursespp/App.h>
|
||||
#include <cursespp/Colors.h>
|
||||
#include <cursespp/DialogOverlay.h>
|
||||
#include <cursespp/InputOverlay.h>
|
||||
#include <cursespp/Screen.h>
|
||||
#include <cursespp/SingleLineEntry.h>
|
||||
|
||||
@ -101,7 +102,11 @@ SettingsLayout::~SettingsLayout() {
|
||||
}
|
||||
|
||||
void SettingsLayout::OnCheckboxChanged(cursespp::Checkbox* cb, bool checked) {
|
||||
if (cb == removeCheckbox.get()) {
|
||||
if (cb == syncOnStartupCheckbox.get()) {
|
||||
this->libraryPrefs->SetBool(core::prefs::keys::SyncOnStartup, checked);
|
||||
this->libraryPrefs->Save();
|
||||
}
|
||||
else if (cb == removeCheckbox.get()) {
|
||||
this->libraryPrefs->SetBool(core::prefs::keys::RemoveMissingFiles, checked);
|
||||
this->libraryPrefs->Save();
|
||||
}
|
||||
@ -152,6 +157,12 @@ void SettingsLayout::OnPluginsDropdownActivate(cursespp::TextLabel* label) {
|
||||
PluginOverlay::Show();
|
||||
}
|
||||
|
||||
void SettingsLayout::OnHotkeyDropdownActivate(cursespp::TextLabel* label) {
|
||||
std::shared_ptr<InputOverlay> overlay(new InputOverlay());
|
||||
overlay->SetTitle("hotkey tester").SetInputMode(IInput::InputRaw);
|
||||
App::Overlays().Push(overlay);
|
||||
}
|
||||
|
||||
void SettingsLayout::OnLayout() {
|
||||
int x = this->GetX(), y = this->GetY();
|
||||
int cx = this->GetWidth(), cy = this->GetHeight();
|
||||
@ -175,12 +186,11 @@ void SettingsLayout::OnLayout() {
|
||||
this->outputDropdown->MoveAndResize(1, y++, cx - 1, LABEL_HEIGHT);
|
||||
this->transportDropdown->MoveAndResize(1, y++, cx - 1, LABEL_HEIGHT);
|
||||
this->pluginsDropdown->MoveAndResize(1, y++, cx - 1, LABEL_HEIGHT);
|
||||
this->hotkeyDropdown->MoveAndResize(1, y++, cx - 1, LABEL_HEIGHT);
|
||||
this->dotfileCheckbox->MoveAndResize(1, y++, cx - 1, LABEL_HEIGHT);
|
||||
this->syncOnStartupCheckbox->MoveAndResize(1, y++, cx - 1, LABEL_HEIGHT);
|
||||
this->removeCheckbox->MoveAndResize(1, y++, cx - 1, LABEL_HEIGHT);
|
||||
this->customColorsCheckbox->MoveAndResize(1, y++, cx - 1, LABEL_HEIGHT);
|
||||
|
||||
this->hotkeyLabel->MoveAndResize(1, y + 1, this->hotkeyLabel->Length(), LABEL_HEIGHT);
|
||||
this->hotkeyInput->MoveAndResize(RIGHT(this->hotkeyLabel), y, HOTKEY_INPUT_WIDTH, INPUT_HEIGHT);
|
||||
}
|
||||
|
||||
void SettingsLayout::RefreshAddedPaths() {
|
||||
@ -249,23 +259,25 @@ void SettingsLayout::InitializeWindows() {
|
||||
this->pluginsDropdown->SetText(arrow + " enable/disable plugins");
|
||||
this->pluginsDropdown->Activated.connect(this, &SettingsLayout::OnPluginsDropdownActivate);
|
||||
|
||||
this->hotkeyDropdown.reset(new TextLabel());
|
||||
this->hotkeyDropdown->SetText(arrow + " hotkey tester");
|
||||
this->hotkeyDropdown->Activated.connect(this, &SettingsLayout::OnHotkeyDropdownActivate);
|
||||
|
||||
CREATE_CHECKBOX(this->dotfileCheckbox, "show dotfiles in directory browser");
|
||||
CREATE_CHECKBOX(this->syncOnStartupCheckbox, "sync metadata on startup");
|
||||
CREATE_CHECKBOX(this->removeCheckbox, "remove missing files from library");
|
||||
CREATE_CHECKBOX(this->customColorsCheckbox, "disable custom colors (requires restart)");
|
||||
|
||||
this->hotkeyLabel.reset(new TextLabel());
|
||||
this->hotkeyLabel->SetText("hotkey tester: ");
|
||||
this->hotkeyInput.reset(new TextInput(IInput::InputRaw));
|
||||
|
||||
this->browseList->SetFocusOrder(0);
|
||||
this->addedPathsList->SetFocusOrder(1);
|
||||
this->outputDropdown->SetFocusOrder(2);
|
||||
this->transportDropdown->SetFocusOrder(3);
|
||||
this->pluginsDropdown->SetFocusOrder(4);
|
||||
this->dotfileCheckbox->SetFocusOrder(5);
|
||||
this->removeCheckbox->SetFocusOrder(6);
|
||||
this->customColorsCheckbox->SetFocusOrder(7);
|
||||
this->hotkeyInput->SetFocusOrder(8);
|
||||
this->hotkeyDropdown->SetFocusOrder(5);
|
||||
this->dotfileCheckbox->SetFocusOrder(6);
|
||||
this->syncOnStartupCheckbox->SetFocusOrder(7);
|
||||
this->removeCheckbox->SetFocusOrder(8);
|
||||
this->customColorsCheckbox->SetFocusOrder(9);
|
||||
|
||||
this->AddWindow(this->browseLabel);
|
||||
this->AddWindow(this->addedPathsLabel);
|
||||
@ -274,11 +286,11 @@ void SettingsLayout::InitializeWindows() {
|
||||
this->AddWindow(this->outputDropdown);
|
||||
this->AddWindow(this->transportDropdown);
|
||||
this->AddWindow(this->pluginsDropdown);
|
||||
this->AddWindow(this->hotkeyDropdown);
|
||||
this->AddWindow(this->dotfileCheckbox);
|
||||
this->AddWindow(this->syncOnStartupCheckbox);
|
||||
this->AddWindow(this->removeCheckbox);
|
||||
this->AddWindow(this->customColorsCheckbox);
|
||||
this->AddWindow(this->hotkeyLabel);
|
||||
this->AddWindow(this->hotkeyInput);
|
||||
}
|
||||
|
||||
void SettingsLayout::SetShortcutsWindow(ShortcutsWindow* shortcuts) {
|
||||
@ -333,6 +345,7 @@ void SettingsLayout::CheckShowFirstRunDialog() {
|
||||
}
|
||||
|
||||
void SettingsLayout::LoadPreferences() {
|
||||
this->syncOnStartupCheckbox->SetChecked(this->libraryPrefs->GetBool(core::prefs::keys::SyncOnStartup, true));
|
||||
this->removeCheckbox->SetChecked(this->libraryPrefs->GetBool(core::prefs::keys::RemoveMissingFiles, true));
|
||||
this->customColorsCheckbox->SetChecked(this->libraryPrefs->GetBool(box::prefs::keys::DisableCustomColors));
|
||||
|
||||
|
@ -97,6 +97,7 @@ namespace musik {
|
||||
void OnOutputDropdownActivated(cursespp::TextLabel* label);
|
||||
void OnTransportDropdownActivate(cursespp::TextLabel* label);
|
||||
void OnPluginsDropdownActivate(cursespp::TextLabel* label);
|
||||
void OnHotkeyDropdownActivate(cursespp::TextLabel* label);
|
||||
|
||||
int64 ListItemDecorator(
|
||||
cursespp::ScrollableWindow* w,
|
||||
@ -114,9 +115,11 @@ namespace musik {
|
||||
std::shared_ptr<cursespp::TextLabel> outputDropdown;
|
||||
std::shared_ptr<cursespp::TextLabel> transportDropdown;
|
||||
std::shared_ptr<cursespp::TextLabel> pluginsDropdown;
|
||||
std::shared_ptr<cursespp::TextLabel> hotkeyDropdown;
|
||||
|
||||
std::shared_ptr<cursespp::Checkbox> removeCheckbox;
|
||||
std::shared_ptr<cursespp::Checkbox> dotfileCheckbox;
|
||||
std::shared_ptr<cursespp::Checkbox> syncOnStartupCheckbox;
|
||||
std::shared_ptr<cursespp::Checkbox> removeCheckbox;
|
||||
std::shared_ptr<cursespp::Checkbox> customColorsCheckbox;
|
||||
|
||||
std::shared_ptr<cursespp::TextLabel> browseLabel;
|
||||
@ -124,9 +127,6 @@ namespace musik {
|
||||
std::shared_ptr<cursespp::ListWindow> browseList;
|
||||
std::shared_ptr<cursespp::ListWindow> addedPathsList;
|
||||
|
||||
std::shared_ptr<cursespp::TextLabel> hotkeyLabel;
|
||||
std::shared_ptr<cursespp::TextInput> hotkeyInput;
|
||||
|
||||
std::shared_ptr<cursespp::DialogOverlay> firstRunDialog;
|
||||
|
||||
std::shared_ptr<cursespp::SimpleScrollAdapter> addedPathsAdapter;
|
||||
|
@ -236,7 +236,14 @@ void App::Run(ILayoutPtr layout) {
|
||||
because they may muck around with layout, then redraw the window. if
|
||||
done in the reverse order, the user may observe more flicker. */
|
||||
Window::MessageQueue().Dispatch();
|
||||
Window::WriteToScreen(this->state.input);
|
||||
|
||||
if (Window::WriteToScreen(this->state.input)) {
|
||||
/* if we wrote to the screen that means panels could have shifted
|
||||
around. ensure any visible overlay is still on top. */
|
||||
if (this->state.overlayWindow && !this->state.overlayWindow->IsTop()) {
|
||||
this->state.overlay->BringToTop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
overlays.Clear();
|
||||
@ -282,6 +289,9 @@ void App::CheckShowOverlay() {
|
||||
|
||||
this->state.overlay = top;
|
||||
|
||||
this->state.overlayWindow =
|
||||
top ? dynamic_cast<IWindow*>(top.get()) : nullptr;
|
||||
|
||||
ILayoutPtr newTopLayout = this->state.ActiveLayout();
|
||||
if (newTopLayout) {
|
||||
newTopLayout->Layout();
|
||||
|
@ -68,12 +68,20 @@ namespace cursespp {
|
||||
private:
|
||||
struct WindowState {
|
||||
ILayoutPtr overlay;
|
||||
IWindow* overlayWindow;
|
||||
ILayoutPtr layout;
|
||||
IWindowPtr focused;
|
||||
IViewRoot* viewRoot;
|
||||
IInput* input;
|
||||
IKeyHandler* keyHandler;
|
||||
|
||||
WindowState() {
|
||||
this->overlayWindow = nullptr;
|
||||
this->viewRoot = nullptr;
|
||||
this->input = nullptr;
|
||||
this->keyHandler = nullptr;
|
||||
}
|
||||
|
||||
inline ILayoutPtr ActiveLayout() {
|
||||
/* if there's a visible overlay, it's always the current
|
||||
layout and will consume all key events */
|
||||
|
@ -83,6 +83,7 @@ namespace cursespp {
|
||||
virtual bool IsVisible() = 0;
|
||||
virtual bool IsFocused() = 0;
|
||||
virtual void OnParentVisibilityChanged(bool visible) = 0;
|
||||
virtual bool IsTop() = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<IWindow> IWindowPtr;
|
||||
|
@ -64,6 +64,7 @@ InputOverlay::InputOverlay() {
|
||||
this->textInput->SetFocusedFrameColor(CURSESPP_OVERLAY_INPUT_FRAME);
|
||||
this->textInput->SetFocusedContentColor(CURSESPP_OVERLAY_BACKGROUND);
|
||||
this->textInput->EnterPressed.connect(this, &InputOverlay::OnInputEnterPressed);
|
||||
this->textInput->TextChanged.connect(this, &InputOverlay::OnInputKeyPress);
|
||||
this->AddWindow(this->textInput);
|
||||
}
|
||||
|
||||
@ -114,6 +115,15 @@ InputOverlay& InputOverlay::SetWidth(int width) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void InputOverlay::OnInputKeyPress(TextInput* input, std::string key) {
|
||||
/* raw input mode will not allow the ESC key to propagate.
|
||||
we can catch it here, and pass it through to the regular key
|
||||
handler to close the dialog */
|
||||
if (input->GetInputMode() == IInput::InputRaw && key == "^[") {
|
||||
this->KeyPress(key);
|
||||
}
|
||||
}
|
||||
|
||||
bool InputOverlay::KeyPress(const std::string& key) {
|
||||
if (key == "^[") { /* esc closes */
|
||||
this->Dismiss();
|
||||
@ -132,6 +142,10 @@ void InputOverlay::OnInputEnterPressed(TextInput* input) {
|
||||
this->Dismiss();
|
||||
}
|
||||
}
|
||||
InputOverlay& InputOverlay::SetInputMode(IInput::InputMode mode) {
|
||||
this->textInput->SetInputMode(mode);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputOverlay& InputOverlay::SetInputAcceptedCallback(InputAcceptedCallback cb) {
|
||||
this->inputAcceptedCallback = cb;
|
||||
|
@ -55,6 +55,7 @@ namespace cursespp {
|
||||
InputOverlay& SetText(const std::string& text);
|
||||
InputOverlay& SetInputAcceptedCallback(InputAcceptedCallback cb);
|
||||
InputOverlay& SetWidth(int width);
|
||||
InputOverlay& SetInputMode(IInput::InputMode mode);
|
||||
|
||||
virtual void Layout();
|
||||
virtual bool KeyPress(const std::string& key);
|
||||
@ -62,6 +63,7 @@ namespace cursespp {
|
||||
protected:
|
||||
virtual void OnVisibilityChanged(bool visible);
|
||||
virtual void OnInputEnterPressed(TextInput* input);
|
||||
virtual void OnInputKeyPress(TextInput* input, std::string key);
|
||||
|
||||
private:
|
||||
void Redraw();
|
||||
|
@ -164,7 +164,7 @@ void LayoutBase::Invalidate() {
|
||||
|
||||
bool LayoutBase::AddWindow(IWindowPtr window) {
|
||||
if (!window) {
|
||||
throw std::runtime_error("asdf");
|
||||
throw std::runtime_error("window cannot be null!");
|
||||
}
|
||||
|
||||
if (find(this->children, window) >= 0) {
|
||||
|
@ -49,6 +49,20 @@ namespace cursespp {
|
||||
this->stack = stack;
|
||||
}
|
||||
|
||||
virtual bool IsTop() {
|
||||
if (LayoutBase::IsTop()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < this->GetWindowCount(); i++) {
|
||||
if (this->GetWindowAt(i)->IsTop()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
OverlayStack* GetOverlayStack() {
|
||||
return this->stack;
|
||||
|
@ -46,8 +46,10 @@ using namespace cursespp;
|
||||
using namespace musik::core::runtime;
|
||||
|
||||
static int NEXT_ID = 0;
|
||||
|
||||
static bool drawPending = false;
|
||||
static bool freeze = false;
|
||||
static Window* top = nullptr;
|
||||
|
||||
static MessageQueue messageQueue;
|
||||
|
||||
@ -68,13 +70,16 @@ static inline void DrawCursor(IInput* input) {
|
||||
}
|
||||
}
|
||||
|
||||
void Window::WriteToScreen(IInput* input) {
|
||||
bool Window::WriteToScreen(IInput* input) {
|
||||
if (drawPending && !freeze) {
|
||||
drawPending = false;
|
||||
update_panels();
|
||||
doupdate();
|
||||
DrawCursor(input);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Window::InvalidateScreen() {
|
||||
@ -151,9 +156,15 @@ void Window::BringToTop() {
|
||||
if (this->contentPanel != this->framePanel) {
|
||||
top_panel(this->contentPanel);
|
||||
}
|
||||
|
||||
::top = this;
|
||||
}
|
||||
}
|
||||
|
||||
bool Window::IsTop() {
|
||||
return (::top == this);
|
||||
}
|
||||
|
||||
void Window::SendToBottom() {
|
||||
if (this->framePanel) {
|
||||
bottom_panel(this->contentPanel);
|
||||
|
@ -105,12 +105,13 @@ namespace cursespp {
|
||||
|
||||
virtual bool IsVisible();
|
||||
virtual bool IsFocused();
|
||||
virtual bool IsTop();
|
||||
|
||||
virtual void OnParentVisibilityChanged(bool visible);
|
||||
|
||||
bool HasBadBounds() { return this->badBounds; }
|
||||
|
||||
static void WriteToScreen(IInput* input);
|
||||
static bool WriteToScreen(IInput* input);
|
||||
static void InvalidateScreen();
|
||||
static void Freeze();
|
||||
static void Unfreeze();
|
||||
|
Loading…
x
Reference in New Issue
Block a user