From b9187c6b75628f4dbdafd6bceca6ec4aa4c52013 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Fri, 8 Apr 2022 15:06:52 +0300 Subject: [PATCH] Compute proper caret position after clicking on ui::edit --- libs/ui/include/psemek/ui/edit.hpp | 1 + libs/ui/source/edit.cpp | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/libs/ui/include/psemek/ui/edit.hpp b/libs/ui/include/psemek/ui/edit.hpp index 304e3417..638e8e2f 100644 --- a/libs/ui/include/psemek/ui/edit.hpp +++ b/libs/ui/include/psemek/ui/edit.hpp @@ -84,6 +84,7 @@ namespace psemek::ui bool editing_ = false; bool mouseover_ = false; + std::optional mouse_x_; 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 76b25e7c..41a75050 100644 --- a/libs/ui/source/edit.cpp +++ b/libs/ui/source/edit.cpp @@ -90,7 +90,10 @@ namespace psemek::ui bool edit::on_event(mouse_move const & e) { - bool new_mouseover = shape_.contains(geom::cast(e.position)); + auto m = geom::cast(e.position); + mouse_x_ = m[0]; + + bool new_mouseover = shape_.contains(m); if (!mouseover_ && new_mouseover) sdl2::set_cursor(sdl2::cursor_type::beam); else if (mouseover_ && !new_mouseover) @@ -113,6 +116,31 @@ namespace psemek::ui start_text_input(); reset_caret(); } + + if (cached_state_ && mouse_x_) + { + float x_offset = 0.f; + + switch (halign_) + { + case halignment::left: + x_offset = text_box_[0].min; + break; + case halignment::center: + x_offset = text_box_[0].center() - cached_state_->size[0] * 0.5f; + break; + case halignment::right: + x_offset = text_box_[0].max - cached_state_->size[0]; + break; + } + + auto it = std::lower_bound(cached_state_->glyphs.begin(), cached_state_->glyphs.end(), *mouse_x_, [&](glyph const & g, float x){ + return g.position[0].center() + x_offset < x; + }); + + caret_ = it - cached_state_->glyphs.begin(); + } + return true; } else