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>
63 lines
2.3 KiB
Markdown
63 lines
2.3 KiB
Markdown
# 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.
|