Widgets/TextAreaWidget: Add a way to limit text length
This commit is contained in:
parent
f10671ac2a
commit
c931e9a509
|
|
@ -42,6 +42,7 @@ namespace Nz
|
|||
inline EchoMode GetEchoMode() const;
|
||||
inline std::size_t GetGlyphIndex() const;
|
||||
inline std::size_t GetGlyphIndex(const Vector2ui& cursorPosition) const;
|
||||
inline std::size_t GetMaximumTextLength() const;
|
||||
|
||||
Vector2ui GetHoveredGlyph(float x, float y) const;
|
||||
|
||||
|
|
@ -61,6 +62,7 @@ namespace Nz
|
|||
inline void SetCursorPosition(std::size_t glyphIndex);
|
||||
inline void SetCursorPosition(Vector2ui cursorPosition);
|
||||
inline void SetEchoMode(EchoMode echoMode);
|
||||
virtual void SetMaximumTextLength(std::size_t maximumLength) = 0;
|
||||
inline void SetReadOnly(bool readOnly = true);
|
||||
inline void SetSelection(Vector2ui fromPosition, Vector2ui toPosition);
|
||||
|
||||
|
|
@ -131,6 +133,7 @@ namespace Nz
|
|||
};
|
||||
|
||||
std::shared_ptr<TextSprite> m_textSprite;
|
||||
std::size_t m_maximumTextLength;
|
||||
std::vector<Cursor> m_cursors;
|
||||
CharacterFilter m_characterFilter;
|
||||
EchoMode m_echoMode;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,11 @@ namespace Nz
|
|||
return glyphIndex;
|
||||
}
|
||||
|
||||
inline std::size_t AbstractTextAreaWidget::GetMaximumTextLength() const
|
||||
{
|
||||
return m_maximumTextLength;
|
||||
}
|
||||
|
||||
inline bool AbstractTextAreaWidget::HasSelection() const
|
||||
{
|
||||
return m_cursorPositionBegin != m_cursorPositionEnd;
|
||||
|
|
@ -257,3 +262,4 @@ namespace Nz
|
|||
}
|
||||
|
||||
#include <Nazara/Widgets/DebugOff.hpp>
|
||||
#include "AbstractTextAreaWidget.hpp"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ namespace Nz
|
|||
inline void SetCharacterSize(unsigned int characterSize);
|
||||
inline void SetCharacterSpacingOffset(float offset);
|
||||
inline void SetLineSpacingOffset(float offset);
|
||||
void SetMaximumTextLength(std::size_t maximumLength) override;
|
||||
inline void SetTextColor(const Color& color);
|
||||
inline void SetTextFont(std::shared_ptr<Font> font);
|
||||
inline void SetTextOutlineColor(const Color& color);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ namespace Nz
|
|||
inline void SetCharacterSize(unsigned int characterSize);
|
||||
inline void SetCharacterSpacingOffset(float offset);
|
||||
inline void SetLineSpacingOffset(float offset);
|
||||
void SetMaximumTextLength(std::size_t maximumLength) override;
|
||||
inline void SetText(std::string text);
|
||||
inline void SetTextColor(const Color& text);
|
||||
inline void SetTextFont(std::shared_ptr<Font> font);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Nz
|
|||
|
||||
AbstractTextAreaWidget::AbstractTextAreaWidget(BaseWidget* parent) :
|
||||
BaseWidget(parent),
|
||||
m_characterFilter(),
|
||||
m_maximumTextLength(0),
|
||||
m_echoMode(EchoMode::Normal),
|
||||
m_cursorPositionBegin(0U, 0U),
|
||||
m_cursorPositionEnd(0U, 0U),
|
||||
|
|
@ -120,6 +120,11 @@ namespace Nz
|
|||
return Vector2ui::Zero();
|
||||
}
|
||||
|
||||
void AbstractTextAreaWidget::SetMaximumTextLength(std::size_t maximumLength)
|
||||
{
|
||||
m_maximumTextLength = maximumLength;
|
||||
}
|
||||
|
||||
Color AbstractTextAreaWidget::GetCursorColor() const
|
||||
{
|
||||
if (m_cursorPositionBegin == m_cursorPositionEnd)
|
||||
|
|
|
|||
|
|
@ -132,22 +132,66 @@ namespace Nz
|
|||
UpdateDisplayText();
|
||||
}
|
||||
|
||||
void RichTextAreaWidget::SetMaximumTextLength(std::size_t maximumLength)
|
||||
{
|
||||
AbstractTextAreaWidget::SetMaximumTextLength(maximumLength);
|
||||
|
||||
if (m_maximumTextLength > 0 && m_drawer.HasBlocks())
|
||||
{
|
||||
std::size_t blockIndex = m_drawer.FindBlock(m_maximumTextLength);
|
||||
|
||||
auto blockRef = m_drawer.GetBlock(blockIndex);
|
||||
const std::string& blockText = blockRef.GetText();
|
||||
|
||||
assert(m_maximumTextLength >= blockRef.GetFirstGlyphIndex());
|
||||
std::size_t maxBlockSize = m_maximumTextLength - blockRef.GetFirstGlyphIndex();
|
||||
std::size_t textLength = ComputeCharacterCount(blockText);
|
||||
if (textLength > maxBlockSize)
|
||||
{
|
||||
blockRef.SetText(std::string(TrimRightCount(blockText, textLength - maxBlockSize, Nz::UnicodeAware{})));
|
||||
|
||||
// And then remove all blocks after the limit (in reverse order because of index shifting)
|
||||
std::size_t lastBlockIndex = m_drawer.GetBlockCount();
|
||||
assert(lastBlockIndex > 0);
|
||||
for (std::size_t i = lastBlockIndex - 1; i > blockIndex; --i)
|
||||
m_drawer.RemoveBlock(i);
|
||||
|
||||
UpdateDisplayText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RichTextAreaWidget::Write(std::string_view text, std::size_t glyphPosition)
|
||||
{
|
||||
if (m_drawer.HasBlocks())
|
||||
{
|
||||
auto block = m_drawer.GetBlock(m_drawer.FindBlock((glyphPosition > 0) ? glyphPosition - 1 : glyphPosition));
|
||||
std::size_t firstGlyph = block.GetFirstGlyphIndex();
|
||||
if (m_maximumTextLength > 0)
|
||||
{
|
||||
auto lastBlockRef = m_drawer.GetBlock(m_drawer.GetBlockCount() - 1);
|
||||
std::size_t currentLength = lastBlockRef.GetFirstGlyphIndex() + ComputeCharacterCount(lastBlockRef.GetText());
|
||||
if (m_maximumTextLength <= currentLength)
|
||||
return;
|
||||
|
||||
text = Substring(text, 0, m_maximumTextLength - currentLength, UnicodeAware{});
|
||||
}
|
||||
|
||||
auto blockRef = m_drawer.GetBlock(m_drawer.FindBlock((glyphPosition > 0) ? glyphPosition - 1 : glyphPosition));
|
||||
std::size_t firstGlyph = blockRef.GetFirstGlyphIndex();
|
||||
assert(glyphPosition >= firstGlyph);
|
||||
|
||||
std::string blockText = block.GetText();
|
||||
std::string blockText = blockRef.GetText();
|
||||
std::size_t characterPosition = GetCharacterPosition(blockText, glyphPosition - firstGlyph);
|
||||
blockText.insert(characterPosition, text);
|
||||
|
||||
block.SetText(blockText);
|
||||
blockRef.SetText(blockText);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_maximumTextLength > 0)
|
||||
text = Substring(text, 0, m_maximumTextLength, UnicodeAware{});
|
||||
|
||||
m_drawer.AppendText(text);
|
||||
}
|
||||
|
||||
SetCursorPosition(glyphPosition + ComputeCharacterCount(text));
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,15 @@ namespace Nz
|
|||
|
||||
void TextAreaWidget::AppendText(std::string_view text)
|
||||
{
|
||||
if (m_maximumTextLength > 0)
|
||||
{
|
||||
std::size_t currentLength = ComputeCharacterCount(m_text);
|
||||
if (m_maximumTextLength <= currentLength)
|
||||
return;
|
||||
|
||||
text = Substring(text, 0, m_maximumTextLength - currentLength, UnicodeAware{});
|
||||
}
|
||||
|
||||
m_text += text;
|
||||
|
||||
switch (m_echoMode)
|
||||
|
|
@ -113,6 +122,14 @@ namespace Nz
|
|||
SetText(newText);
|
||||
}
|
||||
|
||||
void TextAreaWidget::SetMaximumTextLength(std::size_t maximumLength)
|
||||
{
|
||||
AbstractTextAreaWidget::SetMaximumTextLength(maximumLength);
|
||||
|
||||
if (m_maximumTextLength > 0 && ComputeCharacterCount(m_text) > m_maximumTextLength)
|
||||
SetText(std::string(Substring(m_text, 0, m_maximumTextLength, UnicodeAware{})));
|
||||
}
|
||||
|
||||
void TextAreaWidget::Write(std::string_view text, std::size_t glyphPosition)
|
||||
{
|
||||
if (glyphPosition >= m_drawer.GetGlyphCount())
|
||||
|
|
@ -123,6 +140,15 @@ namespace Nz
|
|||
}
|
||||
else
|
||||
{
|
||||
if (m_maximumTextLength > 0)
|
||||
{
|
||||
std::size_t currentLength = ComputeCharacterCount(m_text);
|
||||
if (m_maximumTextLength <= currentLength)
|
||||
return;
|
||||
|
||||
text = Substring(text, 0, m_maximumTextLength - currentLength, UnicodeAware{});
|
||||
}
|
||||
|
||||
m_text.insert(GetCharacterPosition(m_text, glyphPosition), text);
|
||||
SetText(m_text);
|
||||
|
||||
|
|
@ -284,10 +310,7 @@ namespace Nz
|
|||
if (clipboardString.empty())
|
||||
return;
|
||||
|
||||
m_text.insert(targetIndex, clipboardString);
|
||||
UpdateDisplayText();
|
||||
|
||||
SetCursorPosition(targetIndex + ComputeCharacterCount(clipboardString));
|
||||
Write(clipboardString, targetIndex);
|
||||
}
|
||||
|
||||
void TextAreaWidget::UpdateDisplayText()
|
||||
|
|
|
|||
Loading…
Reference in New Issue