diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index 2ffa46b9b..ec0576453 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -34,7 +34,7 @@ namespace Ndk inline const Nz::Vector2ui& GetCursorPosition() const; inline const Nz::String& GetDisplayText() const; inline EchoMode GetEchoMode() const; - inline std::size_t GetGlyphUnderCursor() const; + inline std::size_t GetGlyphIndex(const Nz::Vector2ui& cursorPosition); inline const Nz::String& GetText() const; inline const Nz::Color& GetTextColor() const; @@ -92,7 +92,6 @@ namespace Ndk Nz::String m_text; Nz::TextSpriteRef m_textSprite; Nz::Vector2ui m_cursorPosition; - std::size_t m_cursorGlyph; bool m_multiLineEnabled; bool m_readOnly; }; diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index e0445316f..100c61b6e 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -30,21 +30,27 @@ namespace Ndk return m_cursorPosition; } - inline const Nz::String & TextAreaWidget::GetDisplayText() const + inline const Nz::String& TextAreaWidget::GetDisplayText() const { return m_drawer.GetText(); } + inline std::size_t TextAreaWidget::GetGlyphIndex(const Nz::Vector2ui& cursorPosition) + { + std::size_t glyphIndex = m_drawer.GetLine(cursorPosition.y).glyphIndex + cursorPosition.x; + if (m_drawer.GetLineCount() > cursorPosition.y + 1) + glyphIndex = std::min(glyphIndex, m_drawer.GetLine(cursorPosition.y + 1).glyphIndex - 1); + else + glyphIndex = std::min(glyphIndex, m_drawer.GetGlyphCount()); + + return glyphIndex; + } + inline EchoMode TextAreaWidget::GetEchoMode() const { return m_echoMode; } - inline std::size_t Ndk::TextAreaWidget::GetGlyphUnderCursor() const - { - return m_cursorGlyph; - } - inline const Nz::String& TextAreaWidget::GetText() const { return m_text; @@ -67,21 +73,22 @@ namespace Ndk inline void TextAreaWidget::MoveCursor(int offset) { + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); if (offset >= 0) - SetCursorPosition(m_cursorGlyph + static_cast(offset)); + SetCursorPosition(cursorGlyph + static_cast(offset)); else { std::size_t nOffset = static_cast(-offset); - if (nOffset >= m_cursorGlyph) + if (nOffset >= cursorGlyph) SetCursorPosition(0); else - SetCursorPosition(m_cursorGlyph - nOffset); + SetCursorPosition(cursorGlyph - nOffset); } } inline void TextAreaWidget::MoveCursor(const Nz::Vector2i& offset) { - auto BoundOffset = [] (unsigned int cursorPosition, int cursorOffset) -> unsigned int + auto ClampOffset = [] (unsigned int cursorPosition, int cursorOffset) -> unsigned int { if (cursorOffset >= 0) return cursorPosition + cursorOffset; @@ -96,8 +103,8 @@ namespace Ndk }; Nz::Vector2ui cursorPosition = m_cursorPosition; - cursorPosition.x = BoundOffset(static_cast(cursorPosition.x), offset.x); - cursorPosition.y = BoundOffset(static_cast(cursorPosition.y), offset.y); + cursorPosition.x = ClampOffset(static_cast(cursorPosition.x), offset.x); + cursorPosition.y = ClampOffset(static_cast(cursorPosition.y), offset.y); SetCursorPosition(cursorPosition); } @@ -111,13 +118,13 @@ namespace Ndk { OnTextAreaCursorMove(this, &glyphIndex); - m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount()); - + glyphIndex = std::min(glyphIndex, m_drawer.GetGlyphCount()); + std::size_t lineCount = m_drawer.GetLineCount(); std::size_t line = 0U; for (std::size_t i = line + 1; i < lineCount; ++i) { - if (m_drawer.GetLine(i).glyphIndex > m_cursorGlyph) + if (m_drawer.GetLine(i).glyphIndex > glyphIndex) break; line = i; @@ -126,7 +133,7 @@ namespace Ndk const auto& lineInfo = m_drawer.GetLine(line); m_cursorPosition.y = static_cast(line); - m_cursorPosition.x = static_cast(m_cursorGlyph - lineInfo.glyphIndex); + m_cursorPosition.x = static_cast(glyphIndex - lineInfo.glyphIndex); RefreshCursor(); } @@ -150,8 +157,6 @@ namespace Ndk OnTextAreaCursorMove(this, &glyphIndex); - m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount()); - RefreshCursor(); } diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 0d316a452..6e38fb655 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -13,7 +13,6 @@ namespace Ndk BaseWidget(parent), m_echoMode(EchoMode_Normal), m_cursorPosition(0U, 0U), - m_cursorGlyph(0), m_multiLineEnabled(false), m_readOnly(false) { @@ -110,17 +109,19 @@ namespace Ndk void TextAreaWidget::Write(const Nz::String& text) { - if (m_cursorGlyph >= m_drawer.GetGlyphCount()) + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); + + if (cursorGlyph >= m_drawer.GetGlyphCount()) { AppendText(text); SetCursorPosition(m_drawer.GetGlyphCount()); } else { - m_text.Insert(m_text.GetCharacterPosition(m_cursorGlyph), text); + m_text.Insert(m_text.GetCharacterPosition(cursorGlyph), text); SetText(m_text); - SetCursorPosition(m_cursorGlyph + text.GetLength()); + SetCursorPosition(cursorGlyph + text.GetLength()); } } @@ -139,16 +140,18 @@ namespace Ndk { case Nz::Keyboard::Delete: { + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); + std::size_t textLength = m_text.GetLength(); - if (m_cursorGlyph > textLength) + if (cursorGlyph > textLength) break; Nz::String newText; - if (m_cursorGlyph > 0) - newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(m_cursorGlyph) - 1)); + if (cursorGlyph > 0) + newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyph) - 1)); - if (m_cursorGlyph < textLength) - newText.Append(m_text.SubString(m_text.GetCharacterPosition(m_cursorGlyph + 1))); + if (cursorGlyph < textLength) + newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyph + 1))); SetText(newText); break; @@ -247,18 +250,19 @@ namespace Ndk bool ignoreDefaultAction = false; OnTextAreaKeyBackspace(this, &ignoreDefaultAction); - if (ignoreDefaultAction || m_cursorGlyph == 0) + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); + if (ignoreDefaultAction || cursorGlyph == 0) break; Nz::String newText; - if (m_cursorGlyph > 1) - newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(m_cursorGlyph - 1) - 1)); + if (cursorGlyph > 1) + newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyph - 1) - 1)); - if (m_cursorGlyph < m_text.GetLength()) - newText.Append(m_text.SubString(m_text.GetCharacterPosition(m_cursorGlyph))); + if (cursorGlyph < m_text.GetLength()) + newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyph))); - MoveCursor({-1, 0}); + MoveCursor(-1); SetText(newText); break; } @@ -290,14 +294,15 @@ namespace Ndk void TextAreaWidget::RefreshCursor() { const auto& lineInfo = m_drawer.GetLine(m_cursorPosition.y); + std::size_t cursorGlyph = GetGlyphIndex(m_cursorPosition); std::size_t glyphCount = m_drawer.GetGlyphCount(); float position; - if (glyphCount > 0 && lineInfo.glyphIndex < m_cursorGlyph) + if (glyphCount > 0 && lineInfo.glyphIndex < cursorGlyph) { - const auto& glyph = m_drawer.GetGlyph(std::min(m_cursorGlyph, glyphCount - 1)); + const auto& glyph = m_drawer.GetGlyph(std::min(cursorGlyph, glyphCount - 1)); position = glyph.bounds.x; - if (m_cursorGlyph >= glyphCount) + if (cursorGlyph >= glyphCount) position += glyph.bounds.width; } else