Commit graph

2 commits

Author SHA1 Message Date
Erik
7fe83e2bb9 test(ui): vitals — toggle verified through the real UiRoot mouse path
Two end-to-end additions to the fixture toggle suite: a body press through
UiRoot.OnMouseDown's actual hit test + bubble (left toggles, right toggles),
and a press on the authored top drag bar (0x1000063C) arming the window
move WITHOUT toggling — the retail Dragbar-consumes-the-press semantics
proven against the real input path, not just injected OnEvent calls.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 10:51:15 +02:00
Erik
306a1670d3 feat(ui): vitals — click toggles retail's numeric/graphical detail modes
Port of gmVitalsUI's press toggle, derived end-to-end from the named
retail decomp + the authored DAT data (installed-DAT probe 2026-08-17):

- gmVitalsUI::ListenToElementMessage @0x004BFC00: mouse press (msg 0x1C,
  dwParam1 7=left or 0xA=right — the same param pair the spellbook's
  select/favorite handler @0x0048C033 disambiguates) flips
  SetState(m_state == HideDetail ? ShowDetail : HideDetail). Both floaty
  subclasses (gmFloatyVitalsUI 0x1000004D / gmFloatySideVitalsUI
  0x10000056) inherit it verbatim.
- UIElement::SetState @0x00464E70 cascades through the authored
  PassToChildren chain: root and meters author media-less
  HideDetail/ShowDetail StateDescs with PassToChildren=true.
- HideDetail (0x10000006) = the NUMERIC mode: the cur/max labels author
  {0x3B:false} (0x3B = invisible; UIElement::OnSetAttribute case 8
  @0x00462DAE is SetVisible(value == 0)), the 0x100004A9 overlays author
  File=0.
- ShowDetail (0x10000007) = the GRAPHICAL mode: labels author {0x3B:true}
  (numbers hidden); each bar shows its authored icon pair — dim back icon
  unclipped over the track, bright front icon clipped with the front
  container to the fill fraction (UIElement_Meter::DrawChildren
  @0x0046FBD0 clips the whole element-id-2 child; m_pcChildImage =
  GetChildRecursive(this, 2) @0x0046F7E3). Health heart 0x06007490/91
  (18x16 @66,0), stamina sword 0x06007492/93 (85x16 @32,0), mana scepter
  0x06007494/95 (100x16 @25,0) — identical authoring in both 0x2100006C
  and 0x21000075.
- Initial state is the authored Undef (numbers visible, no icons —
  visually HideDetail); retail's first press lands on HideDetail, then
  the pair toggles forever. NOT persisted: SaveScreenLayout @0x004EAD50
  writes window rects only, and no PlayerModule option is touched — the
  mode resets per session, per window.
- Presses on drag bars / resize grips do not toggle: retail's
  UIElement_Dragbar @0x0046C850 and UIElement_Resizebar @0x0046B930
  consume the press (return 2) before it can bubble to the root.

Implementation: new UiVitalsRoot behavioral widget registered for the
three gmVitals class ids (press handler + state flip over the existing
UiDatElement state machine); UiMeter absorbs the two 0x100004A9 overlays
(ConfigureDetailOverlay + ShowDetail-keyed draw, back unclipped / front
fill-clipped) and forwards the detail states to its absorbed text child;
UiText.ApplyDatState gains the same named-state-only 0x3B honor
UiDatElement already had (the DirectState 0x3B class stays gated — #408).

8 new fixture-driven conformance tests (toggle sequence, right-press,
label cascade, chrome exclusions, per-window independence, overlay
extraction). App suite Release live-DAT: 5495 passed / 3 skips.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 10:34:56 +02:00