using System.Numerics; namespace AcDream.UI.Abstractions.Tests; /// /// In-memory test double for . Records every /// widget call so tests can assert against the recorded trace without /// running an ImGui context. New widgets added to the interface must /// implement here too — that compilation error IS the TDD red signal. /// internal sealed class FakePanelRenderer : IPanelRenderer { /// Ordered list of (method, args) pairs recorded across this renderer's lifetime. public List<(string Method, object?[] Args)> Calls { get; } = new(); /// If is called, return this value. Defaults to true so panels render. public bool BeginReturns { get; set; } = true; // -- Inputs the panel under test can mutate via ref args ----------- /// Pre-set return value for the next — caller flips bool to simulate user click. public bool CheckboxNextReturn { get; set; } public bool? CheckboxNextValue { get; set; } /// Pre-set return value for the next — caller sets to simulate user click. public bool ButtonNextReturn { get; set; } /// Pre-set return value for the next . public bool ComboNextReturn { get; set; } public int? ComboNextSelectedIndex { get; set; } /// Pre-set return for . public bool SliderFloatNextReturn { get; set; } public float? SliderFloatNextValue { get; set; } /// Pre-set return for . public bool CollapsingHeaderNextReturn { get; set; } = true; /// Pre-set return for . public bool TreeNodeNextReturn { get; set; } = true; /// Pre-set return for . public bool BeginTableNextReturn { get; set; } = true; /// Pre-set return for . public bool BeginChildNextReturn { get; set; } = true; /// Pre-set return value for . public float FrameHeightWithSpacingValue { get; set; } = 24f; /// Pre-set "submitted" string for the next ; null = no submit this frame. public string? InputTextSubmitNextSubmitted { get; set; } public string? InputTextSubmitNextBufferAfter { get; set; } public bool Begin(string title) { Calls.Add(("Begin", new object?[] { title })); return BeginReturns; } public void End() => Calls.Add(("End", Array.Empty())); public void Text(string text) => Calls.Add(("Text", new object?[] { text })); public void SameLine() => Calls.Add(("SameLine", Array.Empty())); public void Separator() => Calls.Add(("Separator", Array.Empty())); public void ProgressBar(float fraction, float width, string? overlay = null) => Calls.Add(("ProgressBar", new object?[] { fraction, width, overlay })); public void TextColored(Vector4 rgba, string text) => Calls.Add(("TextColored", new object?[] { rgba, text })); public bool CollapsingHeader(string label, bool defaultOpen = true) { Calls.Add(("CollapsingHeader", new object?[] { label, defaultOpen })); return CollapsingHeaderNextReturn; } public bool TreeNode(string label) { Calls.Add(("TreeNode", new object?[] { label })); return TreeNodeNextReturn; } public void TreePop() => Calls.Add(("TreePop", Array.Empty())); public bool Checkbox(string label, ref bool value) { Calls.Add(("Checkbox", new object?[] { label, value })); if (CheckboxNextValue is bool nv) value = nv; return CheckboxNextReturn; } public bool Button(string label) { Calls.Add(("Button", new object?[] { label })); return ButtonNextReturn; } public bool Combo(string label, ref int selectedIndex, string[] items) { Calls.Add(("Combo", new object?[] { label, selectedIndex, items })); if (ComboNextSelectedIndex is int idx) selectedIndex = idx; return ComboNextReturn; } public bool SliderFloat(string label, ref float value, float min, float max) { Calls.Add(("SliderFloat", new object?[] { label, value, min, max })); if (SliderFloatNextValue is float v) value = v; return SliderFloatNextReturn; } public void PlotLines( string label, float[] values, int count, int offset = 0, string? overlay = null, float? min = null, float? max = null, Vector2? size = null) => Calls.Add(("PlotLines", new object?[] { label, values, count, offset, overlay, min, max, size })); public void BeginTable(string id, int columns) => Calls.Add(("BeginTable", new object?[] { id, columns })); public void TableNextColumn() => Calls.Add(("TableNextColumn", Array.Empty())); public void EndTable() => Calls.Add(("EndTable", Array.Empty())); public bool InputTextSubmit(string label, ref string buffer, int maxLen, out string? submitted) { Calls.Add(("InputTextSubmit", new object?[] { label, buffer, maxLen })); submitted = InputTextSubmitNextSubmitted; if (submitted is not null) buffer = InputTextSubmitNextBufferAfter ?? string.Empty; return submitted is not null; } public void Spacing() => Calls.Add(("Spacing", Array.Empty())); public void Dummy(Vector2 size) => Calls.Add(("Dummy", new object?[] { size })); public void TextWrapped(string text) => Calls.Add(("TextWrapped", new object?[] { text })); public bool BeginChild(string id, Vector2 size, bool border = false) { Calls.Add(("BeginChild", new object?[] { id, size, border })); return BeginChildNextReturn; } public void EndChild() => Calls.Add(("EndChild", Array.Empty())); public float FrameHeightWithSpacing() { Calls.Add(("FrameHeightWithSpacing", Array.Empty())); return FrameHeightWithSpacingValue; } public void SetScrollHereY(float ratio) => Calls.Add(("SetScrollHereY", new object?[] { ratio })); }