feat(D.5.1): wrap toolbar in UiNineSlicePanel chrome frame (mirrors chat window)

The toolbar LayoutDesc (0x21000016, 300x122) was mounted bare — no window
chrome. This commit wraps it in a UiNineSlicePanel (the same 8-piece bevel +
gold grip chrome used by the vitals and chat windows), matching the pattern at
GameWindow.cs ~line 1885 verbatim.

- toolbarFrame is the top-level UiNineSlicePanel (Draggable=true, Anchors=None
  per UiNineSlicePanel ctor defaults). Outer size = 310x132 (300+2*5 x 122+2*5).
- toolbarRoot sits inside at offset (5,5) — the border thickness — with all-edge
  anchors so it reflows if the frame is resized. Draggable=false, Resizable=false
  on the content (only the frame is the drag handle).
- The frame's right border (x=305..310 screen) covers the row-2 right cap
  overhang (~2px past the content edge at x=300..302), since the border region
  starts at content_right=300 and extends to frame_right=310.
- Probe block untouched: still calls toolbarLayout.FindElement for diagnostic ids.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-17 15:53:53 +02:00
parent 8d49042909
commit b37db79a23

View file

@ -2010,15 +2010,34 @@ public sealed class GameWindow : IDisposable
emptyDigits: toolbarEmptyDigits); emptyDigits: toolbarEmptyDigits);
var toolbarRoot = toolbarLayout.Root; var toolbarRoot = toolbarLayout.Root;
toolbarRoot.Left = 10; toolbarRoot.Top = 300; // Wrap the dat content in the universal 8-piece beveled window chrome —
// D1: Anchors=None so ApplyAnchor skips re-pinning every frame and // the SAME UiNineSlicePanel used by the vitals and chat windows. The
// the drag position is preserved (matches vitalsRoot pattern). // toolbar LayoutDesc (0x21000016) is 300×122; the frame adds one border
toolbarRoot.Anchors = AcDream.App.UI.AnchorEdges.None; // thickness on every side, giving an outer window of 310×132.
// D2: UiDatElement ctor defaults ClickThrough=true; override so the const int toolbarBorder = AcDream.App.UI.RetailChromeSprites.Border;
// chrome is hittable and the drag can start (matches vitalsRoot pattern). float toolbarContentW = 300f, toolbarContentH = toolbarRoot.Height;
var toolbarFrame = new AcDream.App.UI.UiNineSlicePanel(ResolveChrome)
{
Left = 10, Top = 300,
Width = toolbarContentW + 2 * toolbarBorder,
Height = toolbarContentH + 2 * toolbarBorder,
// The toolbar is fully opaque (not translucent like the chat window).
Opacity = 1.0f,
};
// Content is offset by the border so it sits inside the chrome.
toolbarRoot.Left = toolbarBorder;
toolbarRoot.Top = toolbarBorder;
toolbarRoot.Width = toolbarContentW;
toolbarRoot.Height = toolbarContentH;
// Anchor content to all four edges so it reflows if the frame is resized.
toolbarRoot.Anchors = AcDream.App.UI.AnchorEdges.Left | AcDream.App.UI.AnchorEdges.Top
| AcDream.App.UI.AnchorEdges.Right | AcDream.App.UI.AnchorEdges.Bottom;
// The frame is the draggable window; the content itself is not.
toolbarRoot.ClickThrough = false; toolbarRoot.ClickThrough = false;
toolbarRoot.Draggable = true; toolbarRoot.Draggable = false;
_uiHost.Root.AddChild(toolbarRoot); toolbarRoot.Resizable = false;
toolbarFrame.AddChild(toolbarRoot);
_uiHost.Root.AddChild(toolbarFrame);
// [D.5.1 PROBE] Bottom-right geometry rect dump — temporary diagnostic. // [D.5.1 PROBE] Bottom-right geometry rect dump — temporary diagnostic.
// Localises the bottom-right mismatch reported by the user; remove once fixed. // Localises the bottom-right mismatch reported by the user; remove once fixed.