docs(ui): Fix 4 — dat UIState model has no Group visibility encoding; CharacterStatController hacks are correct
Investigation (2026-06-26): the character footer three sibling groups (0x10000240/241/247)
all carry DefaultState=0x10000011 (StatManagement_Footer_Default) — the dat does NOT
differentiate them by visibility. Parent 0x1000022F has States {Default, Text, Meter}
with PassToChildren=true, but each child group registers all three states with
IncorporationFlags=None and Media=0, so state-propagation produces no visual change
on any group. Retail gmStatManagementUI uses hardcoded element-id dispatch for
0x10000240/241/247 — the groups are never hidden/shown via the dat state mechanism
(decomp gmStatManagementUI::GetFooterTitleLabel @0x004f0170).
Tab-page containers (0x1000022B/22C/10000539) have DefaultState=Undef — no visibility
encoding. Tab visibility is managed purely at runtime by gmTabUI.
IncorporationFlags (DatReaderWriter): {None, PassToChildren, X, Y, Width, Height,
ZLevel} — no Visible flag. The importer cannot set initial Group visibility from
the dat; the controller is the correct and only place. CharacterStatController
HideAllById footer pass and ContainsWidget page-visibility walk are retail-faithful
and must be kept.
No logic changes — comment-only documentation. Build green, 710 App tests green.
Studio screenshots: character footer shows State-A by default with no overlap;
vitals and toolbar unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ed626f4250
commit
1b9dd6c7a8
2 changed files with 38 additions and 0 deletions
|
|
@ -186,6 +186,25 @@ public static class LayoutImporter
|
|||
/// Dat shell: load the LayoutDesc, resolve inheritance for every top-level
|
||||
/// element, and build the widget tree. Returns null if the layout is absent
|
||||
/// from the dats.
|
||||
///
|
||||
/// <para>
|
||||
/// <b>Dat UIState visibility model (2026-06-26 audit):</b>
|
||||
/// The dat's <c>ElementDesc.DefaultState</c> field specifies which SPRITE/MEDIA
|
||||
/// state an element starts in (e.g., <c>Normal</c>, <c>Minimized</c>). It does
|
||||
/// NOT encode visibility of sibling Group containers. The <c>StateDesc</c>'s
|
||||
/// <see cref="DatReaderWriter.Enums.IncorporationFlags"/> contains X/Y/Width/Height/
|
||||
/// ZLevel/PassToChildren — there is no Visible flag.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// Windows that display multiple sibling Group containers at the same position
|
||||
/// (the character footer's three state-groups; the tab-page content areas) manage
|
||||
/// visibility purely at runtime via C++ controller code. Retail uses
|
||||
/// <c>UIElement::SetState(stateId)</c> on the parent to propagate state, then
|
||||
/// C++ getters access the right sub-group by element id. All groups are shipped
|
||||
/// as visible in the imported widget tree; the relevant controllers
|
||||
/// (<see cref="CharacterStatController"/>) perform the initial show/hide.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="fontResolve">Optional per-element font resolver (see
|
||||
/// <see cref="Build"/> for details). Null = original single-font behavior.</param>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue