feat(D.2b): UiText (Type 12) -- generic text + Type-12 flip; transcript factory-built (widget-generalization Task 5)

Rename UiChatView -> UiText (the retail UIElement_Text class,
RegisterElementClass(0xc) @ acclient_2013_pseudo_c.txt:115655).

Factory changes (DatWidgetFactory.cs):
- Remove the Type-12 skip (was: no-media -> null, with-media -> UiDatElement).
- Add Type 12 -> BuildText() -> UiText in the switch.
- BuildText extracts the element's Direct/Normal sprite as BackgroundSprite
  so any dat-media the element carried keeps rendering under the text.

UiText changes (renamed from UiChatView.cs):
- BackgroundColor default: (0,0,0,0.35) -> (0,0,0,0) (transparent).
  An unbound UiText draws nothing; the controller opts in to the translucent bg.
- New BackgroundSprite + SpriteResolve: optional dat state-sprite background
  drawn UNDER DrawFill+text (faithful UIElement_Text media support).

ChatWindowController.cs (Task 5 Step 8):
- Transcript property: UiChatView -> UiText.
- Bind() now uses layout.FindElement(TranscriptId) as UiText (factory-built)
  instead of manually constructing + AddChild-ing a new UiChatView.
- Sets BackgroundColor = (0,0,0,0.35) on the found widget (retail translucent bg).
- Removes the tInfo null-check from the early guard (transcript is factory-built;
  iInfo lookup kept for the input widget which is still manually constructed).
- BuildLines: UiChatView.Line -> UiText.Line throughout.

Vitals frozen: the Type-12 vitals number elements are meter children and are
never recursed by BuildWidget (the `if (w is not UiMeter)` gate), so they are
not built as widgets and keep rendering via UiMeter.Label. Vitals fixture
vitals_2100006C.json unchanged; LayoutConformanceTests + VitalsBindingTests green.

Tests:
- UiChatViewTests.cs -> UiTextTests.cs (class: UiTextTests, all UiChatView.* -> UiText.*)
- UiChatViewDatFontTests.cs -> UiTextDatFontTests.cs (same)
- DatWidgetFactoryTests: delete Type12_StylePrototype_ReturnsNull +
  DatWidgetFactory_Type12WithMedia_Renders; add Type12_Text_MakesUiText +
  DatWidgetFactory_Type12_AlwaysMakesUiText.
- LayoutImporterTests: BuildFromInfos_Type12Child_IsSkipped_Type3Present updated
  to assert IsType<UiText> (element is now in tree, transparent, not skipped).

Divergence register: AP-37 amended -- removed the "standalone Type-0 text
elements skipped / dat-text widget is Plan 2" clause (now shipped as UiText);
kept the meter-collapse clause and the vitals-numbers-via-UiMeter.Label clause.
AP-38/AP-39/AD-28 file references updated UiChatView.cs -> UiText.cs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-16 17:39:02 +02:00
parent 67e5b8cff2
commit cb082b59e4
10 changed files with 127 additions and 118 deletions

View file

@ -32,12 +32,13 @@ public class LayoutImporterTests
Assert.Equal(150f, found.Width);
}
// ── Test 2: Type-12 child is skipped; Type-3 sibling is present ──────────
// ── Test 2: Type-12 child builds a UiText; Type-3 sibling is also present ──
/// <summary>
/// A root with two children: one Type-12 style prototype and one Type-3 container.
/// The Type-12 must be absent from the tree (FindElement returns null);
/// the Type-3 must be present.
/// A root with two children: one Type-12 UIElement_Text and one Type-3 container.
/// The Type-12 must appear as a <see cref="UiText"/> in the tree (transparent,
/// draws nothing until a controller binds its <c>LinesProvider</c>);
/// the Type-3 must also be present.
/// </summary>
[Fact]
public void BuildFromInfos_Type12Child_IsSkipped_Type3Present()
@ -48,9 +49,9 @@ public class LayoutImporterTests
var tree = LayoutImporter.BuildFromInfos(root, new[] { prototype, container }, NoTex, null);
// Type-12 must be absent.
Assert.Null(tree.FindElement(0x20000001));
// Type-3 must be present.
// Type-12 is now a UiText (transparent, no lines) — present in the tree.
Assert.IsType<UiText>(tree.FindElement(0x20000001));
// Type-3 must also be present.
Assert.NotNull(tree.FindElement(0x20000002));
}