feat(D.2b): draw the window resize-grip overlay (gold ridges + corner studs)

The retail vitals window border is TWO layers, not one: the bevel chrome
(0x060074BF-C6) PLUS a resize-grip overlay on top — gold ridged edge strips
and a square corner stud at each corner. acdream only drew the bevel, so the
border looked plainer than retail and the corners lacked the little square
sprite the user spotted.

The overlay ids come from the vitals LayoutDesc 0x2100006C (elements
0x1000063B-0x10000642): corner stud 0x06006129 (same 5x5 at all four corners),
edge strips 0x0600612A/2C (top/bottom) and 0x0600612B/2D (left/right). They
have transparent gaps so the bevel shows through — both layers are drawn.
UiNineSlicePanel now draws the grip overlay (edges tiled via the existing
UV-repeat, corner studs 1:1) after the bevel, so every retail-chrome window
(vitals + chat) gets it.

Verified the grip sprites + the composited result headlessly: dump-sprite-sheet
(new CLI: composite arbitrary sprite ids magnified) showed 0x06006129 is a gold
stud and 0x0600612A-D are gold ridged strips; render-vitals-mockup now renders
the faithful default window with the overlay.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-15 11:05:18 +02:00
parent 73468be02a
commit 0f55599ba5
4 changed files with 105 additions and 13 deletions

View file

@ -45,4 +45,22 @@ public static class RetailChromeSprites
/// <summary>Border thickness in pixels = the corner/edge sprite size (5px).</summary>
public const int Border = 5;
// ── Resize-grip overlay ──────────────────────────────────────────────
// A second 8-piece layer drawn ON TOP of the bevel above: the gold ridged
// accents + square corner studs that frame a resizable retail window. From
// the vitals LayoutDesc 0x2100006C (elements 0x1000063B0x10000642): each
// corner is the same 5×5 stud (0x06006129); the edges are gold double-line
// strips tiled along each side. These have transparent gaps, so the bevel
// shows through — both layers are needed.
/// <summary>Corner grip stud, all four corners (5×5).</summary>
public const uint GripCorner = 0x06006129;
/// <summary>Top edge grip (10×5, tiled across).</summary>
public const uint GripTop = 0x0600612A;
/// <summary>Left edge grip (5×10, tiled down).</summary>
public const uint GripLeft = 0x0600612B;
/// <summary>Bottom edge grip (10×5).</summary>
public const uint GripBottom = 0x0600612C;
/// <summary>Right edge grip (5×10).</summary>
public const uint GripRight = 0x0600612D;
}

View file

@ -72,6 +72,19 @@ public sealed class UiNineSlicePanel : UiPanel
DrawStretched(ctx, RetailChromeSprites.CornerTR, r.TR);
DrawStretched(ctx, RetailChromeSprites.CornerBL, r.BL);
DrawStretched(ctx, RetailChromeSprites.CornerBR, r.BR);
// Resize-grip overlay (gold ridged edges + square corner studs) drawn on
// top of the bevel — the second border layer the vitals LayoutDesc carries
// (0x1000063B0x10000642). Edges tile; the corner stud is the same sprite
// at all four corners.
DrawTiled(ctx, RetailChromeSprites.GripTop, r.Top);
DrawTiled(ctx, RetailChromeSprites.GripBottom, r.Bottom);
DrawTiled(ctx, RetailChromeSprites.GripLeft, r.Left);
DrawTiled(ctx, RetailChromeSprites.GripRight, r.Right);
DrawStretched(ctx, RetailChromeSprites.GripCorner, r.TL);
DrawStretched(ctx, RetailChromeSprites.GripCorner, r.TR);
DrawStretched(ctx, RetailChromeSprites.GripCorner, r.BL);
DrawStretched(ctx, RetailChromeSprites.GripCorner, r.BR);
}
private void DrawTiled(UiRenderContext ctx, uint id, Rect d)