Finish crafting log helper window
This commit is contained in:
+117
-11
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user