From e619767b04ad57e4608f7bbf44325ce6391c597d Mon Sep 17 00:00:00 2001 From: MrLetsplay Date: Sun, 15 Oct 2023 19:46:28 +0200 Subject: [PATCH] Better TextField cursor --- src/kekengine/cpp/ui/uielements.cpp | 22 +++++++++++++++++++++- src/kekengine/cpp/util/utils.cpp | 4 ++-- src/kekengine/include/utils.h | 18 ++++++++++++++++-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/kekengine/cpp/ui/uielements.cpp b/src/kekengine/cpp/ui/uielements.cpp index 6d68dc8..4fb77bf 100644 --- a/src/kekengine/cpp/ui/uielements.cpp +++ b/src/kekengine/cpp/ui/uielements.cpp @@ -1,6 +1,7 @@ #include "uielements.h" #include +#include #include #include @@ -239,8 +240,24 @@ void TextFieldElement::updateText(std::u32string newText) { this->text = Unicode::convertU32ToStd(newText); this->textElement->setText(this->text); + UIBounds bounds = getBounds(); TextMetrics m = textElement->text->getMetrics(0, newText.length() - cursorPos, textElement->sizePixels); - this->cursor->x = uiPx(m.width); + TextMetrics fullM = textElement->text->getMetrics(0, newText.length(), textElement->sizePixels); + + // Set offset to keep cursor visible + float offsetX = -this->textElement->x.pixels; + float minOffsetX = std::max(m.width - bounds.w + 1, 0); + float maxOffsetX = m.width; + + // Adjust offset to make sure the text field is always fully utilized (if possible) + float adjust = bounds.w - (fullM.width - offsetX); + std::cout << adjust << std::endl; + if(adjust > 0) offsetX -= adjust; + + offsetX = clamp(offsetX, minOffsetX, maxOffsetX); + + this->cursor->x = uiPx(m.width - offsetX); + this->textElement->x = uiPx(-offsetX); } UIElementType TextFieldElement::getType() { @@ -310,6 +327,9 @@ void TextFieldElement::focusExit() { Input::uncaptureKeyboardInput(capture); capture = KEK_INVALID_ID; + + cursorPos = 0; + updateText(Unicode::convertStdToU32(this->text)); } void TextFieldElement::draw(UIPoint screenPos, glm::mat4 projection) { diff --git a/src/kekengine/cpp/util/utils.cpp b/src/kekengine/cpp/util/utils.cpp index f76103c..8b18312 100644 --- a/src/kekengine/cpp/util/utils.cpp +++ b/src/kekengine/cpp/util/utils.cpp @@ -16,13 +16,13 @@ float clamp(float value, float min, float max) { return value; } -float clampCyclic(int value, int min, int max) { +int clampCyclic(int value, int min, int max) { while(value > max) value -= (max - min); while(value < min) value += (max - min); return value; } -float clamp(int value, int min, int max) { +int clamp(int value, int min, int max) { if(value > max) value = max; if(value < min) value = min; return value; diff --git a/src/kekengine/include/utils.h b/src/kekengine/include/utils.h index 1c88f2b..3b2859f 100644 --- a/src/kekengine/include/utils.h +++ b/src/kekengine/include/utils.h @@ -39,9 +39,23 @@ float clampCyclic(float value, float min, float max); float clamp(float value, float min, float max); -float clampCyclic(int value, int min, int max); +int clampCyclic(int value, int min, int max); -float clamp(int value, int min, int max); +int clamp(int value, int min, int max); + +template +T clamp(T value, T min, T max) { + if(value > max) value = max; + if(value < min) value = min; + return value; +} + +template +T clampCyclic(T value, T min, T max) { + while(value > max) value -= (max - min); + while(value < min) value += (max - min); + return value; +} enum class CubeFace { FRONT,