fix(ui): share retail tab state binding

Replace the character window's synthesized tab sprites, labels, colors, and hit panels with the same DAT-authored Open/Closed state path used by Spellbook/Components. Preserve controller-owned page selection while letting UIElement state propagation own tab chrome and typography.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-15 17:21:16 +02:00
parent 1249ad03de
commit 15bb61e05d
5 changed files with 179 additions and 285 deletions

View file

@ -255,6 +255,26 @@ before its retained children lets the center chrome overpaint the caption.
This rule is derived structurally from `PassToChildren`, not from the two
spellbook element ids.
The same mechanism applies to the Character window `0x2100002E`. Its
Attributes `0x10000228`, Skills `0x10000229`, and Titles `0x10000538` controls
are also compound Type-12 tabs with Closed/Open state color and three authored
chrome children. The controller reduction is therefore shared:
```text
BindRetailTab(tab, activate):
tab.Click = activate
SetActiveTab(active):
for each tab:
tab.SetState(tab == active ? Open(12) : Closed(11))
// UIElement::SetState propagates the same state to the retained children
```
Page visibility remains controller-owned because the three character page
containers carry no active-page visibility state. Tab appearance does not:
injecting replacement sprites or hard-coded caption colors bypasses the exact
same DAT state machine already used by Spellbook/Components.
Layout `0x21000034` supplies the 300 by 600 content surface, including its tab
bar and close control, but not the enclosing movable-window border. Production
mounts it through the same shared retained nine-slice frame used by the