Finish crafting log helper window

This commit is contained in:
Asriel Camora
2023-10-10 18:38:01 -07:00
parent 9a924c8049
commit 1da2acc5c5
7 changed files with 288 additions and 34 deletions
+117 -11
View File
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
namespace Craftimizer.Plugin;
internal static class ImGuiUtils
@@ -124,6 +125,96 @@ internal static class ImGuiUtils
ImGui.EndGroup();
}
private static Vector2 UnitCircle(float theta)
{
var (s, c) = MathF.SinCos(theta);
// SinCos positive y is downwards, but we want it upwards for ImGui
return new Vector2(c, -s);
}
private static float Lerp(float a, float b, float t) =>
MathF.FusedMultiplyAdd(b - a, t, a);
private static void ArcSegment(Vector2 o, Vector2 prev, Vector2 cur, Vector2? next, float radius, float ratio, uint color)
{
var d = ImGui.GetWindowDrawList();
d.PathLineTo(o + cur * radius);
d.PathLineTo(o + prev * radius);
d.PathLineTo(o + prev * radius * ratio);
d.PathLineTo(o + cur * radius * ratio);
if (next is { } nextValue)
d.PathLineTo(o + nextValue * radius);
d.PathFillConvex(color);
}
public static void Arc(float startAngle, float endAngle, float radius, float ratio, uint backgroundColor, uint filledColor, bool addDummy = true)
{
// Fix normals when drawing (for antialiasing)
if (startAngle > endAngle)
(startAngle, endAngle) = (endAngle, startAngle);
var offset = ImGui.GetCursorScreenPos() + new Vector2(radius);
var segments = ImGui.GetWindowDrawList()._CalcCircleAutoSegmentCount(radius * 2);
var incrementAngle = MathF.Tau / segments;
var isFullCircle = (endAngle - startAngle) % MathF.Tau == 0;
var prevA = startAngle;
var prev = UnitCircle(prevA);
for (var i = 1; i <= segments; ++i)
{
var a = startAngle + incrementAngle * i;
var cur = UnitCircle(a);
var nextA = a + incrementAngle;
var next = UnitCircle(nextA);
// full segment is background
if (prevA >= endAngle)
{
// don't overlap with the first segment
if (i == segments && !isFullCircle)
ArcSegment(offset, prev, cur, null, radius, ratio, backgroundColor);
else
ArcSegment(offset, prev, cur, next, radius, ratio, backgroundColor);
}
// segment is partially filled
else if (a > endAngle && !isFullCircle)
{
// we split the drawing in two
var end = UnitCircle(endAngle);
ArcSegment(offset, prev, end, null, radius, ratio, filledColor);
ArcSegment(offset, end, cur, next, radius, ratio, backgroundColor);
// set the previous segment to endAngle
a = endAngle;
cur = end;
}
// full segment is filled
else
{
// if the next segment will be partially filled, the next segment will be the endAngle
if (nextA > endAngle && !isFullCircle)
{
var end = UnitCircle(endAngle);
ArcSegment(offset, prev, cur, end, radius, ratio, filledColor);
}
else
ArcSegment(offset, prev, cur, next, radius, ratio, filledColor);
}
prevA = a;
prev = cur;
}
if (addDummy)
ImGui.Dummy(new Vector2(radius * 2));
}
public static void ArcProgress(float value, float radiusInner, float radiusOuter, uint backgroundColor, uint filledColor)
{
Arc(MathF.PI / 2, MathF.PI / 2 - MathF.Tau * Math.Clamp(value, 0, 1), radiusInner, radiusOuter, backgroundColor, filledColor);
}
public static bool IconButtonSized(FontAwesomeIcon icon, Vector2 size)
{
ImGui.PushFont(UiBuilder.IconFont);
@@ -155,16 +246,18 @@ internal static class ImGuiUtils
}
}
public static void AlignCentered(float width)
public static void AlignCentered(float width, float availWidth = default)
{
var availWidth = ImGui.GetContentRegionAvail().X;
if (availWidth == default)
availWidth = ImGui.GetContentRegionAvail().X;
if (availWidth > width)
ImGui.SetCursorPosX(ImGui.GetCursorPos().X + (availWidth - width) / 2);
}
public static void AlignMiddle(Vector2 size)
public static void AlignMiddle(Vector2 size, Vector2 availSize = default)
{
var availSize = ImGui.GetContentRegionAvail();
if (availSize == default)
availSize = ImGui.GetContentRegionAvail();
if (availSize.X > size.X)
ImGui.SetCursorPosX(ImGui.GetCursorPos().X + (availSize.X - size.X) / 2);
if (availSize.Y > size.Y)
@@ -172,21 +265,34 @@ internal static class ImGuiUtils
}
// https://stackoverflow.com/a/67855985
public static void TextCentered(string text)
public static void TextCentered(string text, float availWidth = default)
{
AlignCentered(ImGui.CalcTextSize(text).X);
AlignCentered(ImGui.CalcTextSize(text).X, availWidth);
ImGui.TextUnformatted(text);
}
public static void TextMiddle(string text)
public static void TextMiddle(string text, Vector2 availSize = default)
{
AlignMiddle(ImGui.CalcTextSize(text));
AlignMiddle(ImGui.CalcTextSize(text), availSize);
ImGui.TextUnformatted(text);
}
public static bool ButtonCentered(string text)
public static void TextMiddleNewLine(string text, Vector2 availSize)
{
AlignCentered(ImGui.CalcTextSize(text).X + ImGui.GetStyle().FramePadding.Y * 2);
return ImGui.Button(text);
if (availSize == default)
availSize = ImGui.GetContentRegionAvail();
var c = ImGui.GetCursorPos();
AlignMiddle(ImGui.CalcTextSize(text), availSize);
ImGui.TextUnformatted(text);
ImGui.SetCursorPos(c + new Vector2(0, availSize.Y + ImGui.GetStyle().ItemSpacing.Y - 1));
}
public static bool ButtonCentered(string text, Vector2 buttonSize = default)
{
var buttonWidth = buttonSize.X;
if (buttonSize == default)
buttonWidth = ImGui.CalcTextSize(text).X + ImGui.GetStyle().FramePadding.X * 2;
AlignCentered(buttonWidth);
return ImGui.Button(text, buttonSize);
}
}