acdream/tests/AcDream.UI.Abstractions.Tests
Erik a44488e277 fix(ui): chat input pinned to window bottom on resize via scrollable child
User reported the chat input field disappearing when the chat
window was resized smaller — older entries pushed it past the
visible area. Standard ImGui chat-window pattern fixes it: scrollable
nested region for the chat tail, fixed footer for the
separator + input field below it.

IPanelRenderer extensions (Phase J Tier 3):
- BeginChild(string id, Vector2 size, bool border = false) — opens
  a nested scrollable region. Size follows ImGui semantics:
  0 = fill available, negative = fill available minus this much.
- EndChild() — closes the nested region.
- FrameHeightWithSpacing() — single-line widget height incl. frame
  padding + item spacing. Lets panels compute footer reservations
  without hardcoding pixel constants.
- SetScrollHereY(float ratio) — forces scroll within current region;
  pass 1.0f to keep the latest line visible after new entries
  arrive.

ImGuiPanelRenderer impls. ImGui.NET's BeginChild signature changed
across versions (third arg moved from `bool border` to
`ImGuiChildFlags`); we cast a numeric literal (0x01 = Border bit)
to sidestep the rename. FrameHeightWithSpacing maps to
ImGui.GetFrameHeightWithSpacing(); SetScrollHereY to ImGui.SetScrollHereY.

ChatPanel restructured:
- Reserves footer height = FrameHeightWithSpacing() + 6f (small pad
  for the separator above the input).
- Wraps the chat tail in BeginChild("##chattail", (0, -footer))
  so the inner region scrolls independently of the window.
- Tracks _lastRenderedCount across frames and calls SetScrollHereY(1f)
  only when new entries appended — manual scroll-up isn't fought
  against; new messages jump the view back down only when they
  actually arrive.
- Header Separator removed (the BeginChild border is enough).

FakePanelRenderer extended with the four new methods + recording.
4 new tests in ChatPanelLayoutTests pin the layout invariants:
- Render order: Begin → BeginChild → ... → EndChild → Separator
  → InputTextSubmit → End.
- BeginChild size has X=0 + negative Y at least matching the
  injected FrameHeightWithSpacingValue.
- SetScrollHereY fires when entries grow.
- SetScrollHereY does NOT fire when entries don't grow.

Solution total: 1067 green (243 Core.Net + 164 UI + 660 Core),
0 warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 21:44:10 +02:00
..
Panels fix(ui): chat input pinned to window bottom on resize via scrollable child 2026-04-25 21:44:10 +02:00
AcDream.UI.Abstractions.Tests.csproj test(ui): AcDream.UI.Abstractions unit tests (11 tests green) 2026-04-25 00:25:26 +02:00
ChatVMTests.cs fix(chat): BuildTell wire field order + retail-style FormatEntry + suppress duplicate Channel echo 2026-04-25 20:49:02 +02:00
FakePanelRenderer.cs fix(ui): chat input pinned to window bottom on resize via scrollable child 2026-04-25 21:44:10 +02:00
IPanelRendererWidgetTests.cs feat(ui): #14 IPanelRenderer widget extension - TextColored, Checkbox, Combo, InputTextSubmit, BeginTable, etc. 2026-04-25 19:03:28 +02:00
LiveCommandBusTests.cs feat(ui+net): #16 LiveCommandBus + WorldSession.Send{Talk,Tell,Channel} + SendChatCmd wiring 2026-04-25 19:27:22 +02:00
NullCommandBusTests.cs test(ui): AcDream.UI.Abstractions unit tests (11 tests green) 2026-04-25 00:25:26 +02:00
PanelContextTests.cs test(ui): AcDream.UI.Abstractions unit tests (11 tests green) 2026-04-25 00:25:26 +02:00
SendChatCmdTests.cs feat(ui+net): #16 LiveCommandBus + WorldSession.Send{Talk,Tell,Channel} + SendChatCmd wiring 2026-04-25 19:27:22 +02:00
VitalsVMTests.cs feat(player): #5 PlayerDescription parser — Stam/Mana via attribute block 2026-04-25 16:42:24 +02:00