Support whole-word deletion in ui::edit

This commit is contained in:
Nikita Lisitsa 2022-05-10 11:58:25 +03:00
parent 39fe68e6f7
commit 922daee6d2
2 changed files with 47 additions and 10 deletions

View file

@ -88,6 +88,7 @@ namespace psemek::ui
bool editing_ = false; bool editing_ = false;
bool mouseover_ = false; bool mouseover_ = false;
std::optional<float> mouse_x_; std::optional<float> mouse_x_;
bool ctrl_down_ = false;
std::size_t caret_ = 0; std::size_t caret_ = 0;
float caret_blink_period_ = 0.5f; float caret_blink_period_ = 0.5f;

View file

@ -189,6 +189,9 @@ namespace psemek::ui
bool edit::on_event(key_press const & e) bool edit::on_event(key_press const & e)
{ {
if (e.key == SDLK_LCTRL)
ctrl_down_ = e.down;
if (e.down && editing_) if (e.down && editing_)
{ {
if (e.key == SDLK_LEFT) if (e.key == SDLK_LEFT)
@ -243,24 +246,57 @@ namespace psemek::ui
} }
else if (e.key == SDLK_BACKSPACE) 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_; auto new_text = text_;
new_text.erase(new_text.begin() + caret_); new_text.erase(start, caret_ - start);
if (!set_text(std::move(new_text), false)) if (set_text(std::move(new_text), false))
++caret_; {
reset_caret(); 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) 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_; auto new_text = text_;
new_text.erase(new_text.begin() + caret_); new_text.erase(caret_, end - caret_);
set_text(std::move(new_text), false); if (set_text(std::move(new_text), false))
reset_caret(); {
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();
}
} }
} }