From 06c42882821488e0b19c93b8fa58d7f8d5f10cb9 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 21 Jun 2026 20:55:50 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20D.2b=20inventory=20finish=20?= =?UTF-8?q?=E2=80=94=20window=20chrome=20frame=20(UiNineSlicePanel)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wrap the gmInventoryUI content in the universal 8-piece beveled chrome (same UiNineSlicePanel as vitals/chat/toolbar), so the inventory has a proper window frame like every other window. The frame is the draggable window + the F12- toggled registered window; the dat content sits inside it offset by the border. Reused as the base for the vertical-resize step next. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 31 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) 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 +