From 096ee0c2670f176cfab76d54a440e5d9201d79b4 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 4 Nov 2020 18:44:51 +0100 Subject: Add ctrl+arrow key to move by word in text input, fix search triggering with backspace repeat char --- src/Text.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'src/Text.cpp') diff --git a/src/Text.cpp b/src/Text.cpp index 6512c48..9c6bc86 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -291,6 +291,17 @@ namespace QuickMedia return vertices_linear.back().line; } } + + sf::Uint32 Text::get_vertex_codepoint(int index) const { + const int num_vertices = vertices_linear.size(); + if(num_vertices == 0) { + return 0; + } else if(index < num_vertices) { + return vertices_linear[index].codepoint; + } else { + return vertices_linear.back().codepoint; + } + } void Text::updateGeometry(bool update_even_if_not_dirty) { if(dirtyText) { @@ -546,6 +557,16 @@ namespace QuickMedia caret_offset_x = get_caret_offset_by_caret_index(caretIndex); break; } + case CaretMoveDirection::LEFT_WORD: { + caretIndex = getStartOfWord(caretIndex); + caret_offset_x = get_caret_offset_by_caret_index(caretIndex); + break; + } + case CaretMoveDirection::RIGHT_WORD: { + caretIndex = getEndOfWord(caretIndex); + caret_offset_x = get_caret_offset_by_caret_index(caretIndex); + break; + } } if(caretIndex == (int)vertices_linear.size()) { @@ -587,6 +608,39 @@ namespace QuickMedia } return num_vertices; } + + static bool is_special_character(sf::Uint32 codepoint) { + return (codepoint <= 47) || (codepoint >= 58 && codepoint <= 64) || (codepoint >= 91 && codepoint <= 96) || (codepoint >= 123 && codepoint <= 127); + } + + int Text::getStartOfWord(int startIndex) const { + assert(!dirty && !dirtyText); + int start_line = get_vertex_line(startIndex); + bool start_is_special_char = is_special_character(get_vertex_codepoint(startIndex - 1)); + for(int i = startIndex - 1; i >= 0; --i) { + if(get_vertex_line(i) != start_line) + return i + 1; + bool is_special_char = is_special_character(vertices_linear[i].codepoint); + if(is_special_char != start_is_special_char) + return i + 1; + } + return 0; + } + + int Text::getEndOfWord(int startIndex) const { + assert(!dirty && !dirtyText); + const int num_vertices = vertices_linear.size(); + int start_line = get_vertex_line(startIndex); + bool start_is_special_char = is_special_character(get_vertex_codepoint(startIndex)); + for(int i = startIndex + 1; i < num_vertices; ++i) { + if(get_vertex_line(i) != start_line) + return i - 1; + bool is_special_char = is_special_character(vertices_linear[i].codepoint); + if(is_special_char != start_is_special_char) + return i; + } + return num_vertices; + } // TODO: This can be optimized by using binary search int Text::getPreviousLineClosestPosition(int startIndex) const @@ -642,12 +696,18 @@ namespace QuickMedia { if(event.key.code == sf::Keyboard::Left && caretIndex > 0) { - caretMoveDirection = CaretMoveDirection::LEFT; + if(event.key.control) + caretMoveDirection = CaretMoveDirection::LEFT_WORD; + else + caretMoveDirection = CaretMoveDirection::LEFT; dirtyCaret = true; } else if(event.key.code == sf::Keyboard::Right && !caretAtEnd) { - caretMoveDirection = CaretMoveDirection::RIGHT; + if(event.key.control) + caretMoveDirection = CaretMoveDirection::RIGHT_WORD; + else + caretMoveDirection = CaretMoveDirection::RIGHT; dirtyCaret = true; } else if(event.key.code == sf::Keyboard::BackSpace && caretIndex > 0) -- cgit v1.2.3