From 4ec3dba221eef6ba25c370d20750aec921a25808 Mon Sep 17 00:00:00 2001 From: CasualYT31 <21147925+CasualYT31@users.noreply.github.com> Date: Wed, 30 Aug 2023 14:48:51 +0100 Subject: [PATCH 1/3] Add onCaretPositionChange signal to EditBox --- include/TGUI/Widgets/EditBox.hpp | 15 +++++++++--- src/Widgets/EditBox.cpp | 42 ++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/include/TGUI/Widgets/EditBox.hpp b/include/TGUI/Widgets/EditBox.hpp index 8cd0dda6d..8d1568736 100644 --- a/include/TGUI/Widgets/EditBox.hpp +++ b/include/TGUI/Widgets/EditBox.hpp @@ -543,6 +543,13 @@ TGUI_MODULE_EXPORT namespace tgui TGUI_NODISCARD Widget::Ptr clone() const override; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Updates m_selEnd with a new value and emits the onCaretPositionChange signal + // @param newValue the value to assign to m_selEnd. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void updateSelEnd(const std::size_t newValue); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private: @@ -595,10 +602,10 @@ TGUI_MODULE_EXPORT namespace tgui ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public: - SignalString onTextChange = {"TextChanged"}; //!< The text was changed. Optional parameter: new text - SignalString onReturnKeyPress = {"ReturnKeyPressed"}; //!< The return key was pressed. Optional parameter: text in the edit box - SignalString onReturnOrUnfocus = {"ReturnOrUnfocused"}; //!< The return key was pressed or the edit box was unfocused. Optional parameter: text in the edit box - + SignalString onTextChange = {"TextChanged"}; //!< The text was changed. Optional parameter: new text + SignalString onReturnKeyPress = {"ReturnKeyPressed"}; //!< The return key was pressed. Optional parameter: text in the edit box + SignalString onReturnOrUnfocus = {"ReturnOrUnfocused"}; //!< The return key was pressed or the edit box was unfocused. Optional parameter: text in the edit box + SignalTyped onCaretPositionChange = {"CaretPositionChanged"}; //!< The caret's position was changed. Optional parameter: new caret position ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected: diff --git a/src/Widgets/EditBox.cpp b/src/Widgets/EditBox.cpp index b9434913b..4c6b60dc0 100644 --- a/src/Widgets/EditBox.cpp +++ b/src/Widgets/EditBox.cpp @@ -187,7 +187,7 @@ namespace tgui void EditBox::selectText(std::size_t start, std::size_t length) { m_selStart = start; - m_selEnd = std::min(m_text.length(), start + length); + updateSelEnd(std::min(m_text.length(), start + length)); updateSelection(); } @@ -334,7 +334,7 @@ namespace tgui // Set the caret to the correct position m_selStart = charactersBeforeCaret; - m_selEnd = charactersBeforeCaret; + updateSelEnd(charactersBeforeCaret); updateSelection(); } @@ -460,7 +460,7 @@ namespace tgui // Select the whole text m_selStart = 0; - m_selEnd = m_text.length(); + updateSelEnd(m_text.length()); updateSelection(); } else // No double clicking @@ -501,7 +501,7 @@ namespace tgui if (m_limitTextWidth) { // Find out between which characters the mouse is standing - m_selEnd = findCaretPosition(pos.x - m_bordersCached.getLeft() - m_paddingCached.getLeft()); + updateSelEnd(findCaretPosition(pos.x - m_bordersCached.getLeft() - m_paddingCached.getLeft())); } else // Scrolling is enabled { @@ -545,7 +545,7 @@ namespace tgui } // Find out between which characters the mouse is standing - m_selEnd = findCaretPosition(pos.x - m_bordersCached.getLeft() - m_paddingCached.getLeft()); + updateSelEnd(findCaretPosition(pos.x - m_bordersCached.getLeft() - m_paddingCached.getLeft())); } if (m_selEnd != oldSelEnd) @@ -587,10 +587,10 @@ namespace tgui moveCaretWordEnd(); else if (keyboard::isKeyPressMoveCaretLineStart(event) || keyboard::isKeyPressMoveCaretUp(event) || keyboard::isKeyPressMoveCaretDocumentBegin(event) || (event.code == Event::KeyboardKey::PageUp)) - m_selEnd = 0; + updateSelEnd(0); else if (keyboard::isKeyPressMoveCaretLineEnd(event) || keyboard::isKeyPressMoveCaretDown(event) || keyboard::isKeyPressMoveCaretDocumentEnd(event) || (event.code == Event::KeyboardKey::PageDown)) - m_selEnd = m_text.length(); + updateSelEnd(m_text.length()); else caretMoved = false; @@ -686,6 +686,8 @@ namespace tgui return onReturnKeyPress; else if (signalName == onReturnOrUnfocus.getName()) return onReturnOrUnfocus; + else if (signalName == onCaretPositionChange.getName()) + return onCaretPositionChange; else return ClickableWidget::getSignal(std::move(signalName)); } @@ -1421,9 +1423,9 @@ namespace tgui { // If text is selected then move to the cursor to the left side of the selected text if ((m_selChars > 0) && !shiftPressed) - m_selEnd = std::min(m_selStart, m_selEnd); + updateSelEnd(std::min(m_selStart, m_selEnd)); else if (m_selEnd > 0) - m_selEnd--; + updateSelEnd(m_selEnd - 1); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1432,9 +1434,9 @@ namespace tgui { // If text is selected then move to the cursor to the right side of the selected text if ((m_selChars > 0) && !shiftPressed) - m_selEnd = std::max(m_selStart, m_selEnd); + updateSelEnd(std::max(m_selStart, m_selEnd)); else if (m_selEnd < m_text.length()) - m_selEnd++; + updateSelEnd(m_selEnd + 1); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1450,7 +1452,7 @@ namespace tgui { if (isWhitespace(m_text[i-1])) { - m_selEnd = i; + updateSelEnd(i); done = true; break; } @@ -1463,7 +1465,7 @@ namespace tgui } if (!done && skippedWhitespace) - m_selEnd = 0; + updateSelEnd(0); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1479,7 +1481,7 @@ namespace tgui { if (isWhitespace(m_text[i])) { - m_selEnd = i; + updateSelEnd(i); done = true; break; } @@ -1492,7 +1494,17 @@ namespace tgui } if (!done && skippedWhitespace) - m_selEnd = m_text.length(); + updateSelEnd(m_text.length()); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + void EditBox::updateSelEnd(const std::size_t newValue) + { + const bool emit = newValue != m_selEnd; + m_selEnd = newValue; + if (emit) + onCaretPositionChange.emit(this, m_selEnd); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From 9574f126967cb4ce40b656208dd42faa010b7591 Mon Sep 17 00:00:00 2001 From: CasualYT31 <21147925+CasualYT31@users.noreply.github.com> Date: Thu, 31 Aug 2023 00:47:30 +0100 Subject: [PATCH 2/3] Add additional guards to EditBox::selectText() * You could cause a crash/exception by issuing a start value that was greater than the text size. start is now capped at the text length. * Issuing just the start parameter would cause an overflow when added to length, meaning the default length value (npos) would not always represent "end of the text." Now, if length is npos, it will always mean "end of the text." --- src/Widgets/EditBox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Widgets/EditBox.cpp b/src/Widgets/EditBox.cpp index 4c6b60dc0..ab066a542 100644 --- a/src/Widgets/EditBox.cpp +++ b/src/Widgets/EditBox.cpp @@ -186,8 +186,8 @@ namespace tgui void EditBox::selectText(std::size_t start, std::size_t length) { - m_selStart = start; - updateSelEnd(std::min(m_text.length(), start + length)); + m_selStart = std::min(m_text.length(), start); + updateSelEnd(length == String::npos ? m_text.length() : std::min(m_text.length(), start + length)); updateSelection(); } From 2282280405805856f03dc8b0c95148313fb06154 Mon Sep 17 00:00:00 2001 From: CasualYT31 <21147925+CasualYT31@users.noreply.github.com> Date: Thu, 31 Aug 2023 16:54:16 +0100 Subject: [PATCH 3/3] Add extra blank line to match style guides --- include/TGUI/Widgets/EditBox.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/TGUI/Widgets/EditBox.hpp b/include/TGUI/Widgets/EditBox.hpp index 8d1568736..2dbe0f6fa 100644 --- a/include/TGUI/Widgets/EditBox.hpp +++ b/include/TGUI/Widgets/EditBox.hpp @@ -607,6 +607,7 @@ TGUI_MODULE_EXPORT namespace tgui SignalString onReturnOrUnfocus = {"ReturnOrUnfocused"}; //!< The return key was pressed or the edit box was unfocused. Optional parameter: text in the edit box SignalTyped onCaretPositionChange = {"CaretPositionChanged"}; //!< The caret's position was changed. Optional parameter: new caret position + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected: