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

@ -1,4 +1,5 @@
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.UI.Abstractions.Panels.Settings;
namespace AcDream.App.Tests.UI;
@ -28,6 +29,47 @@ public sealed class RetailWindowLayoutPersistenceTests : IDisposable
Assert.False(saved.Visible);
}
[Fact]
public void MainPanelMove_PersistsCanonicalPositionForEveryPrimaryChild()
{
var store = new SettingsStore(PathName);
var root = new UiRoot { Width = 800, Height = 600 };
RetailWindowHandle inventory = Mount(root, WindowNames.Inventory);
RetailWindowHandle character = Mount(root, WindowNames.Character);
inventory.Hide();
character.Hide();
using var panels = new RetailPanelUiController(
root.IsWindowVisible,
root.ShowWindow,
root.HideWindow);
panels.RegisterMainPanel(
RetailPanelCatalog.Inventory,
WindowNames.Inventory,
inventory);
panels.RegisterMainPanel(
RetailPanelCatalog.Character,
WindowNames.Character,
character);
using var persistence = new RetailWindowLayoutPersistence(
root.WindowManager,
store,
() => "Alice",
() => (800, 600));
panels.SetPanelVisibility(RetailPanelCatalog.Inventory, visible: true);
inventory.MoveTo(244f, 133f);
UiWindowLayout savedInventory = Assert.IsType<UiWindowLayout>(
store.LoadWindowLayout(
"Alice", "800x600", WindowNames.Inventory, default));
UiWindowLayout savedCharacter = Assert.IsType<UiWindowLayout>(
store.LoadWindowLayout(
"Alice", "800x600", WindowNames.Character, default));
Assert.Equal((244f, 133f), (savedInventory.X, savedInventory.Y));
Assert.Equal((244f, 133f), (savedCharacter.X, savedCharacter.Y));
}
[Fact]
public void Restore_ClampsBoundsAndReappliesPanelStateAndVisibility()
{