diff --git a/src/musikbox/app/layout/IndexerLayout.cpp b/src/musikbox/app/layout/IndexerLayout.cpp index 331f8368d..8d35aa4fc 100755 --- a/src/musikbox/app/layout/IndexerLayout.cpp +++ b/src/musikbox/app/layout/IndexerLayout.cpp @@ -51,11 +51,13 @@ using namespace cursespp; using namespace std::placeholders; #define LABEL_HEIGHT 1 +#define INPUT_HEIGHT 3 +#define HOTKEY_INPUT_WIDTH 20 #define TOP(w) w->GetY() #define BOTTOM(w) (w->GetY() + w->GetHeight()) #define LEFT(w) w->GetX() -#define RIGHT (x) (x->GetX() + w->GetWidth()) +#define RIGHT(w) (w->GetX() + w->GetWidth()) typedef IScrollAdapter::EntryPtr EntryPtr; static bool showDotfiles = false; @@ -109,6 +111,18 @@ void IndexerLayout::Layout() { this->dotfileCheckbox->MoveAndResize(1, BOTTOM(this->browseList), cx - 1, LABEL_HEIGHT); this->removeCheckbox->MoveAndResize(1, BOTTOM(this->dotfileCheckbox), cx - 1, LABEL_HEIGHT); + + this->hotkeyLabel->MoveAndResize( + 1, + BOTTOM(this->removeCheckbox) + 2, + this->hotkeyLabel->Length(), + LABEL_HEIGHT); + + this->hotkeyInput->MoveAndResize( + RIGHT(this->hotkeyLabel), + BOTTOM(this->removeCheckbox) + 1, + HOTKEY_INPUT_WIDTH, + INPUT_HEIGHT); } void IndexerLayout::RefreshAddedPaths() { @@ -173,16 +187,21 @@ void IndexerLayout::InitializeWindows() { this->removeCheckbox->SetText("remove missing files from library"); this->removeCheckbox->CheckChanged.connect(this, &IndexerLayout::OnRemoveMissingCheckChanged); - this->browseList->SetFocusOrder(0); - this->addedPathsList->SetFocusOrder(1); - this->dotfileCheckbox->SetFocusOrder(2); - this->removeCheckbox->SetFocusOrder(3); - this->shortcuts.reset(new ShortcutsWindow()); this->shortcuts->AddShortcut("M-a", "library"); this->shortcuts->AddShortcut("M-`", "console"); this->shortcuts->AddShortcut("^D", "quit"); + 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->dotfileCheckbox->SetFocusOrder(2); + this->removeCheckbox->SetFocusOrder(3); + this->hotkeyInput->SetFocusOrder(4); + this->AddWindow(this->browseLabel); this->AddWindow(this->addedPathsLabel); this->AddWindow(this->browseList); @@ -190,6 +209,8 @@ void IndexerLayout::InitializeWindows() { this->AddWindow(this->dotfileCheckbox); this->AddWindow(this->removeCheckbox); this->AddWindow(this->shortcuts); + this->AddWindow(this->hotkeyLabel); + this->AddWindow(this->hotkeyInput); this->Layout(); } diff --git a/src/musikbox/app/layout/IndexerLayout.h b/src/musikbox/app/layout/IndexerLayout.h index 7fa06a281..f98a2966a 100755 --- a/src/musikbox/app/layout/IndexerLayout.h +++ b/src/musikbox/app/layout/IndexerLayout.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -101,6 +102,9 @@ namespace musik { std::shared_ptr browseList; std::shared_ptr addedPathsList; + std::shared_ptr hotkeyLabel; + std::shared_ptr hotkeyInput; + std::shared_ptr shortcuts; cursespp::SimpleScrollAdapter addedPathsAdapter; diff --git a/src/musikbox/cursespp/App.cpp b/src/musikbox/cursespp/App.cpp index 878d1b9d5..333e8f41a 100755 --- a/src/musikbox/cursespp/App.cpp +++ b/src/musikbox/cursespp/App.cpp @@ -167,6 +167,11 @@ void App::Run(ILayoutPtr layout) { else if (kn == "KEY_RESIZE") { resizeAt = App::Now() + REDRAW_DEBOUNCE_MS; } + else if (this->state.input && + this->state.input->GetInputMode() == IInput::InputRaw) + { + this->state.input->Write(kn); + } else if (!keyHandler || !keyHandler(kn)) { bool processed = false; if (this->state.input) { diff --git a/src/musikbox/cursespp/IInput.h b/src/musikbox/cursespp/IInput.h index 9e9ec4879..67238b30e 100755 --- a/src/musikbox/cursespp/IInput.h +++ b/src/musikbox/cursespp/IInput.h @@ -39,9 +39,15 @@ namespace cursespp { class IInput { public: + enum InputMode { + InputRaw, + InputNormal + }; + virtual ~IInput() { } virtual bool Write(const std::string& key) = 0; virtual size_t Length() = 0; virtual size_t Position() = 0; + virtual InputMode GetInputMode() = 0; }; } diff --git a/src/musikbox/cursespp/TextInput.cpp b/src/musikbox/cursespp/TextInput.cpp index 367b86667..56f34b787 100755 --- a/src/musikbox/cursespp/TextInput.cpp +++ b/src/musikbox/cursespp/TextInput.cpp @@ -75,10 +75,11 @@ inline static bool removeUtf8Char(std::string& value, size_t position) { return false; } -TextInput::TextInput() +TextInput::TextInput(IInput::InputMode inputMode) : Window() , bufferLength(0) -, position(0) { +, position(0) +, inputMode(inputMode) { } TextInput::~TextInput() { @@ -101,21 +102,29 @@ size_t TextInput::Position() { bool TextInput::Write(const std::string& key) { /* one character at a time. if it's more than one character, we're - dealing with an escape sequence and should not print it. */ - if (u8len(key) == 1) { - size_t offset = u8offset(this->buffer, this->position); - offset = (offset == std::string::npos) ? 0 : offset; - this->buffer.insert(offset, key); + dealing with an escape sequence and should not print it unless + the input mode allows for modifiers */ + int len = u8len(key); + if (len == 1 || (len > 1 && this->inputMode == InputRaw)) { + if (this->inputMode == InputRaw) { + this->buffer = key; + this->bufferLength = len; + this->position = len; + } + else { + size_t offset = u8offset(this->buffer, this->position); + offset = (offset == std::string::npos) ? 0 : offset; + this->buffer.insert(offset, key); + this->bufferLength = u8len(buffer); + this->position += len; + } + this->TextChanged(this, this->buffer); - ++this->position; - } - else { - return false; + redrawContents(*this, buffer); + return true; } - this->bufferLength = u8len(buffer); - redrawContents(*this, buffer); - return true; + return false; } bool TextInput::KeyPress(const std::string& key) { diff --git a/src/musikbox/cursespp/TextInput.h b/src/musikbox/cursespp/TextInput.h index 3e8142d4c..3d144c3a0 100755 --- a/src/musikbox/cursespp/TextInput.h +++ b/src/musikbox/cursespp/TextInput.h @@ -52,7 +52,7 @@ namespace cursespp { sigslot::signal1 EnterPressed; sigslot::signal2 TextChanged; - TextInput(); + TextInput(InputMode inputMode = IInput::InputNormal); virtual ~TextInput(); virtual void Show(); @@ -61,6 +61,12 @@ namespace cursespp { virtual size_t Length(); virtual size_t Position(); + virtual void SetInputMode(InputMode inputMode) { + this->inputMode = inputMode; + }; + + virtual InputMode GetInputMode() { return this->inputMode; } + virtual bool KeyPress(const std::string& key); virtual void SetText(const std::string& value); @@ -72,5 +78,6 @@ namespace cursespp { std::string buffer; int position; size_t bufferLength; + InputMode inputMode; }; } diff --git a/src/musikbox/cursespp/TextLabel.h b/src/musikbox/cursespp/TextLabel.h index 83a1b1f7c..1d58cd8c2 100755 --- a/src/musikbox/cursespp/TextLabel.h +++ b/src/musikbox/cursespp/TextLabel.h @@ -57,6 +57,7 @@ namespace cursespp { const text::TextAlign alignment = text::AlignLeft); virtual std::string GetText() { return this->buffer; } + virtual size_t Length() { return u8cols(this->buffer); } virtual void Show();