From 922daee6d29a7a55c71c3faee6cd6bcca9de6d40 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Tue, 10 May 2022 11:58:25 +0300 Subject: [PATCH] Support whole-word deletion in ui::edit --- libs/ui/include/psemek/ui/edit.hpp | 1 + libs/ui/source/edit.cpp | 56 ++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/libs/ui/include/psemek/ui/edit.hpp b/libs/ui/include/psemek/ui/edit.hpp index 0a2bdae5..9289767d 100644 --- a/libs/ui/include/psemek/ui/edit.hpp +++ b/libs/ui/include/psemek/ui/edit.hpp @@ -88,6 +88,7 @@ namespace psemek::ui bool editing_ = false; bool mouseover_ = false; std::optional mouse_x_; + bool ctrl_down_ = false; std::size_t caret_ = 0; float caret_blink_period_ = 0.5f; diff --git a/libs/ui/source/edit.cpp b/libs/ui/source/edit.cpp index e40a5038..4a00c769 100644 --- a/libs/ui/source/edit.cpp +++ b/libs/ui/source/edit.cpp @@ -189,6 +189,9 @@ namespace psemek::ui bool edit::on_event(key_press const & e) { + if (e.key == SDLK_LCTRL) + ctrl_down_ = e.down; + if (e.down && editing_) { if (e.key == SDLK_LEFT) @@ -243,24 +246,57 @@ namespace psemek::ui } else if (e.key == SDLK_BACKSPACE) { - if (caret_ > 0) + if (ctrl_down_) { - --caret_; + std::size_t start = caret_; + while (start > 0 && std::isspace(text_[start - 1])) --start; + while (start > 0 && !std::isspace(text_[start - 1])) --start; + auto new_text = text_; - new_text.erase(new_text.begin() + caret_); - if (!set_text(std::move(new_text), false)) - ++caret_; - reset_caret(); + new_text.erase(start, caret_ - start); + if (set_text(std::move(new_text), false)) + { + caret_ = start; + reset_caret(); + } + } + else + { + if (caret_ > 0) + { + --caret_; + auto new_text = text_; + new_text.erase(new_text.begin() + caret_); + if (!set_text(std::move(new_text), false)) + ++caret_; + reset_caret(); + } } } else if (e.key == SDLK_DELETE) { - if (caret_ < text_.size()) + if (ctrl_down_) { + std::size_t end = caret_; + while (end < text_.size() && !std::isspace(text_[end])) ++end; + while (end < text_.size() && std::isspace(text_[end])) ++end; + auto new_text = text_; - new_text.erase(new_text.begin() + caret_); - set_text(std::move(new_text), false); - reset_caret(); + new_text.erase(caret_, end - caret_); + if (set_text(std::move(new_text), false)) + { + reset_caret(); + } + } + else + { + if (caret_ < text_.size()) + { + auto new_text = text_; + new_text.erase(new_text.begin() + caret_); + set_text(std::move(new_text), false); + reset_caret(); + } } }