acdream/tests/AcDream.App.Tests/UI
Erik 22020ef2c4 feat(chat): Campaign CH slice CH6b — floating chat windows 1-4
Mounts retail's four floating chat windows as always-resident, born-hidden
children per gmGamePlayUI::SetupChildren @0x004E9EC0, all sharing LayoutDesc
0x2100005B (window ids 0x10000505/0x1000050E/0x1000050F/0x10000510). New
FloatingChatWindowController (AcDream.App/UI/Layout) binds each window's own
widget tree — built fresh per instance from one shared imported ElementInfo
— reusing ChatWindowController's word-wrap + retail color-carry algorithm via
the extracted ChatTranscriptRenderer instead of duplicating it. A floaty
window has no talk-focus menu (research doc §2.2), so its entry field always
sends on Say; the mismatch against retail's possible shared-channel behavior
is UNVERIFIED and filed as #369/AP-188.

Runtime owns the per-window filter/open state: ChatWindowState (new,
AcDream.Core.Chat) seeds retail's exact PostInit defaults per window
(window 1 0x0000101C Speech/Tell/DirectSend/Emote, window 2 0x00040C00
Social/SocialSend/Allegiance, window 3 0x00080000 Fellowship, window 4
0x78000000 Turbine General/Trade/LFG/Roleplay) and implements the full
ShouldDisplay(windowId, targetWindowId, logTextType) display predicate from
ChatInterface::RecvNotice_DisplayFinalStringInfo @0x004F4640. It lives on
RuntimeCommunicationState.ChatWindows so every host borrows the same
instance. The main window's filter (0xFBFFFFFF, "no user filter") never
actually gates anything because its own explicit-address branch already
covers every broadcast line — that's why UpdateFromPlayerModule early-returns
for window 0 in retail, ported here by construction rather than a special
case.

Keybind wiring: InputAction.ToggleFloatingChatWindow1..4 and their
KeyBindings.RetailDefaults() chords already existed since Phase K.1c
(unwired until now). The MetaKeys table confirms retail's default is Alt+1
through Alt+4 (index 3 = bit 0x00000004, cross-checked against the same
file's Alt+A/D strafe and Alt+Enter/Tab/F4 rows). Routes through
GameplayInputCommandController -> RetainedGameplayWindowCommands ->
RetailUiRuntime.ToggleFloatingChatWindow -> the generic UiHost.ToggleWindow,
whose visibility-change event is the single chokepoint that syncs
ChatWindowState.SetOpen and mirrors the main window's 1-4 indicator button
regardless of what changed a window's visibility (keybind, close button, or
a restored layout).

A direct decomp read of gmMainChatUI::ListenToElementMessage @0x004CDA80 —
the only function in the whole binary that branches on a click message —
settles what the research doc had left as a hedge: it handles exactly
0x1000046f (max/min) and the talk-focus menu's selection message, with NO
case for 0x10000522-0x10000525. The four indicator buttons are PURE
one-directional mirrors in retail; clicking them does nothing.
ChatWindowController.SetIndicatorOpen ports this with no OnClick at all.
Corrected research doc §1.4 accordingly.

Persistence is local-only (register row AP-187; the retail 0x1000008C
GameplayOptions wire remains deferred to CH6f): window geometry and
open/visible state ride the existing generic RetailWindowLayoutPersistence
path for free once each window registers under its own WindowNames entry;
the four filter masks get a dedicated ChatSettings round-trip
(ChatWindow1Filter..ChatWindow4Filter, defaulting to the retail PostInit
constants) loaded at mount and saved alongside SaveLayout().

Tests: ChatWindowStateTests (defaults, TypeIsActive, the full display-rule
matrix, toggle/reset, revision counter), FloatingChatWindowControllerTests
(bind smoke tests against a synthetic 0x2100005B tree, per-window filter
routing, filter-change cache invalidation, fixed-Say submit), new
ChatWindowController.SetIndicatorOpen tests (Highlight/Normal state,
cross-window isolation, range validation), GameplayInputCommandController
routing for the four toggle actions, and a SettingsStore filter round-trip.
Full Release suite: 12,392 passed / 4 skipped / 0 failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 12:10:20 +02:00
..
Layout feat(chat): Campaign CH slice CH6b — floating chat windows 1-4 2026-08-10 12:10:20 +02:00
AutoWieldGenerationTests.cs feat(net): port retail physics spawn and event timestamps 2026-07-14 00:22:17 +02:00
ClientCommandControllerTests.cs fix(chat): CH4 re-review fixes — dialog-queue reentrancy, settings option-bit chokepoint 2026-08-09 22:24:43 +02:00
ControlsIniTests.cs feat(D.2b): controls.ini stylesheet loader + apply title color 2026-06-14 17:31:55 +02:00
CursorFeedbackControllerTests.cs feat(chat): Campaign CH slice CH6a — retail chat-window layout + 8-grip resize 2026-08-10 09:38:27 +02:00
DatWidgetFactoryZOrderTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
DragDropSpineTests.cs fix(vendor): gate-findings pass — the X button HIDES like retail, clicks return, the dropdown scrolls, pyreal suffix, staged-tab slots 2026-08-08 10:29:39 +02:00
GameplayConfirmationControllerTests.cs refactor(net): converge live session state reset 2026-07-21 12:00:48 +02:00
IconComposerTests.cs fix(D.5.2): effect tint = per-pixel tile copy (surface ReplaceColor overload) 2026-06-18 10:21:33 +02:00
ItemInteractionControllerTests.cs feat(vendor): Slice 6b/6c — move-to-use, buy staging, selling; the vendor arc is functionally complete 2026-08-08 11:43:11 +02:00
LayoutImporterMountTests.cs feat(ui): D.2b-B — sub-window mount (inheritor attaches base subtree) 2026-06-20 22:36:20 +02:00
MarkupDocumentTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
RetailCursorCatalogTests.cs fix(ui): port retail window control feedback 2026-07-17 09:40:08 +02:00
RetailCursorManagerTests.cs feat(ui): complete retail cursor state machine 2026-07-11 08:31:40 +02:00
RetailItemConfirmationControllerTests.cs refactor(runtime): own interaction transactions 2026-07-26 11:13:09 +02:00
RetailSkillTrainingConfirmationControllerTests.cs fix(ui): restore retail skill training confirmation 2026-07-13 17:57:29 +02:00
RetailUiAutomationProbeTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
RetailUiInteractionFlowTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
RetailUiRuntimeLeaseTests.cs refactor(lifetime): own render resource prefixes 2026-07-22 14:42:14 +02:00
RetailWindowLayoutPersistenceTests.cs fix(ui): restore modern spell formula presentation 2026-07-24 07:08:47 +02:00
RetailWindowManagerTests.cs fix(ui): port retail window control feedback 2026-07-17 09:40:08 +02:00
RetainedPanelControllerGroupTests.cs refactor(ui): own retained controller lifetimes 2026-07-10 23:35:26 +02:00
RetainedUiInputBindingTests.cs refactor(input): own pointer and callback lifetime 2026-07-22 11:59:33 +02:00
SpewBoxControllerTests.cs fix(chat): Campaign CH round 3 — SpewBox flush-top/font, /help exact print sequence 2026-08-10 10:40:19 +02:00
SpewBoxLayoutDumpDiagnostic.cs fix(chat): CH2 re-review nits — resize centering, top-aligned flow, sweep wording 2026-08-09 18:48:13 +02:00
UiButtonStateMachineTests.cs feat(ui): port retained widget foundations 2026-07-10 17:55:41 +02:00
UiButtonTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
UiClipRectTests.cs fix(ui): complete retail inventory scroll polish 2026-07-11 10:56:33 +02:00
UiCollapsibleFrameTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
UiCompositeShutdownTests.cs test(runtime): add unattended connected R6 soak 2026-07-20 12:12:08 +02:00
UiDatFontTests.cs test(app): measure the warmed path, not the path being warmed (#250) 2026-07-29 03:42:08 +02:00
UiElementChildOrderTests.cs fix(rendering): bound portal resource lifetime 2026-07-18 21:35:16 +02:00
UiFieldTests.cs fix(ui): UiField wrapped-line cache coherent with the text at mouse-hit time 2026-07-29 19:38:52 +02:00
UiItemListGridTests.cs feat(ui): D.2b item interaction + retail cursors + live character sheet 2026-07-03 09:18:43 +02:00
UiItemListScrollTests.cs fix(ui): complete retail inventory scroll polish 2026-07-11 10:56:33 +02:00
UiItemListTests.cs feat(items): port retail shared cooldown overlays 2026-07-23 10:41:16 +02:00
UiItemSlotTests.cs fix(vendor): Slice 6 review corrections — ownership-checked retire, live slider display, drag-proof shop rows, hardened buy reservation 2026-08-07 23:12:50 +02:00
UiLayoutPolicyTests.cs fix(ui): preserve cropped chat and button faces 2026-07-10 18:11:14 +02:00
UiMenuTests.cs fix(ui): vendor dropdown polish — authored arrow-cap with open/closed flip, downward popup, left-aligned rows 2026-08-08 10:59:59 +02:00
UiMeterTests.cs feat(D.2b): UiMeter vital bar + fill-geometry tests 2026-06-14 16:38:07 +02:00
UiMeterVerticalTests.cs feat(ui): D.2b-B — UiMeter vertical fill (burden bar, retail m_eDirection 2/4) 2026-06-21 08:58:37 +02:00
UiNineSlicePanelTests.cs feat(D.2b): UiNineSlicePanel — 8-piece retail window frame + geometry test 2026-06-14 16:36:11 +02:00
UiRadarTests.cs feat(ui): port retail radar and compass 2026-07-10 16:14:37 +02:00
UiRootInputTests.cs feat(chat): Campaign CH slice CH6a — retail chat-window layout + 8-grip resize 2026-08-10 09:38:27 +02:00
UiScrollablePanelTests.cs feat(ui): D.2b item interaction + retail cursors + live character sheet 2026-07-03 09:18:43 +02:00
UiScrollableTests.cs feat(ui): unify retained window mounts 2026-07-10 22:22:25 +02:00
UiScrollbarTests.cs fix(ui): match retail spell bar controls 2026-07-23 07:49:09 +02:00
UiTextDatFontTests.cs feat(D.2b): UiText (Type 12) -- generic text + Type-12 flip; transcript factory-built (widget-generalization Task 5) 2026-06-16 17:39:02 +02:00
UiTextTests.cs fix(ui): render live component counts 2026-07-15 18:11:02 +02:00