diff options
author | SmallJoker <SmallJoker@users.noreply.github.com> | 2020-01-22 19:09:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-22 19:09:11 +0100 |
commit | 1892ff3c0db23ccdf7b0f6dc83cb1bdf4579b4ec (patch) | |
tree | c49c16a69e9c555141960b4bca22a88df9b17a61 /src/util | |
parent | fab3f5f7c8ce0cbfc27e509f065e3f4cfe28c514 (diff) | |
download | minetest-1892ff3c0db23ccdf7b0f6dc83cb1bdf4579b4ec.tar.gz minetest-1892ff3c0db23ccdf7b0f6dc83cb1bdf4579b4ec.tar.bz2 minetest-1892ff3c0db23ccdf7b0f6dc83cb1bdf4579b4ec.zip |
StaticText/EnrichedString: Styling support (#9187)
* StaticText/EnrichedString: Styling support
* Fix tooltip fg/bgcolor
* Fix default color for substr(), add unittests
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/enriched_string.cpp | 71 | ||||
-rw-r--r-- | src/util/enriched_string.h | 28 |
2 files changed, 76 insertions, 23 deletions
diff --git a/src/util/enriched_string.cpp b/src/util/enriched_string.cpp index 642188a52..d5f8aa661 100644 --- a/src/util/enriched_string.cpp +++ b/src/util/enriched_string.cpp @@ -45,15 +45,27 @@ EnrichedString::EnrichedString(const wchar_t *str, const SColor &color) addAtEnd(translate_string(std::wstring(str)), color); } +void EnrichedString::clear() +{ + m_string.clear(); + m_colors.clear(); + m_has_background = false; + m_default_length = 0; + m_default_color = irr::video::SColor(255, 255, 255, 255); +} + void EnrichedString::operator=(const wchar_t *str) { clear(); - addAtEnd(translate_string(std::wstring(str)), SColor(255, 255, 255, 255)); + addAtEnd(translate_string(std::wstring(str)), m_default_color); } void EnrichedString::addAtEnd(const std::wstring &s, const SColor &initial_color) { SColor color(initial_color); + bool use_default = (m_default_length == m_string.size() && + color == m_default_color); + size_t i = 0; while (i < s.length()) { if (s[i] != L'\x1b') { @@ -90,6 +102,12 @@ void EnrichedString::addAtEnd(const std::wstring &s, const SColor &initial_color continue; } parseColorString(wide_to_utf8(parts[1]), color, true); + + // No longer use default color after first escape + if (use_default) { + m_default_length = m_string.size(); + use_default = false; + } } else if (parts[0] == L"b") { if (parts.size() < 2) { continue; @@ -98,6 +116,10 @@ void EnrichedString::addAtEnd(const std::wstring &s, const SColor &initial_color m_has_background = true; } } + + // Update if no escape character was found + if (use_default) + m_default_length = m_string.size(); } void EnrichedString::addChar(const EnrichedString &source, size_t i) @@ -110,7 +132,7 @@ void EnrichedString::addCharNoColor(wchar_t c) { m_string += c; if (m_colors.empty()) { - m_colors.emplace_back(255, 255, 255, 255); + m_colors.emplace_back(m_default_color); } else { m_colors.push_back(m_colors[m_colors.size() - 1]); } @@ -118,35 +140,40 @@ void EnrichedString::addCharNoColor(wchar_t c) EnrichedString EnrichedString::operator+(const EnrichedString &other) const { - std::vector<SColor> result; - result.insert(result.end(), m_colors.begin(), m_colors.end()); - result.insert(result.end(), other.m_colors.begin(), other.m_colors.end()); - return EnrichedString(m_string + other.m_string, result); + EnrichedString result = *this; + result += other; + return result; } void EnrichedString::operator+=(const EnrichedString &other) { + bool update_default_color = m_default_length == m_string.size(); + m_string += other.m_string; m_colors.insert(m_colors.end(), other.m_colors.begin(), other.m_colors.end()); + + if (update_default_color) { + m_default_length += other.m_default_length; + updateDefaultColor(); + } } EnrichedString EnrichedString::substr(size_t pos, size_t len) const { - if (pos == m_string.length()) { + if (pos >= m_string.length()) return EnrichedString(); - } - if (len == std::string::npos || pos + len > m_string.length()) { - return EnrichedString( - m_string.substr(pos, std::string::npos), - std::vector<SColor>(m_colors.begin() + pos, m_colors.end()) - ); - } - return EnrichedString( + if (len == std::string::npos || pos + len > m_string.length()) + len = m_string.length() - pos; + + EnrichedString str( m_string.substr(pos, len), std::vector<SColor>(m_colors.begin() + pos, m_colors.begin() + pos + len) ); - + if (pos < m_default_length) + str.m_default_length = m_default_length - pos; + str.setDefaultColor(m_default_color); + return str; } const wchar_t *EnrichedString::c_str() const @@ -163,3 +190,15 @@ const std::wstring &EnrichedString::getString() const { return m_string; } + +void EnrichedString::setDefaultColor(const irr::video::SColor &color) +{ + m_default_color = color; + updateDefaultColor(); +} + +void EnrichedString::updateDefaultColor() +{ + for (size_t i = 0; i < m_default_length; ++i) + m_colors[i] = m_default_color; +} diff --git a/src/util/enriched_string.h b/src/util/enriched_string.h index 202d84cb0..eaab3bd91 100644 --- a/src/util/enriched_string.h +++ b/src/util/enriched_string.h @@ -32,6 +32,7 @@ public: const irr::video::SColor &color = irr::video::SColor(255, 255, 255, 255)); EnrichedString(const std::wstring &string, const std::vector<irr::video::SColor> &colors); + void clear(); void operator=(const wchar_t *str); void addAtEnd(const std::wstring &s, const irr::video::SColor &color); @@ -50,6 +51,14 @@ public: const wchar_t *c_str() const; const std::vector<irr::video::SColor> &getColors() const; const std::wstring &getString() const; + + void setDefaultColor(const irr::video::SColor &color); + void updateDefaultColor(); + inline const irr::video::SColor &getDefaultColor() const + { + return m_default_color; + } + inline bool operator==(const EnrichedString &other) const { return (m_string == other.m_string && m_colors == other.m_colors); @@ -58,12 +67,6 @@ public: { return !(*this == other); } - inline void clear() - { - m_string.clear(); - m_colors.clear(); - m_has_background = false; - } inline bool empty() const { return m_string.empty(); @@ -72,6 +75,7 @@ public: { return m_string.size(); } + inline bool hasBackground() const { return m_has_background; @@ -80,9 +84,19 @@ public: { return m_background; } + inline void setBackground(const irr::video::SColor &color) + { + m_background = color; + m_has_background = true; + } + private: std::wstring m_string; std::vector<irr::video::SColor> m_colors; - bool m_has_background = false; + bool m_has_background; + irr::video::SColor m_default_color; irr::video::SColor m_background; + // This variable defines the length of the default-colored text. + // Change this to a std::vector if an "end coloring" tag is wanted. + size_t m_default_length; }; |