fix(ui): share primary panel placement

Port gmPanelUI's persistent parent placement semantics across Inventory, Character, and Magic while preserving each imported child's content and resize policy. Synchronize typed retained-window handles so drag, switching, close/reopen, and layout persistence all observe one canonical location; keep effect panels independent.

User-verified in normal Release. Release build and all 5,770 tests passed with five intentional skips.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-17 09:13:31 +02:00
parent 124e046976
commit 3f3cfdac30
7 changed files with 460 additions and 9 deletions

View file

@ -784,7 +784,7 @@ public sealed class RetailUiRuntime : IDisposable
SpellbookWindowController = controller;
UiElement root = layout.Root;
RetailWindowFrame.Mount(
RetailWindowHandle handle = RetailWindowFrame.Mount(
Host.Root,
root,
_bindings.Assets.ResolveSprite,
@ -805,7 +805,10 @@ public sealed class RetailUiRuntime : IDisposable
ContentClickThrough = false,
Controller = controller,
});
_panelUi.Register(RetailPanelCatalog.Magic, WindowNames.Spellbook);
_panelUi.RegisterMainPanel(
RetailPanelCatalog.Magic,
WindowNames.Spellbook,
handle);
Console.WriteLine("[M3] retail spellbook/component book from LayoutDesc 0x21000034.");
}
@ -1134,7 +1137,10 @@ public sealed class RetailUiRuntime : IDisposable
_bindings.Assets.ResolveSprite,
(request, completed) => HandleCharacterRaise(provider, request, completed),
() => CloseWindow(WindowNames.Character));
RetailWindowFrame.Mount(Host.Root, layout.Root, _bindings.Assets.ResolveSprite,
RetailWindowHandle handle = RetailWindowFrame.Mount(
Host.Root,
layout.Root,
_bindings.Assets.ResolveSprite,
new RetailWindowFrame.Options
{
WindowName = WindowNames.Character,
@ -1149,7 +1155,10 @@ public sealed class RetailUiRuntime : IDisposable
ContentAnchors = AnchorEdges.Left | AnchorEdges.Top | AnchorEdges.Bottom,
ContentClickThrough = false,
});
_panelUi.Register(RetailPanelCatalog.Character, WindowNames.Character);
_panelUi.RegisterMainPanel(
RetailPanelCatalog.Character,
WindowNames.Character,
handle);
Console.WriteLine("[D.2b-C] retail character window from LayoutDesc importer (0x2100002E).");
}
@ -1231,7 +1240,10 @@ public sealed class RetailUiRuntime : IDisposable
Host.Root.Height - root.Top),
ContentAnchors = AnchorEdges.Left | AnchorEdges.Top | AnchorEdges.Bottom,
});
_panelUi.Register(RetailPanelCatalog.Inventory, WindowNames.Inventory);
_panelUi.RegisterMainPanel(
RetailPanelCatalog.Inventory,
WindowNames.Inventory,
handle);
uint contents, sideBag, mainPack;
IReadOnlyDictionary<uint, uint> paperdollEmptySprites;
@ -1280,6 +1292,7 @@ public sealed class RetailUiRuntime : IDisposable
_itemConfirmationController?.Dispose();
_gameplayConfirmationController?.Dispose();
DialogFactory?.Dispose();
_panelUi.Dispose();
Host.Dispose();
}
}