Sdk/TextAreaWidget: Add support for EchoMode

This commit is contained in:
Jérôme Leclercq 2017-11-10 13:12:04 +01:00
parent 4a238f825a
commit bb6e032b60
5 changed files with 112 additions and 34 deletions

View File

@ -16,6 +16,7 @@ Nazara Development Kit:
- ⚠️ Removed TextAreaWidget::GetLineCount - ⚠️ Removed TextAreaWidget::GetLineCount
- Fix World movement which could cause crashes when updating systems - Fix World movement which could cause crashes when updating systems
- Fix crash occuring sometimes on keyboard event - Fix crash occuring sometimes on keyboard event
- Add support for EchoMode to TextAreaWidget (which allows to setup password text area)
# 0.4: # 0.4:

View File

@ -17,6 +17,15 @@ namespace Ndk
CheckboxState_Max = CheckboxState_Unchecked CheckboxState_Max = CheckboxState_Unchecked
}; };
enum EchoMode
{
EchoMode_Normal,
EchoMode_Password,
EchoMode_PasswordExceptLast,
EchoMode_Max = EchoMode_PasswordExceptLast
};
} }
#endif // NAZARA_ENUMS_SDK_HPP #endif // NAZARA_ENUMS_SDK_HPP

View File

@ -7,10 +7,10 @@
#ifndef NDK_WIDGETS_TEXTAREAWIDGET_HPP #ifndef NDK_WIDGETS_TEXTAREAWIDGET_HPP
#define NDK_WIDGETS_TEXTAREAWIDGET_HPP #define NDK_WIDGETS_TEXTAREAWIDGET_HPP
#include <NDK/Prerequesites.hpp>
#include <NDK/BaseWidget.hpp>
#include <Nazara/Utility/SimpleTextDrawer.hpp>
#include <Nazara/Graphics/TextSprite.hpp> #include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Utility/SimpleTextDrawer.hpp>
#include <NDK/BaseWidget.hpp>
#include <NDK/Widgets/Enums.hpp>
namespace Ndk namespace Ndk
{ {
@ -30,9 +30,11 @@ namespace Ndk
inline void EnableMultiline(bool enable = true); inline void EnableMultiline(bool enable = true);
inline unsigned int GetCharacterSize() const;
inline const Nz::Vector2ui& GetCursorPosition() const; 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 GetGlyphUnderCursor() const;
inline std::size_t GetLineCount() const;
inline const Nz::String& GetText() const; inline const Nz::String& GetText() const;
inline const Nz::Color& GetTextColor() const; inline const Nz::Color& GetTextColor() const;
@ -46,8 +48,10 @@ namespace Ndk
void ResizeToContent() override; void ResizeToContent() override;
inline void SetCharacterSize(unsigned int characterSize);
inline void SetCursorPosition(std::size_t glyphIndex); inline void SetCursorPosition(std::size_t glyphIndex);
inline void SetCursorPosition(Nz::Vector2ui cursorPosition); inline void SetCursorPosition(Nz::Vector2ui cursorPosition);
inline void SetEchoMode(EchoMode echoMode);
inline void SetReadOnly(bool readOnly = true); inline void SetReadOnly(bool readOnly = true);
inline void SetText(const Nz::String& text); inline void SetText(const Nz::String& text);
inline void SetTextColor(const Nz::Color& text); inline void SetTextColor(const Nz::Color& text);
@ -77,11 +81,14 @@ namespace Ndk
void OnTextEntered(char32_t character, bool repeated) override; void OnTextEntered(char32_t character, bool repeated) override;
void RefreshCursor(); void RefreshCursor();
void UpdateDisplayText();
EchoMode m_echoMode;
EntityHandle m_cursorEntity; EntityHandle m_cursorEntity;
EntityHandle m_textEntity; EntityHandle m_textEntity;
Nz::SimpleTextDrawer m_drawer; Nz::SimpleTextDrawer m_drawer;
Nz::SpriteRef m_cursorSprite; Nz::SpriteRef m_cursorSprite;
Nz::String m_text;
Nz::TextSpriteRef m_textSprite; Nz::TextSpriteRef m_textSprite;
Nz::Vector2ui m_cursorPosition; Nz::Vector2ui m_cursorPosition;
std::size_t m_cursorGlyph; std::size_t m_cursorGlyph;

View File

@ -20,24 +20,34 @@ namespace Ndk
m_multiLineEnabled = enable; m_multiLineEnabled = enable;
} }
inline unsigned int TextAreaWidget::GetCharacterSize() const
{
return m_drawer.GetCharacterSize();
}
inline const Nz::Vector2ui& TextAreaWidget::GetCursorPosition() const inline const Nz::Vector2ui& TextAreaWidget::GetCursorPosition() const
{ {
return m_cursorPosition; return m_cursorPosition;
} }
inline const Nz::String & TextAreaWidget::GetDisplayText() const
{
return m_drawer.GetText();
}
inline EchoMode TextAreaWidget::GetEchoMode() const
{
return m_echoMode;
}
inline std::size_t Ndk::TextAreaWidget::GetGlyphUnderCursor() const inline std::size_t Ndk::TextAreaWidget::GetGlyphUnderCursor() const
{ {
return m_cursorGlyph; return m_cursorGlyph;
} }
inline std::size_t TextAreaWidget::GetLineCount() const
{
return m_drawer.GetLineCount();
}
inline const Nz::String& TextAreaWidget::GetText() const inline const Nz::String& TextAreaWidget::GetText() const
{ {
return m_drawer.GetText(); return m_text;
} }
inline const Nz::Color& TextAreaWidget::GetTextColor() const inline const Nz::Color& TextAreaWidget::GetTextColor() const
@ -92,12 +102,17 @@ namespace Ndk
SetCursorPosition(cursorPosition); SetCursorPosition(cursorPosition);
} }
inline void TextAreaWidget::SetCharacterSize(unsigned int characterSize)
{
m_drawer.SetCharacterSize(characterSize);
}
inline void TextAreaWidget::SetCursorPosition(std::size_t glyphIndex) inline void TextAreaWidget::SetCursorPosition(std::size_t glyphIndex)
{ {
OnTextAreaCursorMove(this, &glyphIndex); OnTextAreaCursorMove(this, &glyphIndex);
m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount()); m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount());
std::size_t lineCount = m_drawer.GetLineCount(); std::size_t lineCount = m_drawer.GetLineCount();
std::size_t line = 0U; std::size_t line = 0U;
for (std::size_t i = line + 1; i < lineCount; ++i) for (std::size_t i = line + 1; i < lineCount; ++i)
@ -110,8 +125,8 @@ namespace Ndk
const auto& lineInfo = m_drawer.GetLine(line); const auto& lineInfo = m_drawer.GetLine(line);
m_cursorPosition.y = line; m_cursorPosition.y = static_cast<unsigned int>(line);
m_cursorPosition.x = m_cursorGlyph - lineInfo.glyphIndex; m_cursorPosition.x = static_cast<unsigned int>(m_cursorGlyph - lineInfo.glyphIndex);
RefreshCursor(); RefreshCursor();
} }
@ -140,6 +155,13 @@ namespace Ndk
RefreshCursor(); RefreshCursor();
} }
inline void TextAreaWidget::SetEchoMode(EchoMode echoMode)
{
m_echoMode = echoMode;
UpdateDisplayText();
}
inline void TextAreaWidget::SetReadOnly(bool readOnly) inline void TextAreaWidget::SetReadOnly(bool readOnly)
{ {
m_readOnly = readOnly; m_readOnly = readOnly;
@ -149,11 +171,9 @@ namespace Ndk
inline void TextAreaWidget::SetText(const Nz::String& text) inline void TextAreaWidget::SetText(const Nz::String& text)
{ {
m_drawer.SetText(text); m_text = text;
m_textSprite->Update(m_drawer); UpdateDisplayText();
SetCursorPosition(m_cursorPosition); //< Refresh cursor position (prevent it from being outside of the text)
} }
inline void TextAreaWidget::SetTextColor(const Nz::Color& text) inline void TextAreaWidget::SetTextColor(const Nz::Color& text)

View File

@ -11,6 +11,7 @@ namespace Ndk
{ {
TextAreaWidget::TextAreaWidget(BaseWidget* parent) : TextAreaWidget::TextAreaWidget(BaseWidget* parent) :
BaseWidget(parent), BaseWidget(parent),
m_echoMode(EchoMode_Normal),
m_cursorPosition(0U, 0U), m_cursorPosition(0U, 0U),
m_cursorGlyph(0), m_cursorGlyph(0),
m_multiLineEnabled(false), m_multiLineEnabled(false),
@ -38,7 +39,34 @@ namespace Ndk
void TextAreaWidget::AppendText(const Nz::String& text) void TextAreaWidget::AppendText(const Nz::String& text)
{ {
m_drawer.AppendText(text); m_text += text;
switch (m_echoMode)
{
case EchoMode_Normal:
m_drawer.AppendText(text);
break;
case EchoMode_Password:
m_drawer.AppendText(Nz::String(text.GetLength(), '*'));
break;
case EchoMode_PasswordExceptLast:
{
m_drawer.Clear();
std::size_t textLength = m_text.GetLength();
if (textLength >= 2)
{
std::size_t lastCharacterPosition = m_text.GetCharacterPosition(textLength - 2);
if (lastCharacterPosition != Nz::String::npos)
m_drawer.AppendText(Nz::String(textLength - 1, '*'));
}
if (textLength >= 1)
m_drawer.AppendText(m_text.SubString(m_text.GetCharacterPosition(textLength - 1)));
break;
}
}
m_textSprite->Update(m_drawer); m_textSprite->Update(m_drawer);
} }
@ -87,9 +115,8 @@ namespace Ndk
} }
else else
{ {
Nz::String currentText = m_drawer.GetText(); m_text.Insert(m_text.GetCharacterPosition(m_cursorGlyph), text);
currentText.Insert(currentText.GetCharacterPosition(m_cursorGlyph), text); SetText(m_text);
SetText(currentText);
SetCursorPosition(m_cursorGlyph + text.GetLength()); SetCursorPosition(m_cursorGlyph + text.GetLength());
} }
@ -110,17 +137,14 @@ namespace Ndk
{ {
case Nz::Keyboard::Delete: case Nz::Keyboard::Delete:
{ {
const Nz::String& text = m_drawer.GetText();
Nz::String newText; Nz::String newText;
if (m_cursorGlyph > 0) if (m_cursorGlyph > 0)
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorGlyph) - 1)); newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(m_cursorGlyph) - 1));
if (m_cursorGlyph < m_drawer.GetGlyphCount()) if (m_cursorGlyph < m_text.GetLength())
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorGlyph + 1))); newText.Append(m_text.SubString(m_text.GetCharacterPosition(m_cursorGlyph + 1)));
m_drawer.SetText(newText); SetText(newText);
m_textSprite->Update(m_drawer);
break; break;
} }
@ -220,14 +244,12 @@ namespace Ndk
if (ignoreDefaultAction) if (ignoreDefaultAction)
break; break;
const Nz::String& text = m_drawer.GetText();
Nz::String newText; Nz::String newText;
if (m_cursorGlyph > 1) if (m_cursorGlyph > 0)
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorGlyph - 1) - 1)); newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(m_cursorGlyph - 1) - 1));
if (m_cursorGlyph < m_drawer.GetGlyphCount()) if (m_cursorGlyph < m_text.GetLength())
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorGlyph))); newText.Append(m_text.SubString(m_text.GetCharacterPosition(m_cursorGlyph + 1)));
MoveCursor({-1, 0}); MoveCursor({-1, 0});
SetText(newText); SetText(newText);
@ -278,4 +300,23 @@ namespace Ndk
m_cursorEntity->GetComponent<NodeComponent>().SetPosition(contentOrigin.x + position, contentOrigin.y + lineInfo.bounds.y); m_cursorEntity->GetComponent<NodeComponent>().SetPosition(contentOrigin.x + position, contentOrigin.y + lineInfo.bounds.y);
} }
void TextAreaWidget::UpdateDisplayText()
{
switch (m_echoMode)
{
case EchoMode_Normal:
m_drawer.SetText(m_text);
break;
case EchoMode_Password:
case EchoMode_PasswordExceptLast:
m_drawer.SetText(Nz::String(m_text.GetLength(), '*'));
break;
}
m_textSprite->Update(m_drawer);
SetCursorPosition(m_cursorPosition); //< Refresh cursor position (prevent it from being outside of the text)
}
} }