mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 12:51:42 +00:00
Add capability of max width wrapping to message box (#78)
* Add capability of max width wrapping to message box. Takes out the need to add manual line breaks to messages. * DrawCentredParagraph: fix line centring breaking at unequal lengths --------- Co-authored-by: Hyper <34012267+hyperbx@users.noreply.github.com>
This commit is contained in:
parent
63d474ce91
commit
5f9fdcf934
2 changed files with 87 additions and 36 deletions
|
|
@ -256,28 +256,88 @@ inline std::string Truncate(const std::string& input, size_t maxLength, bool use
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::vector<std::string> Split(const char* str, char delimiter)
|
inline std::vector<std::string> Split(const char* strStart, const ImFont *font, float fontSize, float maxWidth)
|
||||||
{
|
{
|
||||||
|
if (!strStart)
|
||||||
|
return {};
|
||||||
|
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
|
float textWidth = 0.0f;
|
||||||
if (!str)
|
float lineWidth = 0.0f;
|
||||||
return result;
|
const float scale = fontSize / font->FontSize;
|
||||||
|
const char *str = strStart;
|
||||||
const char* start = str;
|
const char *strEnd = strStart + strlen(strStart);
|
||||||
const char* current = str;
|
const char *lineStart = strStart;
|
||||||
|
const bool wordWrapEnabled = (maxWidth > 0.0f);
|
||||||
while (*current)
|
const char *wordWrapEOL = nullptr;
|
||||||
|
while (*str != 0)
|
||||||
{
|
{
|
||||||
if (*current == delimiter)
|
if (wordWrapEnabled)
|
||||||
{
|
{
|
||||||
result.emplace_back(start, current - start);
|
if (wordWrapEOL == nullptr)
|
||||||
start = current + 1;
|
{
|
||||||
|
wordWrapEOL = font->CalcWordWrapPositionA(scale, str, strEnd, maxWidth - lineWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str >= wordWrapEOL)
|
||||||
|
{
|
||||||
|
if (textWidth < lineWidth)
|
||||||
|
textWidth = lineWidth;
|
||||||
|
|
||||||
|
result.emplace_back(lineStart, str);
|
||||||
|
lineWidth = 0.0f;
|
||||||
|
wordWrapEOL = nullptr;
|
||||||
|
|
||||||
|
while (str < strEnd && ImCharIsBlankA(*str))
|
||||||
|
str++;
|
||||||
|
|
||||||
|
if (*str == '\n')
|
||||||
|
str++;
|
||||||
|
|
||||||
|
lineStart = str;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current++;
|
const char *prevStr = str;
|
||||||
|
unsigned int c = (unsigned int)*str;
|
||||||
|
if (c < 0x80)
|
||||||
|
str += 1;
|
||||||
|
else
|
||||||
|
str += ImTextCharFromUtf8(&c, str, strEnd);
|
||||||
|
|
||||||
|
if (c < 32)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
result.emplace_back(lineStart, str - 1);
|
||||||
|
lineStart = str;
|
||||||
|
textWidth = ImMax(textWidth, lineWidth);
|
||||||
|
lineWidth = 0.0f;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\r')
|
||||||
|
{
|
||||||
|
lineStart = str;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const float charWidth = ((int)c < font->IndexAdvanceX.Size ? font->IndexAdvanceX.Data[c] : font->FallbackAdvanceX) * scale;
|
||||||
|
if (lineWidth + charWidth >= maxWidth)
|
||||||
|
{
|
||||||
|
str = prevStr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineWidth += charWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.emplace_back(start);
|
if (str != lineStart)
|
||||||
|
{
|
||||||
|
result.emplace_back(lineStart, str);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -298,40 +358,29 @@ inline ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float
|
||||||
return { x, y };
|
return { x, y };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMargin, const char* text)
|
inline ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float maxWidth, float lineMargin, const char* text)
|
||||||
{
|
{
|
||||||
return MeasureCentredParagraph(font, fontSize, lineMargin, Split(text, '\n'));
|
return MeasureCentredParagraph(font, fontSize, lineMargin, Split(text, font, fontSize, maxWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void DrawCentredParagraph(const ImFont* font, float fontSize, const ImVec2& centre, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod)
|
inline void DrawCentredParagraph(const ImFont* font, float fontSize, float maxWidth, const ImVec2& centre, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod)
|
||||||
{
|
{
|
||||||
auto lines = Split(text, '\n');
|
auto lines = Split(text, font, fontSize, maxWidth);
|
||||||
auto paragraphSize = MeasureCentredParagraph(font, fontSize, lineMargin, lines);
|
auto paragraphSize = MeasureCentredParagraph(font, fontSize, lineMargin, lines);
|
||||||
auto offsetY = 0.0f;
|
auto offsetY = 0.0f;
|
||||||
|
|
||||||
auto hasList = std::strstr(text, "- ");
|
|
||||||
auto isList = false;
|
|
||||||
auto listOffsetX = 0.0f;
|
|
||||||
|
|
||||||
for (int i = 0; i < lines.size(); i++)
|
for (int i = 0; i < lines.size(); i++)
|
||||||
{
|
{
|
||||||
auto& str = lines[i];
|
auto& str = lines[i];
|
||||||
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, str.c_str());
|
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, str.c_str());
|
||||||
|
|
||||||
if (hasList)
|
auto textX = str.starts_with("- ")
|
||||||
{
|
? centre.x - paragraphSize.x / 2
|
||||||
if (!isList && str.starts_with("- ") && lines.size() > i + 1 && lines[i + 1].starts_with("- "))
|
: centre.x - textSize.x / 2;
|
||||||
{
|
|
||||||
isList = true;
|
|
||||||
listOffsetX = centre.x - textSize.x / 2;
|
|
||||||
}
|
|
||||||
else if (isList && !str.starts_with("- "))
|
|
||||||
{
|
|
||||||
isList = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drawMethod(str.c_str(), ImVec2(/* X */ isList ? listOffsetX : centre.x - textSize.x / 2, /* Y */ centre.y - paragraphSize.y / 2 + offsetY));
|
auto textY = centre.y - paragraphSize.y / 2 + offsetY;
|
||||||
|
|
||||||
|
drawMethod(str.c_str(), { textX, textY });
|
||||||
|
|
||||||
offsetY += textSize.y + Scale(lineMargin);
|
offsetY += textSize.y + Scale(lineMargin);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -288,8 +288,9 @@ void MessageWindow::Draw()
|
||||||
|
|
||||||
ImVec2 centre = { res.x / 2, res.y / 2 };
|
ImVec2 centre = { res.x / 2, res.y / 2 };
|
||||||
|
|
||||||
|
float maxWidth = Scale(640.0f);
|
||||||
auto fontSize = Scale(28);
|
auto fontSize = Scale(28);
|
||||||
auto textSize = MeasureCentredParagraph(g_fntSeurat, fontSize, 5, g_text.c_str());
|
auto textSize = MeasureCentredParagraph(g_fntSeurat, fontSize, maxWidth, 5, g_text.c_str());
|
||||||
auto textMarginX = Scale(37);
|
auto textMarginX = Scale(37);
|
||||||
auto textMarginY = Scale(45);
|
auto textMarginY = Scale(45);
|
||||||
|
|
||||||
|
|
@ -325,6 +326,7 @@ void MessageWindow::Draw()
|
||||||
(
|
(
|
||||||
g_fntSeurat,
|
g_fntSeurat,
|
||||||
fontSize,
|
fontSize,
|
||||||
|
maxWidth,
|
||||||
{ centre.x, centre.y + Scale(3) },
|
{ centre.x, centre.y + Scale(3) },
|
||||||
5,
|
5,
|
||||||
g_text.c_str(),
|
g_text.c_str(),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue