support ruby annotations for options menu descriptions

This commit is contained in:
DeaTh-G 2025-01-25 12:18:14 +01:00
parent bddf9efff6
commit a1540cd6c3
3 changed files with 61 additions and 34 deletions

View file

@ -189,6 +189,13 @@ void DrawPauseHeaderContainer(ImVec2 min, ImVec2 max, float alpha)
drawList->AddImage(g_texGeneralWindow.get(), { max.x - commonWidth, min.y }, max, GET_UV_COORDS(right), colour);
}
void DrawTextBasic(const ImFont* font, float fontSize, const ImVec2& pos, ImU32 colour, const char* text)
{
auto drawList = ImGui::GetForegroundDrawList();
drawList->AddText(font, fontSize, pos, colour, text, nullptr);
}
void DrawTextWithMarquee(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 color, const char* text, double time, double delay, double speed)
{
auto drawList = ImGui::GetForegroundDrawList();
@ -207,6 +214,24 @@ void DrawTextWithMarquee(const ImFont* font, float fontSize, const ImVec2& pos,
drawList->PopClipRect();
}
void DrawTextWithMarqueeShadow(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 colour, const char* text, double time, double delay, double speed, float offset, float radius, ImU32 shadowColour)
{
auto drawList = ImGui::GetForegroundDrawList();
auto rectWidth = max.x - min.x;
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, text);
auto textX = pos.x - fmodf(std::max(0.0, ImGui::GetTime() - (time + delay)) * speed, textSize.x + rectWidth);
drawList->PushClipRect(min, max, true);
if (textX <= pos.x)
DrawTextWithShadow(font, fontSize, { textX, pos.y }, colour, text, offset, radius, shadowColour);
if (textX + textSize.x < pos.x)
DrawTextWithShadow(font, fontSize, { textX + textSize.x + rectWidth, pos.y }, colour, text, offset, radius, shadowColour);
drawList->PopClipRect();
}
void DrawTextWithOutline(const ImFont* font, float fontSize, const ImVec2& pos, ImU32 color, const char* text, float outlineSize, ImU32 outlineColor, uint32_t shaderModifier)
{
auto drawList = ImGui::GetForegroundDrawList();
@ -534,12 +559,12 @@ ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float maxWidt
return MeasureCentredParagraph(font, fontSize, lineMargin, Split(text, font, fontSize, maxWidth));
}
void DrawCentredParagraph(const ImFont* font, float fontSize, float maxWidth, const ImVec2& centre, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod)
void DrawRubyAnnotatedText(const ImFont* font, float fontSize, float maxWidth, const ImVec2& pos, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod, std::function<void(const char*, float, ImVec2)> annotationDrawMethod, bool isCentred)
{
const auto& input = RemoveRubyAnnotations(text);
auto lines = Split(input.first.c_str(), font, fontSize, maxWidth);
auto paragraphSize = MeasureCentredParagraph(font, fontSize, lineMargin, lines);
auto offsetY = 0.0f;
float offsetY = 0.0f;
for (auto& line : lines)
{
@ -555,20 +580,26 @@ void DrawCentredParagraph(const ImFont* font, float fontSize, float maxWidth, co
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, annotationRemovedLine.c_str());
auto annotationSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, "");
auto textX = annotationRemovedLine.starts_with("- ")
? centre.x - paragraphSize.x / 2
: centre.x - textSize.x / 2;
float textX = pos.x;
if (isCentred)
{
textX = annotationRemovedLine.starts_with("- ")
? pos.x - paragraphSize.x / 2
: pos.x - textSize.x / 2;
}
for (const auto& segment : annotatedLine)
{
textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, segment.text.c_str());
auto textY = centre.y - paragraphSize.y / 2 + offsetY;
float textY = pos.y + offsetY;
if (isCentred)
{
textY = pos.y - paragraphSize.y / 2 + offsetY;
}
if (segment.annotated)
{
annotationSize = font->CalcTextSizeA(fontSize * 0.55f, FLT_MAX, 0, segment.annotation.c_str());
float annotationX = textX + (textSize.x - annotationSize.x) / 2.0f;
annotationDrawMethod(segment.annotation.c_str(), fontSize * 0.55f, { annotationX, textY - (fontSize * 0.55f) });
@ -577,7 +608,7 @@ void DrawCentredParagraph(const ImFont* font, float fontSize, float maxWidth, co
drawMethod(segment.text.c_str(), { textX, textY });
textX += textSize.x;
}
offsetY += textSize.y + Scale(lineMargin);
if (annotatedLines.annotated)
{
@ -586,22 +617,9 @@ void DrawCentredParagraph(const ImFont* font, float fontSize, float maxWidth, co
}
}
void DrawTextWithMarqueeShadow(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 colour, const char* text, double time, double delay, double speed, float offset, float radius, ImU32 shadowColour)
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 drawList = ImGui::GetForegroundDrawList();
auto rectWidth = max.x - min.x;
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, text);
auto textX = pos.x - fmodf(std::max(0.0, ImGui::GetTime() - (time + delay)) * speed, textSize.x + rectWidth);
drawList->PushClipRect(min, max, true);
if (textX <= pos.x)
DrawTextWithShadow(font, fontSize, { textX, pos.y }, colour, text, offset, radius, shadowColour);
if (textX + textSize.x < pos.x)
DrawTextWithShadow(font, fontSize, { textX + textSize.x + rectWidth, pos.y }, colour, text, offset, radius, shadowColour);
drawList->PopClipRect();
DrawRubyAnnotatedText(font, fontSize, maxWidth, centre, lineMargin, text, drawMethod, annotationDrawMethod, true);
}
float Lerp(float a, float b, float t)

View file

@ -51,8 +51,10 @@ float Scale(float size);
double ComputeLinearMotion(double duration, double offset, double total);
double ComputeMotion(double duration, double offset, double total);
void DrawPauseContainer(ImVec2 min, ImVec2 max, float alpha = 1);
void DrawTextBasic(const ImFont* font, float fontSize, const ImVec2& pos, ImU32 colour, const char* text);
void DrawPauseHeaderContainer(ImVec2 min, ImVec2 max, float alpha = 1);
void DrawTextWithMarquee(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 color, const char* text, double time, double delay, double speed);
void DrawTextWithMarqueeShadow(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 colour, const char* text, double time, double delay, double speed, float offset = 2.0f, float radius = 1.0f, ImU32 shadowColour = IM_COL32(0, 0, 0, 255));
void DrawTextWithOutline(const ImFont* font, float fontSize, const ImVec2& pos, ImU32 color, const char* text, float outlineSize, ImU32 outlineColor, uint32_t shaderModifier = IMGUI_SHADER_MODIFIER_NONE);
void DrawTextWithShadow(const ImFont* font, float fontSize, const ImVec2& pos, ImU32 colour, const char* text, float offset = 2.0f, float radius = 1.0f, ImU32 shadowColour = IM_COL32(0, 0, 0, 255));
float CalcWidestTextSize(const ImFont* font, float fontSize, std::span<std::string> strs);
@ -65,8 +67,8 @@ std::vector<std::string> RemoveAnnotationFromParagraph(const std::vector<std::st
std::string RemoveAnnotationFromParagraphLine(const std::vector<TextSegment>& annotatedLine);
ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMargin, std::vector<std::string> lines);
ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float maxWidth, float lineMargin, const char* text);
void DrawRubyAnnotatedText(const ImFont* font, float fontSize, float maxWidth, const ImVec2& pos, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod, std::function<void(const char*, float, ImVec2)> annotationDrawMethod, bool isCentred = false);
void DrawCentredParagraph(const ImFont* font, float fontSize, float maxWidth, const ImVec2& centre, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod);
void DrawTextWithMarqueeShadow(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 colour, const char* text, double time, double delay, double speed, float offset = 2.0f, float radius = 1.0f, ImU32 shadowColour = IM_COL32(0, 0, 0, 255));
float Lerp(float a, float b, float t);
float Cubic(float a, float b, float t);
float Hermite(float a, float b, float t);

View file

@ -1231,17 +1231,24 @@ static void DrawInfoPanel(ImVec2 infoMin, ImVec2 infoMax)
desc += "\n\n" + g_selectedItem->GetValueDescription(Config::Language);
}
auto size = Scale(26.0f);
drawList->AddText
(
auto fontSize = Scale(26.0f);
DrawRubyAnnotatedText(
g_seuratFont,
size,
{ clipRectMin.x, thumbnailMax.y + size - 5.0f },
IM_COL32_WHITE,
fontSize,
clipRectMax.x - clipRectMin.y,
{ clipRectMin.x, thumbnailMax.y + fontSize - 5.0f },
0.0f,
desc.c_str(),
0,
clipRectMax.x - clipRectMin.x
[=](const char* str, ImVec2 pos)
{
DrawTextBasic(g_seuratFont, fontSize, pos, IM_COL32(255, 255, 255, 255), str);
},
[=](const char* str, float size, ImVec2 pos)
{
DrawTextBasic(g_seuratFont, size, pos, IM_COL32(255, 255, 255, 255), str);
}
);
}