diff --git a/Craftimizer/ImGuiExtras.cs b/Craftimizer/ImGuiExtras.cs index a90ba0f..6583adc 100644 --- a/Craftimizer/ImGuiExtras.cs +++ b/Craftimizer/ImGuiExtras.cs @@ -22,6 +22,12 @@ internal static unsafe class ImGuiExtras [DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)] private static extern bool igItemSize_Vec2(Vector2 size, float text_baseline_y = -1.0f); + [DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)] + private static extern void igRenderFrame(Vector2 p_min, Vector2 p_max, uint fill_col, bool border = true, float rounding = 0.0f); + + [DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)] + private static extern void igRenderRectFilledRangeH(ImDrawList* draw_list, Vector4* rect, uint col, float x_start_norm, float x_end_norm, float rounding); + [DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)] private static extern ImGuiItemFlags igGetItemFlags(); @@ -149,7 +155,10 @@ internal static unsafe class ImGuiExtras return result != 0; } - public static unsafe bool ItemAdd(Vector4 bb, uint id, out Vector4 navBb, uint flags) + public static unsafe bool ItemAdd(Vector4 bb, uint id) => + ItemAdd(bb, id, out _); + + public static unsafe bool ItemAdd(Vector4 bb, uint id, out Vector4 navBb, uint flags = 0) { fixed (Vector4* navBbPtr = &navBb) { @@ -166,6 +175,12 @@ internal static unsafe class ImGuiExtras } } + public static unsafe void RenderFrame(Vector2 p_min, Vector2 p_max, uint fill_col, bool border = true, float rounding = 0.0f) => + igRenderFrame(p_min, p_max, fill_col, border, rounding); + + public static unsafe void RenderRectFilledRangeH(ImDrawListPtr draw_list, Vector4 rect, uint col, float x_start_norm, float x_end_norm, float rounding) => + igRenderRectFilledRangeH(draw_list.NativePtr, &rect, col, x_start_norm, x_end_norm, rounding); + public static unsafe bool ItemSize(Vector2 size, float text_baseline_y = -1.0f) => igItemSize_Vec2(size, text_baseline_y); diff --git a/Craftimizer/ImGuiUtils.cs b/Craftimizer/ImGuiUtils.cs index 3f9a43b..45c005e 100644 --- a/Craftimizer/ImGuiUtils.cs +++ b/Craftimizer/ImGuiUtils.cs @@ -247,6 +247,38 @@ internal static class ImGuiUtils Arc(startAngle, endAngle, radius, ratio, backgroundColor, filledColor); } + public static void ProgressBar(float value, Vector2 size) + { + var style = ImGui.GetStyle(); + var pos = ImGui.GetCursorScreenPos(); + + //size = ImGuiExtras.CalcItemSize(size, ImGui.CalcItemWidth(), ImGui.GetFontSize() + style.FramePadding.Y * 2.0f); + + var bbMin = pos; + var bbMax = pos + size; + ImGuiExtras.ItemSize(size, style.FramePadding.Y); + if (!ImGuiExtras.ItemAdd(new(bbMin.X, bbMin.Y, bbMax.X, bbMax.Y), 0)) + return; + + var bar_begin = 0.0f; + var bar_end = Math.Clamp(value, 0, 1); + + var indeterminate = value < 0.0f; + if (indeterminate) + { + const float bar_fraction = 0.2f; + bar_begin = (-value % 1.0f * (1.0f + bar_fraction)) - bar_fraction; + bar_end = bar_begin + bar_fraction; + } + + ImGuiExtras.RenderFrame(bbMin, bbMax, ImGui.GetColorU32(ImGuiCol.FrameBg), true, style.FrameRounding); + + bbMin += new Vector2(style.FrameBorderSize); + bbMax -= new Vector2(style.FrameBorderSize); + + ImGuiExtras.RenderRectFilledRangeH(ImGui.GetWindowDrawList(), new(bbMin.X, bbMin.Y, bbMax.X, bbMax.Y), ImGui.GetColorU32(ImGuiCol.PlotHistogram), bar_begin, bar_end, style.FrameRounding); + } + public sealed class ViolinData { public struct Point(float x, float y, float y2) diff --git a/Craftimizer/Utils/DynamicBars.cs b/Craftimizer/Utils/DynamicBars.cs index 493e21f..bacb877 100644 --- a/Craftimizer/Utils/DynamicBars.cs +++ b/Craftimizer/Utils/DynamicBars.cs @@ -88,7 +88,7 @@ internal static class DynamicBars var pos = ImGui.GetCursorPos(); var screenPos = ImGui.GetCursorScreenPos(); using (var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, bar.Color)) - ImGui.ProgressBar(Math.Clamp(bar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty); + ImGuiUtils.ProgressBar(Math.Clamp(bar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight())); if (bar.Collectability is { } collectability) { var i = 0; @@ -188,19 +188,28 @@ internal static class DynamicBars } var percentWidth = ImGui.CalcTextSize("100%").X; - var progressWidth = availSpace.Value - percentWidth - spacing; + var progressWidth = availSpace.Value; var progressColors = Colors.GetSolverProgressColors(solver.ProgressStage); fraction = Math.Clamp(fraction, 0, 1); + if (!solver.IsIndeterminate) + progressWidth -= percentWidth + spacing; + else + fraction = (float)-ImGui.GetTime() * .5f; + using (ImRaii.PushColor(ImGuiCol.FrameBg, progressColors.Background)) using (ImRaii.PushColor(ImGuiCol.PlotHistogram, progressColors.Foreground)) - ImGui.ProgressBar(solver.IsIndeterminate ? (float)-ImGui.GetTime() : fraction, new(progressWidth, ImGui.GetFrameHeight()), string.Empty); + ImGuiUtils.ProgressBar(fraction, new(progressWidth, ImGui.GetFrameHeight())); if (ImGui.IsItemHovered()) DrawProgressBarTooltip(solver); - ImGui.SameLine(0, spacing); - ImGui.AlignTextToFramePadding(); - ImGuiUtils.TextRight($"{fraction * 100:N0}%", percentWidth); + + if (!solver.IsIndeterminate) + { + ImGui.SameLine(0, spacing); + ImGui.AlignTextToFramePadding(); + ImGuiUtils.TextRight($"{fraction * 100:N0}%", percentWidth); + } } public static void DrawProgressBarTooltip(Solver.Solver solver)