Complete the retail cast-intent, target, component, enchantment, and busy-state paths; mount the DAT-authored spell bar, spellbook, component book, effects panels, and shared panel lifecycle; and add scoped input plus conformance coverage.
Co-Authored-By: Codex <noreply@openai.com>
Keep the horizontal thumb at its raw pointer position so both endpoints are reachable, honor the stack entry's authored right alignment, and preserve PublicWeenieDesc plural names from CreateObject through the object table. Port retail's singular s/es fallback when no plural was sent.
Co-Authored-By: Codex <codex@openai.com>
Bind the authored stack count entry and horizontal slider to one Core split-quantity owner, preserve retail count-first naming and exact 1000-step rounding, refresh on stack changes, and consume the selected amount during merges. Conformance covers the production DAT fixture and retained pointer/focus paths.
Co-Authored-By: Codex <codex@openai.com>
The generalized channel menu wouldn't open: the factory recursed the Type-6
menu element's dat children, building its invisible Type-12 label child as a
UiText. Hit-testing is children-first and UiText consumes MouseDown (selection),
so the label child swallowed the menu button click and the dropdown never opened.
The transcript similarly gained an invisible Ghosted-button child (a 16x16
selection dead-zone). The old hand-made build never had these — it skipped Type 12
and hand-placed the widgets with no children.
Fix: behavioral widgets (Meter/Menu/Button/Scrollbar/Text/Field) draw their full
appearance and reproduce their dat sub-elements procedurally, so they are LEAF —
the importer must not build their dat children as separate (click-stealing)
widgets. Add UiElement.ConsumesDatChildren (default false; the 6 behavioral
widgets override true) and gate LayoutImporter recursion on it (replacing the
UiMeter-only special case). Only generic containers (UiDatElement, panels) recurse.
Visually confirmed in the live client (channel menu opens; General/Trade selected
and sent). Vitals unchanged (UiMeter was already leaf). Full suite: 404 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Rename UiChatInput → UiField (UIElement_Field, RegisterElementClass(3) @ :126190);
update doc to cite retail's CatchDroppedItem/MouseOverTop drag-drop hooks for
future item windows. BackgroundColor default → transparent (controller sets
the translucent 0.35α value explicitly, matching UiText pattern).
- Register Type 3 in DatWidgetFactory.Create: `3 => new UiField()`.
- ChatWindowController.Bind (Variant B): factory now builds 0x10000016 as an
invisible UiText placeholder (Type 12); Bind removes that placeholder via
FindElement(InputId).Parent.RemoveChild and places a UiField at the same rect.
Result: exactly ONE input widget in the input bar, no stray UiText duplicate.
- Input property type changed from UiChatInput to UiField; GameWindow.cs:1861
UiField.Keyboard assignment compiles unchanged (field exists).
- Tests: UiChatInputTests → UiFieldTests (class + all ctor refs renamed);
DatWidgetFactoryTests: new Type3_Field_MakesUiField test; ChatWindowControllerTests:
updated stale "skipped by factory" comments; LayoutConformanceTests: updated
VitalsTree_ChromeCornerHasExpectedSprite — Type-3 chrome-corner elements are
now UiField (sprite rendering for Type-3 dat image elements is a known
limitation, tracked for post-Task-8 UiField.BackgroundSprite follow-up).
- Full suite: 404 passed, 2 skipped, 0 failed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 17:48:51 +02:00
Renamed from src/AcDream.App/UI/UiChatInput.cs (Browse further)