Skip to content

Commit 7877185

Browse files
committed
Added wrapIndexesBreakOnSpace wrapIndexesBreakOnSpace that can be used to create wrapped text from a given string.
1 parent 27218a9 commit 7877185

1 file changed

Lines changed: 89 additions & 2 deletions

File tree

libControls/ToolTip.cpp

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,93 @@ namespace
3232
});
3333
return maxWidthStringSize;
3434
}
35+
36+
37+
// Returns a vector of pairs <indexes where the wraps should occur> and <if a truncation occurred>.
38+
// Wraps occur at the last available space before the text width is exceeded.
39+
std::vector<std::pair<size_t, bool>> wrapIndexesBreakOnSpace (const std::string& text, const NAS2D::Font& font, int textWidth)
40+
{
41+
std::vector<std::pair<size_t, bool>> wrapIndexes;
42+
size_t wrapIndexOffset = 0;
43+
size_t lastSpaceIndex = 0;
44+
const int truncationSize = font.size("...").x;
45+
46+
for (size_t index = 0; index < text.size(); ++index)
47+
{
48+
if (text[index] == '\n')
49+
{
50+
wrapIndexOffset = index + 1;
51+
}
52+
53+
if (text[index] == ' ')
54+
{
55+
lastSpaceIndex = index;
56+
}
57+
58+
if (font.size(text.substr(wrapIndexOffset, index - wrapIndexOffset + 1)).x + truncationSize > textWidth && lastSpaceIndex <= wrapIndexOffset)
59+
{
60+
wrapIndexes.push_back({index - 1, true});
61+
62+
// Fast forward the index to the next space
63+
while (index < text.size() && text[index] != ' ')
64+
{
65+
++index;
66+
}
67+
68+
if (index < text.size())
69+
{
70+
wrapIndexOffset = index + 1;
71+
lastSpaceIndex = index;
72+
}
73+
}
74+
75+
if (font.size(text.substr(wrapIndexOffset, index - wrapIndexOffset + 1)).x > textWidth && lastSpaceIndex > wrapIndexOffset)
76+
{
77+
// Rewind index to the last space
78+
index = lastSpaceIndex;
79+
wrapIndexOffset = index + 1;
80+
wrapIndexes.push_back({lastSpaceIndex, false});
81+
}
82+
}
83+
84+
return wrapIndexes;
85+
};
86+
87+
88+
// Returns a constructed string with line breaks at the last available space before the text width is exceeded.
89+
// Lines truncated will attempt to fit and end in "..." but may spill beyond the designated width
90+
std::string wrapTextBreakOnSpace(const std::string& text, const NAS2D::Font& font, int textWidth)
91+
{
92+
auto wrapIndexes = wrapIndexesBreakOnSpace(text, font, textWidth);
93+
std::string wrappedText;
94+
size_t wrapIndexOffset = 0;
95+
for (const auto& [wrapIndex, truncated] : wrapIndexes)
96+
{
97+
wrappedText += text.substr(wrapIndexOffset, wrapIndex - wrapIndexOffset);
98+
if (truncated)
99+
{
100+
wrappedText += "...";
101+
wrapIndexOffset = wrapIndex;
102+
while (wrapIndexOffset < text.size() && text[wrapIndexOffset] != ' ')
103+
{
104+
++wrapIndexOffset;
105+
}
106+
107+
if (wrapIndexOffset < text.size())
108+
{
109+
wrappedText += '\n';
110+
wrapIndexOffset++;
111+
}
112+
}
113+
else
114+
{
115+
wrappedText += '\n';
116+
wrapIndexOffset = wrapIndex + 1;
117+
}
118+
}
119+
wrappedText += text.substr(wrapIndexOffset);
120+
return wrappedText;
121+
};
35122
}
36123

37124

@@ -133,8 +220,8 @@ void ToolTip::draw() const
133220
auto linePosition = position() + PaddingSize;
134221

135222
forEachLine(mFocusedControl->second, [this, &renderer, &linePosition](const std::string& lineStr) {
136-
renderer.drawText(mFont, lineStr, linePosition);
137-
linePosition.y += mFont.height();
223+
renderer.drawText(mFont, lineStr, linePosition);
224+
linePosition.y += mFont.height();
138225
});
139226
}
140227
}

0 commit comments

Comments
 (0)