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/QuickMedia.cpp | 3 +++ src/SearchBar.cpp | 10 ++++++++- src/Text.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 7ff05cf..865f6fe 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -3929,6 +3929,9 @@ namespace QuickMedia { case PageType::CHAT_LOGIN: { previous_messages_future.cancel(); cleanup_tasks(); + tabs.clear(); + unreferenced_event_by_room.clear(); + all_messages.clear(); new_page = PageType::CHAT; matrix->stop_sync(); matrix->logout(); diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp index aafe987..0c72805 100644 --- a/src/SearchBar.cpp +++ b/src/SearchBar.cpp @@ -37,6 +37,7 @@ namespace QuickMedia { needs_update(true), input_masked(input_masked), typing(false), + backspace_seq_count(0), vertical_pos(0.0f) { text.setFillColor(text_placeholder_color); @@ -94,7 +95,10 @@ namespace QuickMedia { void SearchBar::update() { sf::Int32 elapsed_time = time_since_search_update.getElapsedTime().asMilliseconds(); - if(updated_search && elapsed_time >= text_autosearch_delay) { + int timeout = text_autosearch_delay; + if(backspace_seq_count == 1) + timeout = 750; + if(updated_search && elapsed_time >= timeout) { updated_search = false; auto u8 = text.getString().toUtf8(); std::string *u8_str = (std::string*)&u8; @@ -173,9 +177,11 @@ namespace QuickMedia { } updated_search = true; updated_autocomplete = true; + ++backspace_seq_count; time_since_search_update.restart(); } } else if(codepoint == 13) { // Return + backspace_seq_count = 0; if(onTextSubmitCallback) { auto u8 = text.getString().toUtf8(); std::string *u8_str = (std::string*)&u8; @@ -199,6 +205,7 @@ namespace QuickMedia { needs_update = true; updated_search = false; updated_autocomplete = false; + backspace_seq_count = 0; } void SearchBar::append_text(const std::string &text_to_add) { @@ -224,6 +231,7 @@ namespace QuickMedia { updated_search = true; updated_autocomplete = true; time_since_search_update.restart(); + backspace_seq_count = 0; if(str[str.getSize() - 1] == '\n') needs_update = true; } 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