From 5394f202a104a46efdfe2f2914c433d3d8db8407 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 13 Mar 2025 22:07:10 +0300 Subject: [PATCH] fix multiline width calculation & feat: multiline tooltips support --- src/graphics/core/Font.cpp | 4 ++-- src/graphics/core/Font.hpp | 4 ++-- src/graphics/ui/GUI.cpp | 2 +- src/graphics/ui/elements/Label.cpp | 32 ++++++++++++++++++++++++++++-- src/graphics/ui/elements/Label.hpp | 3 ++- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/graphics/core/Font.cpp b/src/graphics/core/Font.cpp index 2116fdd3..74a78932 100644 --- a/src/graphics/core/Font.cpp +++ b/src/graphics/core/Font.cpp @@ -38,11 +38,11 @@ bool Font::isPrintableChar(uint codepoint) const { } } -int Font::calcWidth(const std::wstring& text, size_t length) const { +int Font::calcWidth(std::wstring_view text, size_t length) const { return calcWidth(text, 0, length); } -int Font::calcWidth(const std::wstring& text, size_t offset, size_t length) const { +int Font::calcWidth(std::wstring_view text, size_t offset, size_t length) const { return std::min(text.length()-offset, length) * glyphInterval; } diff --git a/src/graphics/core/Font.hpp b/src/graphics/core/Font.hpp index 07fe0532..eabfbcc6 100644 --- a/src/graphics/core/Font.hpp +++ b/src/graphics/core/Font.hpp @@ -56,14 +56,14 @@ public: /// @param text selected text /// @param length max substring length (default: no limit) /// @return pixel width of the substring - int calcWidth(const std::wstring& text, size_t length=-1) const; + int calcWidth(std::wstring_view text, size_t length=-1) const; /// @brief Calculate text width in pixels /// @param text selected text /// @param offset start of the substring /// @param length max substring length /// @return pixel width of the substring - int calcWidth(const std::wstring& text, size_t offset, size_t length) const; + int calcWidth(std::wstring_view text, size_t offset, size_t length) const; /// @brief Check if character is visible (non-whitespace) /// @param codepoint character unicode codepoint diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 5b028ac4..95425da4 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -41,7 +41,7 @@ GUI::GUI() tooltip = guiutil::create( "" - "" + "" "" ); store("tooltip", tooltip); diff --git a/src/graphics/ui/elements/Label.cpp b/src/graphics/ui/elements/Label.cpp index 392a9434..9a174c74 100644 --- a/src/graphics/ui/elements/Label.cpp +++ b/src/graphics/ui/elements/Label.cpp @@ -35,7 +35,7 @@ uint LabelCache::getLineByTextIndex(size_t index) const { return lines.size()-1; } -void LabelCache::update(const std::wstring& text, bool multiline, bool wrap) { +void LabelCache::update(std::wstring_view text, bool multiline, bool wrap) { resetFlag = false; lines.clear(); lines.push_back(LineScheme {0, false}); @@ -59,6 +59,27 @@ void LabelCache::update(const std::wstring& text, bool multiline, bool wrap) { } } } + if (font != nullptr) { + int lineHeight = font->getLineHeight(); + int maxWidth = 0; + for (int i = 0; i < lines.size() - 1; i++) { + const auto& next = lines[i + 1]; + const auto& cur = lines[i]; + maxWidth = std::max( + font->calcWidth( + text.substr(cur.offset, next.offset - cur.offset) + ), + maxWidth + ); + } + maxWidth = std::max( + font->calcWidth( + text.substr(lines[lines.size() - 1].offset) + ), + maxWidth + ); + multilineWidth = maxWidth; + } } } @@ -89,8 +110,15 @@ glm::vec2 Label::calcSize() { if (cache.lines.size() > 1) { lineHeight *= lineInterval; } + auto view = std::wstring_view(text); + if (multiline) { + return glm::vec2( + cache.multilineWidth, + lineHeight * cache.lines.size() + font->getYOffset() + ); + } return glm::vec2 ( - cache.font->calcWidth(text), + cache.font->calcWidth(view), lineHeight * cache.lines.size() + font->getYOffset() ); } diff --git a/src/graphics/ui/elements/Label.hpp b/src/graphics/ui/elements/Label.hpp index 1fbf5f5e..00d3d0b0 100644 --- a/src/graphics/ui/elements/Label.hpp +++ b/src/graphics/ui/elements/Label.hpp @@ -18,9 +18,10 @@ namespace gui { /// @brief Reset cache flag bool resetFlag = true; size_t wrapWidth = -1; + int multilineWidth = 0; void prepare(Font* font, size_t wrapWidth); - void update(const std::wstring& text, bool multiline, bool wrap); + void update(std::wstring_view text, bool multiline, bool wrap); size_t getTextLineOffset(size_t line) const; uint getLineByTextIndex(size_t index) const;