SDK: Add RichTextAreaWidget (WIP)
This commit is contained in:
@@ -27,6 +27,8 @@ namespace Nz
|
||||
AbstractTextDrawer() = default;
|
||||
virtual ~AbstractTextDrawer();
|
||||
|
||||
virtual void Clear() = 0;
|
||||
|
||||
virtual const Recti& GetBounds() const = 0;
|
||||
virtual Font* GetFont(std::size_t index) const = 0;
|
||||
virtual std::size_t GetFontCount() const = 0;
|
||||
@@ -35,6 +37,9 @@ namespace Nz
|
||||
virtual const Line& GetLine(std::size_t index) const = 0;
|
||||
virtual std::size_t GetLineCount() const = 0;
|
||||
inline std::size_t GetLineGlyphCount(std::size_t index) const;
|
||||
virtual float GetMaxLineWidth() const = 0;
|
||||
|
||||
virtual void SetMaxLineWidth(float lineWidth) = 0;
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
|
||||
@@ -26,29 +26,33 @@ namespace Nz
|
||||
RichTextDrawer(RichTextDrawer&& drawer);
|
||||
~RichTextDrawer();
|
||||
|
||||
BlockRef AppendText(const String& str);
|
||||
BlockRef AppendText(const String& str, bool forceNewBlock = false);
|
||||
|
||||
inline void Clear();
|
||||
void Clear() override;
|
||||
|
||||
inline std::size_t FindBlock(std::size_t glyphIndex) const;
|
||||
|
||||
inline unsigned int GetBlockCharacterSize(std::size_t index) const;
|
||||
inline const Color& GetBlockColor(std::size_t index) const;
|
||||
inline std::size_t GetBlockCount() const;
|
||||
inline std::size_t GetBlockFirstGlyphIndex(std::size_t index) const;
|
||||
inline const FontRef& GetBlockFont(std::size_t index) const;
|
||||
inline TextStyleFlags GetBlockStyle(std::size_t index) const;
|
||||
inline const String& GetBlockText(std::size_t index) const;
|
||||
|
||||
inline BlockRef GetBlock(std::size_t index);
|
||||
const Recti& GetBounds() const override;
|
||||
inline unsigned int GetDefaultCharacterSize() const;
|
||||
inline const Color& GetDefaultColor() const;
|
||||
inline const FontRef& GetDefaultFont() const;
|
||||
inline TextStyleFlags GetDefaultStyle() const;
|
||||
|
||||
const Recti& GetBounds() const override;
|
||||
Font* GetFont(std::size_t index) const override;
|
||||
std::size_t GetFontCount() const override;
|
||||
const Glyph& GetGlyph(std::size_t index) const override;
|
||||
std::size_t GetGlyphCount() const override;
|
||||
const Line& GetLine(std::size_t index) const override;
|
||||
std::size_t GetLineCount() const override;
|
||||
float GetMaxLineWidth() const override;
|
||||
|
||||
void MergeBlocks();
|
||||
|
||||
@@ -65,9 +69,13 @@ namespace Nz
|
||||
inline void SetDefaultFont(const FontRef& font);
|
||||
inline void SetDefaultStyle(TextStyleFlags style);
|
||||
|
||||
void SetMaxLineWidth(float lineWidth) override;
|
||||
|
||||
RichTextDrawer& operator=(const RichTextDrawer& drawer);
|
||||
RichTextDrawer& operator=(RichTextDrawer&& drawer);
|
||||
|
||||
static constexpr std::size_t InvalidBlockIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
//static RichTextDrawer Draw(const String& str, unsigned int characterSize, TextStyleFlags style = TextStyle_Regular, const Color& color = Color::White);
|
||||
//static RichTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style = TextStyle_Regular, const Color& color = Color::White);
|
||||
|
||||
@@ -94,6 +102,7 @@ namespace Nz
|
||||
struct Block
|
||||
{
|
||||
std::size_t fontIndex;
|
||||
std::size_t glyphIndex;
|
||||
Color color;
|
||||
String text;
|
||||
TextStyleFlags style;
|
||||
@@ -123,6 +132,7 @@ namespace Nz
|
||||
mutable Recti m_bounds;
|
||||
mutable Vector2ui m_drawPos;
|
||||
mutable bool m_glyphUpdated;
|
||||
float m_maxLineWidth;
|
||||
unsigned int m_defaultCharacterSize;
|
||||
};
|
||||
|
||||
@@ -137,6 +147,7 @@ namespace Nz
|
||||
|
||||
inline unsigned int GetCharacterSize() const;
|
||||
inline Color GetColor() const;
|
||||
inline std::size_t GetFirstGlyphIndex() const;
|
||||
inline const FontRef& GetFont() const;
|
||||
inline TextStyleFlags GetStyle() const;
|
||||
inline const String& GetText() const;
|
||||
|
||||
@@ -7,13 +7,38 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline void RichTextDrawer::Clear()
|
||||
inline std::size_t RichTextDrawer::FindBlock(std::size_t glyphIndex) const
|
||||
{
|
||||
m_fontIndexes.clear();
|
||||
m_blocks.clear();
|
||||
m_fonts.clear();
|
||||
m_glyphs.clear();
|
||||
ClearGlyphs();
|
||||
// Binary search
|
||||
std::size_t count = m_blocks.size();
|
||||
std::size_t step;
|
||||
|
||||
std::size_t i = InvalidBlockIndex;
|
||||
std::size_t first = 0;
|
||||
std::size_t last = count;
|
||||
while (count > 0)
|
||||
{
|
||||
i = first;
|
||||
step = count / 2;
|
||||
|
||||
i += step;
|
||||
|
||||
if (m_blocks[i].glyphIndex < glyphIndex)
|
||||
{
|
||||
first = i + 1;
|
||||
count -= step + 1;
|
||||
}
|
||||
else
|
||||
count = step;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
inline auto RichTextDrawer::GetBlock(std::size_t index) -> BlockRef
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return BlockRef(*this, index);
|
||||
}
|
||||
|
||||
inline unsigned int RichTextDrawer::GetBlockCharacterSize(std::size_t index) const
|
||||
@@ -33,6 +58,12 @@ namespace Nz
|
||||
return m_blocks.size();
|
||||
}
|
||||
|
||||
inline std::size_t RichTextDrawer::GetBlockFirstGlyphIndex(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].glyphIndex;
|
||||
}
|
||||
|
||||
inline const FontRef& RichTextDrawer::GetBlockFont(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
@@ -204,8 +235,19 @@ namespace Nz
|
||||
inline void RichTextDrawer::SetBlockText(std::size_t index, const String& str)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
|
||||
std::size_t previousLength = m_blocks[index].text.GetLength();
|
||||
|
||||
m_blocks[index].text = str;
|
||||
|
||||
std::size_t newLength = m_blocks[index].text.GetLength();
|
||||
if (newLength != previousLength)
|
||||
{
|
||||
std::size_t delta = newLength - previousLength; //< Underflow allowed
|
||||
for (std::size_t i = index + 1; i < m_blocks.size(); ++i)
|
||||
m_blocks[i].glyphIndex += delta;
|
||||
}
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
@@ -291,6 +333,17 @@ namespace Nz
|
||||
return m_drawer.GetBlockStyle(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the first glyph index at which starts the referenced block
|
||||
* \return The first glyph index concerned by this block
|
||||
*
|
||||
* \see GetText
|
||||
*/
|
||||
inline std::size_t RichTextDrawer::BlockRef::GetFirstGlyphIndex() const
|
||||
{
|
||||
return m_drawer.GetBlockFirstGlyphIndex(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the text of the referenced block
|
||||
* \return The referenced block text
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Nz
|
||||
|
||||
void AppendText(const String& str);
|
||||
|
||||
void Clear();
|
||||
void Clear() override;
|
||||
|
||||
const Recti& GetBounds() const override;
|
||||
unsigned int GetCharacterSize() const;
|
||||
|
||||
Reference in New Issue
Block a user