diff --git a/include/ui/TextField.hpp b/include/ui/TextField.hpp index 2d1fabf0..9fd01844 100644 --- a/include/ui/TextField.hpp +++ b/include/ui/TextField.hpp @@ -46,6 +46,8 @@ struct TextField : widget::OpaqueWidget { void pasteClipboard(); void cursorToPrevWord(); void cursorToNextWord(); + void cursorToLineStart(); + void cursorToLineEnd(); void createContextMenu(); }; diff --git a/src/ui/TextField.cpp b/src/ui/TextField.cpp index ce38a1ff..7507285c 100644 --- a/src/ui/TextField.cpp +++ b/src/ui/TextField.cpp @@ -196,7 +196,7 @@ void TextField::onSelectKey(const SelectKeyEvent& e) { cursorToNextWord(); e.consume(this); } - // Up (placeholder) + // Up if (e.isKeyCommand(GLFW_KEY_UP)) { string::Location location = string::positionToLocation(text, cursor); if (location.line == 0) @@ -207,7 +207,7 @@ void TextField::onSelectKey(const SelectKeyEvent& e) { selection = cursor; e.consume(this); } - // Down (placeholder) + // Down if (e.isKeyCommand(GLFW_KEY_DOWN)) { string::Location location = string::positionToLocation(text, cursor); location.line++; @@ -221,7 +221,8 @@ void TextField::onSelectKey(const SelectKeyEvent& e) { || e.isKeyCommand(GLFW_KEY_LEFT, RACK_MOD_CTRL) #endif ) { - selection = cursor = 0; + cursorToLineStart(); + selection = cursor; e.consume(this); } // Shift+Home @@ -230,7 +231,7 @@ void TextField::onSelectKey(const SelectKeyEvent& e) { || e.isKeyCommand(GLFW_KEY_LEFT, RACK_MOD_CTRL | GLFW_MOD_SHIFT) #endif ) { - cursor = 0; + cursorToLineStart(); e.consume(this); } // End @@ -239,7 +240,8 @@ void TextField::onSelectKey(const SelectKeyEvent& e) { || e.isKeyCommand(GLFW_KEY_RIGHT, RACK_MOD_CTRL) #endif ) { - selection = cursor = text.size(); + cursorToLineEnd(); + selection = cursor; e.consume(this); } // Shift+End @@ -248,7 +250,7 @@ void TextField::onSelectKey(const SelectKeyEvent& e) { || e.isKeyCommand(GLFW_KEY_RIGHT, RACK_MOD_CTRL | GLFW_MOD_SHIFT) #endif ) { - cursor = text.size(); + cursorToLineEnd(); e.consume(this); } // Ctrl+V @@ -383,7 +385,6 @@ void TextField::cursorToPrevWord() { cursor = 0; return; } - // This works for valid UTF-8 text size_t pos = text.rfind(' ', std::max(cursor - 2, 0)); if (pos == std::string::npos) cursor = 0; @@ -396,13 +397,36 @@ void TextField::cursorToNextWord() { cursor = text.size(); return; } - // This works for valid UTF-8 text size_t pos = text.find(' ', std::min(cursor + 1, (int) text.size())); if (pos == std::string::npos) pos = text.size(); cursor = pos; } +void TextField::cursorToLineStart() { + if (password) { + cursor = 0; + return; + } + size_t pos = text.rfind('\n', std::max(cursor - 1, 0)); + if (pos == std::string::npos) + cursor = 0; + else + cursor = std::min((int) pos + 1, (int) text.size()); +} + +void TextField::cursorToLineEnd() { + if (password) { + cursor = text.size(); + return; + } + size_t pos = text.find('\n', cursor); + if (pos == std::string::npos) + cursor = text.size(); + else + cursor = pos; +} + void TextField::createContextMenu() { ui::Menu* menu = createMenu();