fix multiline width calculation & feat: multiline tooltips support

This commit is contained in:
MihailRis 2025-03-13 22:07:10 +03:00
parent 4400f7fbfb
commit 5394f202a1
5 changed files with 37 additions and 8 deletions

View File

@ -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); 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; return std::min(text.length()-offset, length) * glyphInterval;
} }

View File

@ -56,14 +56,14 @@ public:
/// @param text selected text /// @param text selected text
/// @param length max substring length (default: no limit) /// @param length max substring length (default: no limit)
/// @return pixel width of the substring /// @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 /// @brief Calculate text width in pixels
/// @param text selected text /// @param text selected text
/// @param offset start of the substring /// @param offset start of the substring
/// @param length max substring length /// @param length max substring length
/// @return pixel width of the substring /// @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) /// @brief Check if character is visible (non-whitespace)
/// @param codepoint character unicode codepoint /// @param codepoint character unicode codepoint

View File

@ -41,7 +41,7 @@ GUI::GUI()
tooltip = guiutil::create( tooltip = guiutil::create(
"<container color='#000000A0' interactive='false' z-index='999'>" "<container color='#000000A0' interactive='false' z-index='999'>"
"<label id='tooltip.label' pos='2' autoresize='true'></label>" "<label id='tooltip.label' pos='2' autoresize='true' multiline='true' text-wrap='false'></label>"
"</container>" "</container>"
); );
store("tooltip", tooltip); store("tooltip", tooltip);

View File

@ -35,7 +35,7 @@ uint LabelCache::getLineByTextIndex(size_t index) const {
return lines.size()-1; 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; resetFlag = false;
lines.clear(); lines.clear();
lines.push_back(LineScheme {0, false}); 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) { if (cache.lines.size() > 1) {
lineHeight *= lineInterval; lineHeight *= lineInterval;
} }
auto view = std::wstring_view(text);
if (multiline) {
return glm::vec2(
cache.multilineWidth,
lineHeight * cache.lines.size() + font->getYOffset()
);
}
return glm::vec2 ( return glm::vec2 (
cache.font->calcWidth(text), cache.font->calcWidth(view),
lineHeight * cache.lines.size() + font->getYOffset() lineHeight * cache.lines.size() + font->getYOffset()
); );
} }

View File

@ -18,9 +18,10 @@ namespace gui {
/// @brief Reset cache flag /// @brief Reset cache flag
bool resetFlag = true; bool resetFlag = true;
size_t wrapWidth = -1; size_t wrapWidth = -1;
int multilineWidth = 0;
void prepare(Font* font, size_t wrapWidth); 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; size_t getTextLineOffset(size_t line) const;
uint getLineByTextIndex(size_t index) const; uint getLineByTextIndex(size_t index) const;