From 90057e1f3007d482b00e197e90c1a47540578167 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 22 Feb 2024 13:32:27 +0300 Subject: [PATCH] mouse caret movement --- src/frontend/gui/controls.cpp | 32 ++++++++++++++++++++++++-------- src/frontend/gui/controls.h | 4 ++++ src/graphics/Font.cpp | 4 ++-- src/graphics/Font.h | 2 +- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/frontend/gui/controls.cpp b/src/frontend/gui/controls.cpp index 4fc29c58..996226c2 100644 --- a/src/frontend/gui/controls.cpp +++ b/src/frontend/gui/controls.cpp @@ -257,6 +257,8 @@ TextBox::TextBox(std::wstring placeholder, glm::vec4 padding) void TextBox::draw(const GfxContext* pctx, Assets* assets) { Panel::draw(pctx, assets); + font = assets->getFont(label->getFontName()); + if (!isFocused()) return; @@ -266,7 +268,6 @@ void TextBox::draw(const GfxContext* pctx, Assets* assets) { batch->color = glm::vec4(1.0f); glm::vec2 lcoord = label->calcCoord(); - auto font = assets->getFont(label->getFontName()); int width = font->calcWidth(input.substr(0, caret)); batch->rect(lcoord.x + width, lcoord.y, 2, font->getLineHeight()); } @@ -313,7 +314,7 @@ void TextBox::paste(const std::wstring& text) { auto right = input.substr(caret); input = left + text + right; } - caret += text.length(); + setCaret(caret + text.length()); validate(); } @@ -345,7 +346,7 @@ void TextBox::setOnEditStart(runnable oneditstart) { void TextBox::focus(GUI* gui) { Panel::focus(gui); if (onEditStart){ - caret = input.size(); + setCaret(input.size()); onEditStart(); } } @@ -355,6 +356,21 @@ void TextBox::refresh() { label->setSize(size-glm::vec2(padding.z+padding.x, padding.w+padding.y)); } +void TextBox::clicked(GUI*, int button) { + +} + +void TextBox::mouseMove(GUI*, int x, int y) { + if (font == nullptr) + return; + glm::vec2 lcoord = label->calcCoord(); + uint offset = 0; + while (lcoord.x + font->calcWidth(input, offset) < x && offset <= input.length()) { + offset++; + } + setCaret(offset); +} + void TextBox::keyPressed(int key) { if (key == keycode::BACKSPACE) { if (caret > 0 && input.length() > 0) { @@ -362,7 +378,7 @@ void TextBox::keyPressed(int key) { caret = input.length(); } input = input.substr(0, caret-1) + input.substr(caret); - caret--; + setCaret(caret-1); validate(); } } else if (key == keycode::DELETE) { @@ -378,15 +394,14 @@ void TextBox::keyPressed(int key) { } else if (key == keycode::LEFT) { if (caret > 0) { if (caret > input.length()) { - caret = input.length()-1; + setCaret(input.length()-1); } else { - caret--; + setCaret(caret-1); } - caretLastMove = Window::time(); } } else if (key == keycode::RIGHT) { if (caret < input.length()) { - caret++; + setCaret(caret+1); caretLastMove = Window::time(); } } @@ -455,6 +470,7 @@ uint TextBox::getCaret() const { void TextBox::setCaret(uint position) { this->caret = position; + caretLastMove = Window::time(); } // ============================== InputBindBox ================================ diff --git a/src/frontend/gui/controls.h b/src/frontend/gui/controls.h index ee606d99..92a1a088 100644 --- a/src/frontend/gui/controls.h +++ b/src/frontend/gui/controls.h @@ -15,6 +15,7 @@ class Batch2D; class Assets; +class Font; namespace gui { class Label : public UINode { @@ -111,6 +112,7 @@ namespace gui { /// @brief text input pointer, value may be greather than text length uint caret = 0; double caretLastMove = 0.0; + Font* font = nullptr; void paste(const std::wstring& text); public: @@ -145,6 +147,8 @@ namespace gui { virtual void setOnEditStart(runnable oneditstart); virtual void focus(GUI*) override; virtual void refresh() override; + virtual void clicked(GUI*, int button) override; + virtual void mouseMove(GUI*, int x, int y) override; }; class InputBindBox : public Panel { diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index 27548631..12d4ce87 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -34,8 +34,8 @@ bool Font::isPrintableChar(int c) { const int RES = 16; -int Font::calcWidth(std::wstring text) { - return text.length() * 8; +int Font::calcWidth(std::wstring text, size_t length) { + return std::min(text.length(), length) * 8; } void Font::draw(Batch2D* batch, std::wstring text, int x, int y) { diff --git a/src/graphics/Font.h b/src/graphics/Font.h index d2800b1c..b97436e3 100644 --- a/src/graphics/Font.h +++ b/src/graphics/Font.h @@ -23,7 +23,7 @@ public: int getLineHeight() const; int getYOffset() const; - int calcWidth(std::wstring text); + int calcWidth(std::wstring text, size_t length=-1); // int getGlyphWidth(char c); bool isPrintableChar(int c); void draw(Batch2D* batch, std::wstring text, int x, int y);