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);
}
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;
}

View File

@ -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

View File

@ -41,7 +41,7 @@ GUI::GUI()
tooltip = guiutil::create(
"<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>"
);
store("tooltip", tooltip);

View File

@ -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()
);
}

View File

@ -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;