fix: plain <menu> popup scrollbar draws retail chrome, not a flat bar
Owner live-client report 2026-09-07: "For scrollable dropdown or the meta window we use the same assets as we do in for example chat or inventory window." The plain-style <menu> popup's scrollable-overflow scrollbar (DrawScrollablePopupPlain / DrawPopupScrollbarPlain in UiMenu.cs) drew a home-made flat 1px track + flat thumb instead of the gold track + up/down arrow buttons + thumb the chat SpewBox and inventory UiItemList already use through RetailScrollbarChrome. The owner only ever objected to the retail ROW art (checkmark glyph, gradient panel) — the bar itself was never in scope for the plain-row fix, so this change touches only the scrollbar draw call and leaves the plain row rendering untouched. DrawScrollablePopupPlain now calls the existing DrawPopupScrollbar helper (the same procedural sprite-chrome draw VendorUiController/ ConfigOptionsPageController already use) whenever a SpriteResolve is wired, falling back to the old flat DrawPopupScrollbarPlain only for a hand-built UiMenu with no resolver at all. New RetailScrollbarChrome.ApplyToMenuPopup(UiMenu) wires the same vertical skin ids (Track/Up/Down/ThumbTop/Mid/Bot Normal) the chat/inventory scrollbar uses onto a menu's own ScrollTrackSprite/etc properties. Mutation shown to fail first: UiMenuPlainStyleTests's Plain_OpenPopup_ScrollableOverflow_DrawsPlainTrackAndFlatThumb_NoDatArt and Plain_ScrollablePopup_ContentFits_DrawsTrackWithNoThumb asserted resolveCalls==0 and an all-fill scrollbar — both failed (6 resolve calls, 6 sprite quads instead of 0) against the new DrawPopupScrollbar call before being rewritten to Plain_OpenPopup_ScrollableOverflow_DrawsRetailScrollbarChrome_RowsStayPlain and Plain_ScrollablePopup_ContentFits_DrawsNoScrollbarAtAll, which pin the new sprite-chrome behavior (6 resolved ids on overflow: track, up, down, thumb top/mid/bottom; 3 on content-fits: track+up+down, no thumb; 0 on a menu built with no resolver) while re-asserting the rows are still plain fills with zero retail row-sprite quads. Retail's own RetailButtonArt=true popup path (DrawGridPopup/DrawScrollablePopup) is untouched — its regression golden (Retail_OpenPopup_DrawIsByteForByteUnchanged_RegressionGolden) still passes byte-for-byte. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
b36b036475
commit
67aba8c386
3 changed files with 96 additions and 26 deletions
|
|
@ -359,8 +359,17 @@ public sealed class UiMenuPlainStyleTests
|
|||
Assert.Equal(RetailChromeSprites.Border + UiMenu.PlainPadding, glyphSeg.Verts[0], 3);
|
||||
}
|
||||
|
||||
// ── Owner live-client report 2026-09-07 ("For scrollable dropdown or the
|
||||
// meta window we use the same assets as we do in for example chat or
|
||||
// inventory window"): the plain popup's SCROLLBAR now draws retail's own
|
||||
// chrome (the exact sprite ids RetailScrollbarChrome wires onto
|
||||
// chat/inventory's own bar) — only the ROWS stayed plain. These two tests
|
||||
// used to pin a fully flat/untextured scrollbar; they now pin the
|
||||
// opposite: real sprite draws for the bar, untouched plain fills for the
|
||||
// rows, and no visible bar at all once the content fits.
|
||||
|
||||
[Fact]
|
||||
public void Plain_OpenPopup_ScrollableOverflow_DrawsPlainTrackAndFlatThumb_NoDatArt()
|
||||
public void Plain_OpenPopup_ScrollableOverflow_DrawsRetailScrollbarChrome_RowsStayPlain()
|
||||
{
|
||||
int resolveCalls = 0;
|
||||
var menu = MakePopupMenu(retailButtonArt: false, itemCount: 12, rowsPerColumn: 5, scrollable: true,
|
||||
|
|
@ -373,27 +382,39 @@ public sealed class UiMenuPlainStyleTests
|
|||
var segs = renderer.DebugSpriteSegmentVerts;
|
||||
|
||||
Assert.True(menu.PopupScroll.HasOverflow);
|
||||
Assert.Equal(0, resolveCalls);
|
||||
Assert.Equal(0, QuadCount(segs, menu.ScrollTrackSprite));
|
||||
Assert.Equal(0, QuadCount(segs, menu.ScrollThumbSprite));
|
||||
// Track + up + down + thumb top/mid/bottom = 6 resolved sprite ids —
|
||||
// the SAME chrome ids the chat/inventory scrollbar resolves through
|
||||
// the same SpriteResolve seam, no longer the flat DrawFill-only path.
|
||||
Assert.Equal(6, resolveCalls);
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollTrackSprite));
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollUpSprite));
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollDownSprite));
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollThumbTopSprite));
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollThumbSprite));
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollThumbBottomSprite));
|
||||
|
||||
float outerTop = menu.Height;
|
||||
float inX = RetailChromeSprites.Border, inY = outerTop + RetailChromeSprites.Border;
|
||||
float scrollbarX = inX + PlainColumnWidth;
|
||||
|
||||
// The rows are untouched by the chrome swap: still a plain fill, no
|
||||
// DAT row/checkbox art at all (RetailButtonArt=false's own contract).
|
||||
Assert.True(HasFillQuad(segs, inX, inY, PlainColumnWidth, PlainRowHeight, menu.PlainSelectedColor),
|
||||
"expected visible row 0 (selected/current) filled with PlainSelectedColor");
|
||||
Assert.True(HasFillQuad(segs, scrollbarX, inY, menu.ScrollbarWidth, 5 * PlainRowHeight, menu.PlainBackgroundColor),
|
||||
"expected the scrollbar track background fill");
|
||||
"expected visible row 0 (selected/current) still filled with PlainSelectedColor");
|
||||
Assert.Equal(0, QuadCount(segs, menu.ItemHighlightSprite));
|
||||
Assert.Equal(0, QuadCount(segs, menu.ItemNormalSprite));
|
||||
|
||||
// popup bg(1)+outline(4) + selected row(1) + scrollbar bg(1)+outline(4) + thumb(1) = 12.
|
||||
Assert.Equal(12, QuadCount(segs, 0u));
|
||||
// popup bg(1)+outline(4) + selected row(1) = 6 untextured quads;
|
||||
// the scrollbar itself no longer contributes any (it is all sprite
|
||||
// draws now).
|
||||
Assert.Equal(6, QuadCount(segs, 0u));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Plain_ScrollablePopup_ContentFits_DrawsTrackWithNoThumb()
|
||||
public void Plain_ScrollablePopup_ContentFits_DrawsNoScrollbarAtAll()
|
||||
{
|
||||
var menu = MakePopupMenu(retailButtonArt: false, itemCount: 3, rowsPerColumn: 5, scrollable: true);
|
||||
int resolveCalls = 0;
|
||||
var menu = MakePopupMenu(retailButtonArt: false, itemCount: 3, rowsPerColumn: 5, scrollable: true,
|
||||
countResolveCall: n => resolveCalls += n);
|
||||
OpenAndHover(menu);
|
||||
|
||||
var (renderer, ctx) = MakeContext(200f, 200f);
|
||||
|
|
@ -402,9 +423,18 @@ public sealed class UiMenuPlainStyleTests
|
|||
|
||||
Assert.False(menu.PopupScroll.HasOverflow);
|
||||
|
||||
// popup bg(1)+outline(4) + scrollbar bg(1)+outline(4) = 10, no thumb quad
|
||||
// (nothing selected/hovered here either).
|
||||
Assert.Equal(10, QuadCount(segs, 0u));
|
||||
// Content-fits still draws the track + up/down buttons (retail's own
|
||||
// proportion-0x88-defaults-to-1.0 rule — a content-fits bar shows a
|
||||
// full-track thumb elsewhere in this class), but no thumb: 3 resolves.
|
||||
Assert.Equal(3, resolveCalls);
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollTrackSprite));
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollUpSprite));
|
||||
Assert.Equal(1, QuadCount(segs, menu.ScrollDownSprite));
|
||||
Assert.Equal(0, QuadCount(segs, menu.ScrollThumbSprite));
|
||||
|
||||
// popup bg(1)+outline(4) = 5 untextured quads (nothing
|
||||
// selected/hovered here either, and the scrollbar draws no fills).
|
||||
Assert.Equal(5, QuadCount(segs, 0u));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue