feat(studio): dump LayoutSource — preview any retail window from the UI dump
Adds Task 4b: a second load path for the UI Studio that reads the committed retail UI layout dump (docs/research/2026-06-25-retail-ui-layout-dump.json) and renders any of the 26 retail windows as a static sprite hierarchy. New files: - src/AcDream.App/Studio/UiDumpModel.cs — POCOs + System.Text.Json parse of the dump (UiDump, DumpPanel, DumpNode, DumpRect, DumpStateSet, DumpImage, DumpState + UiDumpModel static helpers: Parse, ListSlugs, PickImageId). - src/AcDream.App/Studio/DumpLayout.cs — DumpLayout.Load(path, slug, resolve, out err): parses the dump, finds the panel by slug, builds a UiElement tree. Internal DumpSpriteElement draws its sprite via DrawSprite (not reusing UiDatElement — avoids the ElementInfo/StateMedia dat-import dependency for this static mockup). DumpGroupElement is a transparent container for Group nodes. Rect basis is ABSOLUTE in the dump (verified: inventory root at absolute x=500 and its children also start at x≈500 — child offset from parent is 0–50px, not 500px); DumpLayout subtracts parent rect to produce parent-relative Left/Top for each child. - tests/AcDream.App.Tests/Studio/DumpLayoutTests.cs — 5 tests covering: inventory load with 0x100001D5 check + >= 40 nodes, unknown slug → null+err, root at origin, children are parent-relative, all 26 slugs smoke-load. Modified files: - StudioOptions: adds DumpSlug + DumpFile fields; --dump <slug> and --dump-file <path> args; ResolveDumpFile() walks up to the solution root to find the default dump JSON (mirrors ConformanceDats.SolutionRoot()). --dump suppresses the default vitals layout so the two modes are exclusive. - StudioWindow.OnLoad: when DumpSlug is set, loads via DumpLayout (no FixtureProvider, no controllers — static structure only); else falls through to the existing LayoutSource + FixtureProvider path. Results: DumpLayoutTests 5/5 passed; full AcDream.App.Tests 609 passed, 2 skipped (same as before); dotnet build green, 0 warnings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9ed9d8dbd9
commit
e3de7f0dab
6 changed files with 117572 additions and 10 deletions
|
|
@ -117,8 +117,34 @@ public sealed class StudioWindow : IDisposable
|
|||
_stack.UiHost.WireKeyboard(kb);
|
||||
|
||||
// Load the panel described by options and add it to the UI tree.
|
||||
// Task 4b: --dump <slug> uses DumpLayout (static retail mockup, no controllers).
|
||||
// All other modes use LayoutSource + FixtureProvider (production path).
|
||||
_source = new LayoutSource(_dats, _stack.ResolveChrome, _stack.VitalsDatFont);
|
||||
var root = _source.Load(_opts);
|
||||
UiElement? root;
|
||||
if (_opts.DumpSlug is not null)
|
||||
{
|
||||
var dumpFile = _opts.ResolveDumpFile();
|
||||
if (dumpFile is null)
|
||||
{
|
||||
Console.Error.WriteLine("[studio] --dump: retail UI dump file not found. " +
|
||||
"Expected docs/research/2026-06-25-retail-ui-layout-dump.json in the source tree, " +
|
||||
"or pass --dump-file <path>.");
|
||||
root = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
root = DumpLayout.Load(dumpFile, _opts.DumpSlug, _stack.ResolveChrome, out var dumpErr);
|
||||
if (root is null)
|
||||
Console.Error.WriteLine($"[studio] dump load failed: {dumpErr}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
root = _source.Load(_opts);
|
||||
if (root is null)
|
||||
Console.Error.WriteLine($"[studio] panel load failed: {_source.LastError}");
|
||||
}
|
||||
|
||||
_panelRoot = root;
|
||||
if (root is not null)
|
||||
{
|
||||
|
|
@ -126,15 +152,14 @@ public sealed class StudioWindow : IDisposable
|
|||
|
||||
// Task 4: populate the panel with sample data via production controllers,
|
||||
// so inventory / vitals / toolbar panels render with plausible content.
|
||||
if (_source.CurrentLayout is not null)
|
||||
// Dump source is static — no FixtureProvider needed.
|
||||
if (_opts.DumpSlug is null && _source.CurrentLayout is not null)
|
||||
{
|
||||
uint layoutId = _opts.LayoutId ?? 0x2100006Cu;
|
||||
_objects = SampleData.BuildObjectTable();
|
||||
FixtureProvider.Populate(layoutId, _source.CurrentLayout, _stack, _objects, _dats);
|
||||
}
|
||||
}
|
||||
else
|
||||
Console.Error.WriteLine($"[studio] panel load failed: {_source.LastError}");
|
||||
|
||||
// Task 3: ImGui IDE. The studio is always "devtools" — no gate flag needed.
|
||||
_imgui = new AcDream.UI.ImGui.ImGuiBootstrapper(gl, _window!, input);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue