fix(ui): match retail spell bar controls
Place favorite-bar arrows by their authored sides, import rollover and pressed media through the shared scrollbar, and preserve manual offsets across passive refreshes. Carry the mixed-parent DAT anchor chain to a fixed 18-cell favorite viewport so overflow controls and the Cast button remain inside the retail-sized combat frame. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
02c29e67c8
commit
0134122c28
17 changed files with 424 additions and 59 deletions
|
|
@ -14,8 +14,12 @@ bodies begin: spell-bar overflow controls, status-bar Use/Assess commands,
|
|||
assessment information, equipped-child picking, vendor browsing, and
|
||||
server-authoritative vendor transactions. Slice 1 is active and ports the
|
||||
DAT-authored arrow-only favorite-spell scrollbar through the shared retained
|
||||
scrollbar/list model. Its implementation and complete Release suite pass;
|
||||
connected overflow-arrow visual acceptance is pending.
|
||||
scrollbar/list model. The corrected import preserves authored arrow sides and
|
||||
rollover/pressed media, passive refresh preserves manual offsets, and the
|
||||
mixed-parent DAT anchor chain produces the fixed retail capacity of 18 visible
|
||||
favorite cells (nine numbered plus nine unnumbered). Its
|
||||
implementation and complete Release suite pass; connected overflow-arrow
|
||||
visual acceptance is pending.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -43,12 +43,18 @@ Each slice begins with named-retail research, produces pseudocode and
|
|||
conformance tests, updates the divergence register if required, and lands as a
|
||||
separate bisectable commit. A visual gate follows each UI-bearing slice.
|
||||
|
||||
Slice 1 now imports both 23-pixel arrow buttons and HideDisabled from the real
|
||||
combat fixture, shares the list's single pixel-scroll model, advances one
|
||||
32-pixel cell per press, and exposes programmatically selected spells. The
|
||||
focused 57-test set, all 3,466 App tests / 3 skips, the Release solution build,
|
||||
and all 7,839 solution tests / 5 skips pass. Only the connected visual gate
|
||||
remains before Slice 2 starts.
|
||||
Slice 1 now imports both 23-pixel arrow buttons, their rollover/pressed media,
|
||||
and HideDisabled from the real combat fixture; places their artwork by the
|
||||
authored leading/trailing positions; shares the list's single pixel-scroll
|
||||
model; advances one 32-pixel cell per press; and exposes only actively selected
|
||||
spells. Passive object/endowment refresh preserves a manual offset. The mixed
|
||||
610/800-pixel DAT anchor chain is solved to a fixed 747-pixel combat root,
|
||||
producing exactly 18 visible 32-pixel favorite cells (nine numbered plus nine
|
||||
unnumbered) without consuming the overflow. The initial 57-test/full-suite gate passed;
|
||||
the corrective 104-test focus set, 3,472 App tests / 3 skips, Release solution
|
||||
build, and 7,845 complete-solution tests / 5 skips pass. The connected gate is
|
||||
pending after user feedback on arrow sides, rollover, width, and offset
|
||||
persistence.
|
||||
|
||||
## Slice 1 — spell-bar overflow arrows
|
||||
|
||||
|
|
@ -74,7 +80,8 @@ Named retail references and executable pseudocode are recorded in
|
|||
|
||||
1. Generalize `DatWidgetFactory.BuildScrollbar` so horizontal and vertical
|
||||
scrollbars both import the referenced decrement/increment children,
|
||||
including their authored dimensions and HideDisabled property.
|
||||
including their authored positions, dimensions, Normal/rollover/pressed
|
||||
media, and HideDisabled property.
|
||||
2. Generalize `UiScrollbar` to use distinct authored decrement/increment
|
||||
extents for rendering, hit-testing, track geometry, and dragging. Preserve
|
||||
the existing 16-pixel default for layouts whose button children are absent.
|
||||
|
|
@ -85,10 +92,14 @@ Named retail references and executable pseudocode are recorded in
|
|||
`UiItemList.Scroll`, enable horizontal scrolling, and retain one independent
|
||||
pixel offset per favorite tab.
|
||||
5. Match `SpellCastSubMenu::SetSelected`: selecting a spell through keyboard,
|
||||
shortcut, or code scrolls that item into view.
|
||||
6. Pin the importer, arrow hit extents, 32-pixel step, no-overflow behavior,
|
||||
shortcut, or code scrolls that item into view; passive state refresh does
|
||||
not re-expose it.
|
||||
6. Carry the combat root's mixed-parent raw-edge policies through the complete
|
||||
imported tree and solve for the retail 18-cell favorite viewport; keep that
|
||||
HUD capacity fixed across desktop resizes.
|
||||
7. Pin the importer, arrow hit extents, 32-pixel step, no-overflow behavior,
|
||||
controller binding, and selection exposure with focused App tests.
|
||||
7. Run the App Release suite, solution Release build, and complete Release
|
||||
8. Run the App Release suite, solution Release build, and complete Release
|
||||
suite. Then update the roadmap/memory and request the connected visual gate:
|
||||
place more favorites than fit, scroll both directions, change tabs, and
|
||||
verify arrows disappear on a non-overflowing tab.
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ Each of the eight `SpellCastSubMenu` groups contains:
|
|||
```text
|
||||
favorite group
|
||||
scrollbar 0x100000B5, 685x36
|
||||
decrement button 0x10000071, 23x36
|
||||
increment reference 0x10000072, authored x=0, 23x36
|
||||
Normal 0x06004CDE (left-facing arrow)
|
||||
Rollover 0x06004CDF
|
||||
decrement reference 0x10000071, authored x=63, 23x36
|
||||
Normal 0x06004CDC
|
||||
Rollover 0x06004CDD
|
||||
increment button 0x10000072, 23x36
|
||||
Normal 0x06004CDE
|
||||
Rollover 0x06004CDF
|
||||
item list 0x100000B6, x=23, y=2, 639x32
|
||||
|
||||
scrollbar property 0x77 = increment button 0x10000072
|
||||
|
|
@ -28,7 +28,12 @@ item-list property 0x71 = horizontal scrollbar 0x100000B5
|
|||
```
|
||||
|
||||
The spell-bar scrollbar has no authored track or thumb. Its 23-pixel buttons
|
||||
occupy the space immediately outside the 639-pixel item-list viewport.
|
||||
occupy the space immediately outside the 639-pixel item-list viewport. The
|
||||
property names do not determine their drawn side:
|
||||
`UIElement_Scrollbar::UpdateScrollingArea @ 0x00470AA0` places the 0x77
|
||||
increment reference at the leading/top-left edge and the 0x78 decrement
|
||||
reference at the trailing/bottom-right edge. For this horizontal fixture that
|
||||
means `0x06004CDE` on the left and `0x06004CDC` on the right.
|
||||
|
||||
## Initialization and ownership
|
||||
|
||||
|
|
@ -85,8 +90,8 @@ UpdateScrollbarSize(horizontal):
|
|||
|
||||
Scrollbar.UpdateLayout():
|
||||
scrollingArea = own rectangle
|
||||
position decrement button at the start and subtract its authored width
|
||||
position increment button at the end and subtract its authored width
|
||||
position property-0x77 button at the start and subtract its authored width
|
||||
position property-0x78 button at the end and subtract its authored width
|
||||
update thumb/track geometry, when those children exist
|
||||
Visible = NOT (Disabled AND HideDisabled)
|
||||
```
|
||||
|
|
@ -95,6 +100,31 @@ For the favorite bar, disabled plus HideDisabled removes both arrows when every
|
|||
favorite/empty cell fits. With overflow, the arrows remain visible and the
|
||||
item list clips the horizontally translated cells.
|
||||
|
||||
The combat LayoutDesc deliberately mixes design extents: its outer combat root
|
||||
is 610 pixels wide, while the magic page's children are authored against an
|
||||
800-pixel parent. Applying retail
|
||||
`UIElement::UpdateForParentSizeChange @ 0x00462640` through that complete
|
||||
raw-edge chain gives a 439-pixel favorite viewport at the 610-pixel root—the
|
||||
13-slot short bar seen before this slice.
|
||||
|
||||
The retail presentation exposes 18 favorite cells: nine shortcut-numbered
|
||||
cells plus nine unnumbered cells. At 32 pixels per cell the target viewport is
|
||||
576 pixels. Because every horizontal raw-edge stage carries the parent delta
|
||||
one-for-one, solving the imported tree for that viewport yields:
|
||||
|
||||
```text
|
||||
outer combat root = 747 px
|
||||
magic page = 737 px (5 px inset on each side)
|
||||
favorite group = 622 px (x=40, followed by Cast)
|
||||
scrollbar = 622 px (23 + 576 + 23)
|
||||
favorite list = 576 px (18 * 32)
|
||||
Cast = x=662, width=75 inside the magic page
|
||||
```
|
||||
|
||||
This is a fixed visible-capacity HUD, not a desktop-wide strip. Stretching it
|
||||
to the display width makes the favorite content fit, which legitimately
|
||||
disables and hides the `HideDisabled` overflow arrows.
|
||||
|
||||
## Scroll delta and selection exposure
|
||||
|
||||
Retail:
|
||||
|
|
@ -127,15 +157,23 @@ SpellCastSubMenu.SetSelected(spellId):
|
|||
```
|
||||
|
||||
The favorite cells are 32 pixels wide, so a line arrow moves exactly 32
|
||||
pixels. Programmatic or keyboard selection exposes the selected cell even when
|
||||
it was outside the prior viewport.
|
||||
pixels. An actual programmatic, keyboard, or pointer selection exposes the
|
||||
selected cell even when it was outside the prior viewport. Passive endowment
|
||||
or object-table refresh does not re-run `SetSelected`; doing so would undo a
|
||||
manual scrollbar offset.
|
||||
|
||||
## Port constraints
|
||||
|
||||
- Preserve the imported `0x71`/`0x77`/`0x78` relationships.
|
||||
- Preserve each authored button's dimension; do not assume the 16-pixel chat
|
||||
scrollbar button size.
|
||||
- Preserve each authored button's Normal, Normal_rollover, and Normal_pressed
|
||||
media through the shared scrollbar presentation path.
|
||||
- Do not fabricate a track/thumb for this arrow-only control.
|
||||
- Derive disabled state from the shared model's content and viewport extents.
|
||||
- Hide disabled controls from both drawing and hit-testing.
|
||||
- Keep every favorite tab's scroll offset independent.
|
||||
- Carry the DAT raw-edge policies through the full imported combat tree and
|
||||
solve the root width for an 18-cell (576-pixel) favorite viewport.
|
||||
- Keep the resulting 747-pixel HUD width fixed across desktop resizes; do not
|
||||
turn the favorite bar into a desktop-wide strip.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue