TextAreaWidget: Make Tab writable (#175)
* TextAreaWidget: Make Tab writable * Implement Tab ena/disabling, disable it by default * Log change * Rename Tab Enabling function * Add useful Write/Delete functions * Finished! * whoops * Fix everything * whoops * I don't know why but it works * whoops * I'M PUSHING.
This commit is contained in:
parent
beca6e7dd5
commit
d83c12c2d3
|
|
@ -188,6 +188,7 @@ Nazara Development Kit:
|
|||
- Fixed GraphicsComponent copy constructor not copying scissor rect
|
||||
- Force parent parameter to be present in widgets constructor
|
||||
- Added the possibility to write only specific characters with a predicate in TextAreaWidget
|
||||
- Enable write of Tab character in TextAreaWidget
|
||||
- It is now possible to disable object culling in the RenderSystem
|
||||
- Make Nz::PhysWorld2D& Ndk::PhysicsSystem2D::GetWorld private and rename it into GetPhysWorld
|
||||
- Make Ndk::PhysicsSystem2D an interface of Nz::PhysWorld2D
|
||||
|
|
|
|||
|
|
@ -32,8 +32,12 @@ namespace Ndk
|
|||
|
||||
//virtual TextAreaWidget* Clone() const = 0;
|
||||
|
||||
inline void EnableMultiline(bool enable = true);
|
||||
|
||||
inline void EnableMultiline(bool enable = true);
|
||||
inline void EnableTabWriting(bool enable = true);
|
||||
|
||||
inline void Erase(std::size_t glyphPosition);
|
||||
void Erase(std::size_t firstGlyph, std::size_t lastGlyph);
|
||||
void EraseSelection();
|
||||
|
||||
inline CharacterFilter GetCharacterFilter() const;
|
||||
|
|
@ -52,6 +56,7 @@ namespace Ndk
|
|||
|
||||
inline bool IsMultilineEnabled() const;
|
||||
inline bool IsReadOnly() const;
|
||||
inline bool IsTabWritingEnabled() const;
|
||||
|
||||
inline void MoveCursor(int offset);
|
||||
inline void MoveCursor(const Nz::Vector2i& offset);
|
||||
|
|
@ -68,7 +73,9 @@ namespace Ndk
|
|||
inline void SetText(const Nz::String& text);
|
||||
inline void SetTextColor(const Nz::Color& text);
|
||||
|
||||
void Write(const Nz::String& text);
|
||||
inline void Write(const Nz::String& text);
|
||||
inline void Write(const Nz::String& text, const Nz::Vector2ui& glyphPosition);
|
||||
void Write(const Nz::String& text, std::size_t glyphPosition);
|
||||
|
||||
TextAreaWidget& operator=(const TextAreaWidget&) = delete;
|
||||
TextAreaWidget& operator=(TextAreaWidget&&) = default;
|
||||
|
|
@ -115,6 +122,7 @@ namespace Ndk
|
|||
bool m_isMouseButtonDown;
|
||||
bool m_multiLineEnabled;
|
||||
bool m_readOnly;
|
||||
bool m_tabEnabled; // writes (Shift+)Tab character if set to true
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,16 @@ namespace Ndk
|
|||
m_multiLineEnabled = enable;
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::EnableTabWriting(bool enable)
|
||||
{
|
||||
m_tabEnabled = enable;
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::Erase(std::size_t glyphPosition)
|
||||
{
|
||||
Erase(glyphPosition, glyphPosition + 1U);
|
||||
}
|
||||
|
||||
inline TextAreaWidget::CharacterFilter TextAreaWidget::GetCharacterFilter() const
|
||||
{
|
||||
return m_characterFilter;
|
||||
|
|
@ -102,6 +112,11 @@ namespace Ndk
|
|||
return m_multiLineEnabled;
|
||||
}
|
||||
|
||||
inline bool TextAreaWidget::IsTabWritingEnabled() const
|
||||
{
|
||||
return m_tabEnabled;
|
||||
}
|
||||
|
||||
inline bool TextAreaWidget::IsReadOnly() const
|
||||
{
|
||||
return m_readOnly;
|
||||
|
|
@ -233,4 +248,14 @@ namespace Ndk
|
|||
|
||||
m_textSprite->Update(m_drawer);
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::Write(const Nz::String& text)
|
||||
{
|
||||
Write(text, GetGlyphIndex(m_cursorPositionBegin));
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::Write(const Nz::String& text, const Nz::Vector2ui& glyphPosition)
|
||||
{
|
||||
Write(text, GetGlyphIndex(glyphPosition));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ namespace Ndk
|
|||
m_cursorPositionEnd(0U, 0U),
|
||||
m_isMouseButtonDown(false),
|
||||
m_multiLineEnabled(false),
|
||||
m_readOnly(false)
|
||||
m_readOnly(false),
|
||||
m_tabEnabled(false)
|
||||
{
|
||||
m_cursorEntity = CreateEntity(true);
|
||||
m_cursorEntity->AddComponent<GraphicsComponent>();
|
||||
|
|
@ -71,26 +72,41 @@ namespace Ndk
|
|||
OnTextChanged(this, m_text);
|
||||
}
|
||||
|
||||
void TextAreaWidget::Erase(std::size_t firstGlyph, std::size_t lastGlyph)
|
||||
{
|
||||
if (firstGlyph > lastGlyph)
|
||||
std::swap(firstGlyph, lastGlyph);
|
||||
|
||||
std::size_t textLength = m_text.GetLength();
|
||||
if (firstGlyph > textLength)
|
||||
return;
|
||||
|
||||
Nz::String newText;
|
||||
if (firstGlyph > 0)
|
||||
{
|
||||
std::size_t characterPosition = m_text.GetCharacterPosition(firstGlyph - 1);
|
||||
NazaraAssert(characterPosition != Nz::String::npos, "Invalid character position");
|
||||
|
||||
newText.Append(m_text.SubString(0, characterPosition));
|
||||
}
|
||||
|
||||
if (lastGlyph < textLength)
|
||||
{
|
||||
std::size_t characterPosition = m_text.GetCharacterPosition(lastGlyph);
|
||||
NazaraAssert(characterPosition != Nz::String::npos, "Invalid character position");
|
||||
|
||||
newText.Append(m_text.SubString(characterPosition));
|
||||
}
|
||||
|
||||
SetText(newText);
|
||||
}
|
||||
|
||||
void TextAreaWidget::EraseSelection()
|
||||
{
|
||||
if (!HasSelection())
|
||||
return;
|
||||
|
||||
std::size_t cursorGlyphBegin = GetGlyphIndex(m_cursorPositionBegin);
|
||||
std::size_t cursorGlyphEnd = GetGlyphIndex(m_cursorPositionEnd);
|
||||
|
||||
std::size_t textLength = m_text.GetLength();
|
||||
if (cursorGlyphBegin > textLength)
|
||||
return;
|
||||
|
||||
Nz::String newText;
|
||||
if (cursorGlyphBegin > 0)
|
||||
newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyphBegin) - 1));
|
||||
|
||||
if (cursorGlyphEnd < textLength)
|
||||
newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyphEnd)));
|
||||
|
||||
SetText(newText);
|
||||
Erase(GetGlyphIndex(m_cursorPositionBegin), GetGlyphIndex(m_cursorPositionEnd));
|
||||
}
|
||||
|
||||
Nz::Vector2ui TextAreaWidget::GetHoveredGlyph(float x, float y) const
|
||||
|
|
@ -129,21 +145,19 @@ namespace Ndk
|
|||
SetContentSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths()));
|
||||
}
|
||||
|
||||
void TextAreaWidget::Write(const Nz::String& text)
|
||||
void TextAreaWidget::Write(const Nz::String& text, std::size_t glyphPosition)
|
||||
{
|
||||
std::size_t cursorGlyph = GetGlyphIndex(m_cursorPositionBegin);
|
||||
|
||||
if (cursorGlyph >= m_drawer.GetGlyphCount())
|
||||
if (glyphPosition >= m_drawer.GetGlyphCount())
|
||||
{
|
||||
AppendText(text);
|
||||
SetCursorPosition(m_drawer.GetGlyphCount());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_text.Insert(m_text.GetCharacterPosition(cursorGlyph), text);
|
||||
m_text.Insert(m_text.GetCharacterPosition(glyphPosition), text);
|
||||
SetText(m_text);
|
||||
|
||||
SetCursorPosition(cursorGlyph + text.GetLength());
|
||||
SetCursorPosition(glyphPosition + text.GetLength());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,23 +195,7 @@ namespace Ndk
|
|||
if (HasSelection())
|
||||
EraseSelection();
|
||||
else
|
||||
{
|
||||
std::size_t cursorGlyphBegin = GetGlyphIndex(m_cursorPositionBegin);
|
||||
std::size_t cursorGlyphEnd = GetGlyphIndex(m_cursorPositionEnd);
|
||||
|
||||
std::size_t textLength = m_text.GetLength();
|
||||
if (cursorGlyphBegin > textLength)
|
||||
return true;
|
||||
|
||||
Nz::String newText;
|
||||
if (cursorGlyphBegin > 0)
|
||||
newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyphBegin) - 1));
|
||||
|
||||
if (cursorGlyphEnd < textLength)
|
||||
newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyphEnd + 1)));
|
||||
|
||||
SetText(newText);
|
||||
}
|
||||
Erase(GetGlyphIndex(m_cursorPositionBegin));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -338,6 +336,58 @@ namespace Ndk
|
|||
return true;
|
||||
}
|
||||
|
||||
case Nz::Keyboard::Tab:
|
||||
{
|
||||
if (!m_tabEnabled)
|
||||
return false;
|
||||
|
||||
if (HasSelection())
|
||||
{
|
||||
for(unsigned line = m_cursorPositionBegin.y; line <= m_cursorPositionEnd.y; ++line)
|
||||
{
|
||||
const Nz::Vector2ui cursorPositionBegin = m_cursorPositionBegin;
|
||||
const Nz::Vector2ui cursorPositionEnd = m_cursorPositionEnd;
|
||||
|
||||
if (key.shift)
|
||||
{
|
||||
if (m_drawer.GetLineGlyphCount(line) == 0)
|
||||
continue;
|
||||
|
||||
std::size_t firstGlyph = GetGlyphIndex({ 0U, line });
|
||||
|
||||
if (m_text[m_text.GetCharacterPosition(firstGlyph)] == '\t')
|
||||
{
|
||||
Erase(firstGlyph);
|
||||
SetSelection(cursorPositionBegin - (cursorPositionBegin.y == line && cursorPositionBegin.x != 0U ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {}),
|
||||
cursorPositionEnd - (cursorPositionEnd.y == line && cursorPositionEnd.x != 0U ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {}));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(Nz::String('\t'), { 0U, line });
|
||||
SetSelection(cursorPositionBegin + (cursorPositionBegin.y == line && cursorPositionBegin.x != 0U ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {}),
|
||||
cursorPositionEnd + (cursorPositionEnd.y == line ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (key.shift)
|
||||
{
|
||||
std::size_t currentGlyph = GetGlyphIndex(m_cursorPositionBegin);
|
||||
|
||||
if (currentGlyph > 0 && m_text[m_text.GetCharacterPosition(currentGlyph - 1U)] == '\t') // Check if previous glyph is a tab
|
||||
{
|
||||
Erase(currentGlyph - 1U);
|
||||
|
||||
if (m_cursorPositionBegin.x < static_cast<unsigned int>(m_drawer.GetLineGlyphCount(m_cursorPositionBegin.y)))
|
||||
MoveCursor(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
Write(Nz::String('\t'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -438,6 +488,9 @@ namespace Ndk
|
|||
if (ignoreDefaultAction || !m_multiLineEnabled)
|
||||
break;
|
||||
|
||||
if (HasSelection())
|
||||
EraseSelection();
|
||||
|
||||
Write(Nz::String('\n'));
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue