From 72befe8049f7b66509f46e519eef2d169add3219 Mon Sep 17 00:00:00 2001 From: Asriel Camora Date: Wed, 15 Nov 2023 02:53:10 -0800 Subject: [PATCH] Move dynamic bars to dedicated helper class --- Craftimizer/Utils/DynamicBars.cs | 91 +++++++++++++++++++++++++ Craftimizer/Windows/MacroEditor.cs | 105 +++++++++++++++-------------- 2 files changed, 147 insertions(+), 49 deletions(-) create mode 100644 Craftimizer/Utils/DynamicBars.cs diff --git a/Craftimizer/Utils/DynamicBars.cs b/Craftimizer/Utils/DynamicBars.cs new file mode 100644 index 0000000..a768ba4 --- /dev/null +++ b/Craftimizer/Utils/DynamicBars.cs @@ -0,0 +1,91 @@ +using Craftimizer.Plugin; +using Dalamud.Interface.Utility.Raii; +using ImGuiNET; +using System.Collections.Generic; +using System; +using System.Numerics; +using System.Linq; + +namespace Craftimizer.Utils; + +internal static class DynamicBars +{ + public readonly record struct BarData(string Name, Vector4 Color, SimulatedMacro.Reliablity.Param? Reliability, float Value, float Max, string? Caption = null, Action? CustomDrawer = null) + { + public BarData(string name, Action customDrawer) : this(name, default, null, 0, 0, null, customDrawer) + { + + } + + public BarData(string name, Vector4 color, float value, float max) : this(name, color, null, value, max, null, null) + { + + } + } + + public readonly record struct DrawerParams(float TotalSize, float Spacing); + + public static float GetTextSize(IEnumerable bars) => + bars.Max(b => + { + if (b.CustomDrawer is { }) + return 0; + if (b.Caption is { } caption) + return ImGui.CalcTextSize(caption).X; + // max (sp/2) "/" (sp/2) max + return Math.Max(ImGui.CalcTextSize($"{b.Value:0}").X, ImGui.CalcTextSize($"{b.Max:0}").X) * 2 + + ImGui.GetStyle().ItemSpacing.X + + ImGui.CalcTextSize("/").X; + }); + + public static void Draw(IEnumerable bars, float? textSize = null) + { + var spacing = ImGui.GetStyle().ItemSpacing.X; + var totalSize = ImGui.GetContentRegionAvail().X; + totalSize -= 2 * spacing; + textSize ??= GetTextSize(bars); + var maxSize = (textSize.Value - 2 * spacing - ImGui.CalcTextSize("/").X) / 2; + var barSize = totalSize - textSize.Value - spacing; + foreach (var bar in bars) + { + using var panel = ImRaii2.GroupPanel(bar.Name, totalSize, out _); + if (bar.CustomDrawer is { } drawer) + drawer(new(totalSize, spacing)); + else + { + var pos = ImGui.GetCursorPos(); + 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); + if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenOverlapped)) + { + if (bar.Reliability is { } reliability) + { + if (reliability.GetViolinData(bar.Max, (int)(barSize / 5), 0.02) is { } violinData) + { + ImGui.SetCursorPos(pos); + ImGuiUtils.ViolinPlot(violinData, new(barSize, ImGui.GetFrameHeight())); + if (ImGui.IsItemHovered()) + ImGui.SetTooltip( + $"Min: {reliability.Min}\n" + + $"Med: {reliability.Median:0.##}\n" + + $"Avg: {reliability.Average:0.##}\n" + + $"Max: {reliability.Max}"); + } + } + } + ImGui.SameLine(0, spacing); + ImGui.AlignTextToFramePadding(); + if (bar.Caption is { } caption) + ImGuiUtils.TextRight(caption, textSize.Value); + else + { + ImGuiUtils.TextRight($"{bar.Value:0}", maxSize); + ImGui.SameLine(0, spacing / 2); + ImGui.Text("/"); + ImGui.SameLine(0, spacing / 2); + ImGuiUtils.TextRight($"{bar.Max:0}", maxSize); + } + } + } + } +} diff --git a/Craftimizer/Windows/MacroEditor.cs b/Craftimizer/Windows/MacroEditor.cs index c23bdc1..2dab731 100644 --- a/Craftimizer/Windows/MacroEditor.cs +++ b/Craftimizer/Windows/MacroEditor.cs @@ -985,32 +985,75 @@ public sealed class MacroEditor : Window, IDisposable ImGui.TableSetupColumn("col2", ImGuiTableColumnFlags.WidthStretch, 2); ImGui.TableNextColumn(); - var datas = new List(3) + void DrawCondition(DynamicBars.DrawerParams drawerParams) { - new("Durability", Colors.Durability, null, State.Durability, RecipeData.RecipeInfo.MaxDurability, null, null), - new("Condition", default, null, 0, 0, null, State.Condition) + var (totalSize, spacing) = drawerParams; + var condition = State.Condition; + + var pos = ImGui.GetCursorPos(); + using (var g = ImRaii.Group()) + { + var availSize = totalSize - (spacing + ImGui.GetFrameHeight()); + var size = ImGui.GetFrameHeight() + spacing + ImGui.CalcTextSize(condition.Name()).X; + + ImGuiUtils.AlignCentered(size, availSize); + ImGui.GetWindowDrawList().AddCircleFilled( + ImGui.GetCursorScreenPos() + new Vector2(ImGui.GetFrameHeight() / 2), + ImGui.GetFrameHeight() / 2, + ImGui.ColorConvertFloat4ToU32(new Vector4(.35f, .35f, .35f, 0) + condition.GetColor(DateTime.UtcNow.TimeOfDay))); + ImGui.Dummy(new(ImGui.GetFrameHeight())); + ImGui.SameLine(0, spacing); + ImGui.AlignTextToFramePadding(); + ImGui.Text(condition.Name()); + } + if (ImGui.IsItemHovered()) + ImGui.SetTooltip(condition.Description(CharacterStats.HasSplendorousBuff).Replace("%", "%%")); + + ImGui.SetCursorPos(pos); + ImGuiUtils.AlignRight(ImGui.GetFrameHeight(), totalSize); + + using (var disabled = ImRaii.Disabled(SolverRunning)) + { + using var tint = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !Service.Configuration.ConditionRandomness); + if (ImGuiUtils.IconButtonSquare(FontAwesomeIcon.Dice)) + { + Service.Configuration.ConditionRandomness ^= true; + Service.Configuration.Save(); + + RecalculateState(); + } + } + if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) + ImGui.SetTooltip("Condition Randomness\n" + + "Allows the condition to fluctuate randomly like a real craft.\n" + + "Turns off when generating a macro."); + } + var datas = new List(3) + { + new("Durability", Colors.Durability, State.Durability, RecipeData.RecipeInfo.MaxDurability), + new("Condition", DrawCondition) }; if (RecipeData.Recipe.ItemResult.Value!.IsCollectable) - datas.Add(new("Collectability", Colors.HQ, Reliability.ParamScore, State.Collectability, State.MaxCollectability, $"{State.Collectability}", null)); + datas.Add(new("Collectability", Colors.HQ, Reliability.ParamScore, State.Collectability, State.MaxCollectability, $"{State.Collectability}")); else if (RecipeData.Recipe.RequiredQuality > 0) { var qualityPercent = (float)State.Quality / RecipeData.Recipe.RequiredQuality * 100; - datas.Add(new("Quality %%", Colors.HQ, Reliability.ParamScore, qualityPercent, 100, $"{qualityPercent:0}%", null)); + datas.Add(new("Quality %%", Colors.HQ, Reliability.ParamScore, qualityPercent, 100, $"{qualityPercent:0}%")); } else if (RecipeData.RecipeInfo.MaxQuality > 0) - datas.Add(new("HQ %%", Colors.HQ, Reliability.ParamScore, State.HQPercent, 100, $"{State.HQPercent}%", null)); - DrawBars(datas); + datas.Add(new("HQ %%", Colors.HQ, Reliability.ParamScore, State.HQPercent, 100, $"{State.HQPercent}%")); + DynamicBars.Draw(datas); ImGui.TableNextColumn(); - datas = new List(3) + datas = new List(3) { - new("Progress", Colors.Progress, Reliability.Progress, State.Progress, RecipeData.RecipeInfo.MaxProgress, null, null), - new("Quality", Colors.Quality, Reliability.Quality, State.Quality, RecipeData.RecipeInfo.MaxQuality, null, null), - new("CP", Colors.CP, null, State.CP, CharacterStats.CP, null, null) + new("Progress", Colors.Progress, Reliability.Progress, State.Progress, RecipeData.RecipeInfo.MaxProgress), + new("Quality", Colors.Quality, Reliability.Quality, State.Quality, RecipeData.RecipeInfo.MaxQuality), + new("CP", Colors.CP, State.CP, CharacterStats.CP) }; if (RecipeData.RecipeInfo.MaxQuality <= 0) datas.RemoveAt(1); - DrawBars(datas); + DynamicBars.Draw(datas); } } @@ -1075,43 +1118,7 @@ public sealed class MacroEditor : Window, IDisposable using var panel = ImRaii2.GroupPanel(bar.Name, totalSize, out _); if (bar.Condition is { } condition) { - var pos = ImGui.GetCursorPos(); - using (var g = ImRaii.Group()) - { - var availSize = totalSize - (spacing + ImGui.GetFrameHeight()); - var size = ImGui.GetFrameHeight() + spacing + ImGui.CalcTextSize(condition.Name()).X; - - ImGuiUtils.AlignCentered(size, availSize); - ImGui.GetWindowDrawList().AddCircleFilled( - ImGui.GetCursorScreenPos() + new Vector2(ImGui.GetFrameHeight() / 2), - ImGui.GetFrameHeight() / 2, - ImGui.ColorConvertFloat4ToU32(new Vector4(.35f, .35f, .35f, 0) + condition.GetColor(DateTime.UtcNow.TimeOfDay))); - ImGui.Dummy(new(ImGui.GetFrameHeight())); - ImGui.SameLine(0, spacing); - ImGui.AlignTextToFramePadding(); - ImGui.Text(condition.Name()); - } - if (ImGui.IsItemHovered()) - ImGui.SetTooltip(condition.Description(CharacterStats.HasSplendorousBuff).Replace("%", "%%")); - - ImGui.SetCursorPos(pos); - ImGuiUtils.AlignRight(ImGui.GetFrameHeight(), totalSize); - - using (var disabled = ImRaii.Disabled(SolverRunning)) - { - using var tint = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !Service.Configuration.ConditionRandomness); - if (ImGuiUtils.IconButtonSquare(FontAwesomeIcon.Dice)) - { - Service.Configuration.ConditionRandomness ^= true; - Service.Configuration.Save(); - - RecalculateState(); - } - } - if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) - ImGui.SetTooltip("Condition Randomness\n" + - "Allows the condition to fluctuate randomly like a real craft.\n" + - "Turns off when generating a macro."); + } else {