diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index a2832cc3..7f8063ff 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -2150,12 +2150,31 @@ public sealed class GameWindow : IDisposable _dats!, 0x21000023u, ResolveChrome, vitalsDatFont); if (invLayout is not null) { - var inventoryWindow = invLayout.Root; - inventoryWindow.Visible = false; - inventoryWindow.Anchors = AcDream.App.UI.AnchorEdges.None; // user-positioned - inventoryWindow.Draggable = true; - _uiHost.Root.AddChild(inventoryWindow); - _uiHost.RegisterWindow(AcDream.App.UI.WindowNames.Inventory, inventoryWindow); + var inventoryRoot = invLayout.Root; + // Wrap the dat content in the universal 8-piece beveled window chrome — the + // SAME UiNineSlicePanel the vitals/chat/toolbar windows use. The gmInventoryUI + // LayoutDesc (0x21000023) is 300×362; the frame adds one border thickness on + // every side. The frame is the draggable window; the dat content sits inside it. + const int invBorder = AcDream.App.UI.RetailChromeSprites.Border; + float invContentW = inventoryRoot.Width, invContentH = inventoryRoot.Height; + var inventoryFrame = new AcDream.App.UI.UiNineSlicePanel(ResolveChrome) + { + Left = inventoryRoot.Left, Top = inventoryRoot.Top, // keep the dat window position + Width = invContentW + 2 * invBorder, + Height = invContentH + 2 * invBorder, + Opacity = 1.0f, + Visible = false, // F12 toggles it + Anchors = AcDream.App.UI.AnchorEdges.None, // user-positioned + Draggable = true, + }; + // Content offset by the border so it sits inside the chrome. + inventoryRoot.Left = invBorder; inventoryRoot.Top = invBorder; + inventoryRoot.Width = invContentW; inventoryRoot.Height = invContentH; + inventoryRoot.Anchors = AcDream.App.UI.AnchorEdges.Left | AcDream.App.UI.AnchorEdges.Top; + inventoryRoot.Draggable = false; + inventoryFrame.AddChild(inventoryRoot); + _uiHost.Root.AddChild(inventoryFrame); + _uiHost.RegisterWindow(AcDream.App.UI.WindowNames.Inventory, inventoryFrame); // Phase D.2b-B — populate the inventory from ClientObjectTable: the // "Contents of Backpack" grid + the pack-selector strip + the burden meter +