From 1892ff3c0db23ccdf7b0f6dc83cb1bdf4579b4ec Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Wed, 22 Jan 2020 19:09:11 +0100 Subject: StaticText/EnrichedString: Styling support (#9187) * StaticText/EnrichedString: Styling support * Fix tooltip fg/bgcolor * Fix default color for substr(), add unittests --- src/util/enriched_string.cpp | 71 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) (limited to 'src/util/enriched_string.cpp') 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 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(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(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; +} -- cgit v1.2.3