fix(ui): complete retail inventory scroll polish
Preserve pixel scroll offsets across inventory rebuilds, crop partially visible rows with nested geometry/UV clips, and replace the obsolete 560px resize ceiling with available screen height. Keep retail's row-sized wheel step while allowing continuous scrollbar thumb positions. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
ea72c395c9
commit
15aa3b9aff
15 changed files with 379 additions and 34 deletions
|
|
@ -0,0 +1,63 @@
|
|||
# Retail inventory listbox scrolling pseudocode
|
||||
|
||||
## Named-retail anchors
|
||||
|
||||
- `UIElement_ListBox::ScrollToY @ 0x0046D550`
|
||||
- `UIElement_ListBox::InqScrollDelta @ 0x0046DC10`
|
||||
- `UIElement_ListBox::ScrollToView @ 0x0046E9F0`
|
||||
- `UIElement_Scrollable::SetScrollableXY @ 0x004740C0`
|
||||
- `UIElement_ItemList::ItemList_SetParentContainer @ 0x004E49D0`
|
||||
- `UIElement_ItemList::RefreshList @ 0x004E4C00`
|
||||
|
||||
## Scroll model
|
||||
|
||||
```text
|
||||
ScrollToY(pixelY):
|
||||
SetScrollableXY(currentX, pixelY, false)
|
||||
|
||||
InqScrollDelta(vertical, negativeDirection, page):
|
||||
if page:
|
||||
delta = viewportHeight
|
||||
else if rowCount != 0:
|
||||
delta = min(scrollableHeight / rowCount, viewportHeight)
|
||||
else:
|
||||
delta = 0
|
||||
return negativeDirection ? -delta : delta
|
||||
```
|
||||
|
||||
The stored position is an integer pixel coordinate, not a row index. Scrollbar
|
||||
thumb movement can therefore stop with a row partially visible. Wheel/arrow line
|
||||
steps remain one row high because `InqScrollDelta` derives the line delta from
|
||||
`scrollableHeight / rowCount`.
|
||||
|
||||
`ScrollToView(index)` sums preceding row heights and compares that pixel rectangle
|
||||
against `[scrollY, scrollY + viewportHeight]`; it adjusts only when the item lies
|
||||
outside the visible pixel interval.
|
||||
|
||||
## Refresh behavior
|
||||
|
||||
```text
|
||||
RefreshList():
|
||||
ItemList_SetParentContainer(parentContainerID, refresh=true, notify=true)
|
||||
|
||||
ItemList_SetParentContainer(...):
|
||||
update capacity
|
||||
flush item elements
|
||||
add current contained objects in order
|
||||
// no ScrollToHome / SetScrollableXY(0) in this path
|
||||
```
|
||||
|
||||
The item-element rebuild does not explicitly home the list. A client-side retained
|
||||
rebuild must therefore preserve `m_iScrollableY` and clamp it only after the complete
|
||||
replacement content establishes its final extent.
|
||||
|
||||
## acdream port shape
|
||||
|
||||
- `UiItemList.DeferLayout` prevents transient one-cell extents from clamping the
|
||||
retained pixel offset during `InventoryController.Populate`.
|
||||
- Intersecting edge cells remain visible at their true `rowY - ScrollY` coordinate.
|
||||
- `UiElement.ClipsChildren` pushes a nested screen-space clip; `UiRenderContext`
|
||||
crops sprite geometry and matching UVs, so a partial row paints only inside the
|
||||
contents viewport and cannot receive input outside it.
|
||||
- The inventory window's maximum height is the available screen height rather than
|
||||
the former arbitrary 560 px cap. Exact keystone resize bounds remain AP-54.
|
||||
Loading…
Add table
Add a link
Reference in a new issue