fix(ui): retail scrollbar parity — button seating, full-track thumb, hover/pressed states
Owner report (2026-08-24): our scrollbar arrows pointed the wrong way, the thumb vanished when there was nothing to scroll, and neither the thumb nor the arrow buttons reacted to hover/press. All three are one retail mechanism we had not ported: 1. Seating: UIElement_Scrollbar::UpdateScrollingArea @0x00470AA0 moves the INCREMENT designee (attribute 0x77) to the top/left corner and the DECREMENT designee (0x78) to the bottom/right, ignoring authored positions. The vertical base skin (0x10000455 in layout 0x2100003E) authors the DOWN-arrow decrement at Y=0 and the UP-arrow increment at Y=32 (live-DAT probed; sprite art visually verified from decoded PNGs), so our authored-Y ordering drew both arrows upside down. DatWidgetFactory now seats by designation; the hand-wired sites (CharacterStatController, ExternalContainerController, the Config/Vendor menu chrome) share the new RetailScrollbarChrome catalog instead of local constants. 2. Full-track thumb: UpdateLayout @0x004710d0 sizes the thumb from proportion attribute 0x88, which DEFAULTS to 1.0 — a content-fits bar shows a thumb filling the whole track; disabled only removes input and the page regions. Our draw skipped the thumb entirely on !HasOverflow. 3. States: every arrow button and thumb slice authors Normal (red gem / dark navy), Normal_rollover (amber gem / bright blue) and Normal_pressed (gold highlight / dark) media. The widget now tracks thumb hover and selects rollover media on hover and pressed media while dragging; the factory extracts the thumb-state media for both the 3-slice and single-sprite thumb shapes. ScrollbarSkinLiveDatTests pins the designations and state media against the installed DAT so a revision or importer regression fails loudly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
35abbe1d0d
commit
8fd3d1a9f0
12 changed files with 541 additions and 64 deletions
|
|
@ -137,13 +137,10 @@ public static class CharacterStatController
|
|||
private const uint SkillHeaderUnusableSprite = 0x06000F89u;
|
||||
private const uint RowHighlightSprite = 0x06001397u;
|
||||
|
||||
// Scrollbar chrome from base layout 0x2100003E, shared with chat/inventory.
|
||||
private const uint ScrollTrackSprite = 0x06004C5Fu;
|
||||
private const uint ScrollThumbSprite = 0x06004C63u;
|
||||
private const uint ScrollThumbTop = 0x06004C60u;
|
||||
private const uint ScrollThumbBot = 0x06004C66u;
|
||||
private const uint ScrollUpSprite = 0x06004C69u;
|
||||
private const uint ScrollDownSprite = 0x06004C6Cu;
|
||||
// Scrollbar chrome from base layout 0x2100003E, shared with chat/
|
||||
// inventory — sprite set + retail button seating live in
|
||||
// RetailScrollbarChrome (2026-08-24: the previous local constants seated
|
||||
// the DOWN-arrow art on the top button).
|
||||
|
||||
private enum CharacterStatTab
|
||||
{
|
||||
|
|
@ -681,12 +678,7 @@ public static class CharacterStatController
|
|||
Func<uint, (uint handle, int w, int h)> spriteResolve)
|
||||
{
|
||||
bar.SpriteResolve = id => { var (h, w, ht) = spriteResolve(id); return (h, w, ht); };
|
||||
bar.TrackSprite = ScrollTrackSprite;
|
||||
bar.ThumbSprite = ScrollThumbSprite;
|
||||
bar.ThumbTopSprite = ScrollThumbTop;
|
||||
bar.ThumbBotSprite = ScrollThumbBot;
|
||||
bar.UpSprite = ScrollUpSprite;
|
||||
bar.DownSprite = ScrollDownSprite;
|
||||
RetailScrollbarChrome.ApplyVertical(bar);
|
||||
}
|
||||
|
||||
private static float SkillViewportWidth(UiElement statList, UiScrollbar? bar)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue