acdream/src
Erik 47eb2d575b fix(plugin-ui): shelf children must not anchor — the per-draw anchor pass was undoing collapse/reflow geometry
EVIDENCE (live UI probe dump at 1280x720, build 2ebcc0164): after collapsing
the plugin shelf, PluginSidePanel rect=(1240,233,24,28) was correct, but
ShelfGripPanel rect=(1240,233,20,18) and the toggle rect=(1260,233,16,18)
stayed UNCHANGED from the expanded geometry. The toggle then sat outside the
24px shelf and the ancestor clip removed it, so the owner saw the tab with
no "<".

ROOT CAUSE: UiElement.ApplyAnchor (src/AcDream.App/UI/UiElement.cs ~829-856)
runs for every child on every draw (called at :699). For any child whose
Anchors != AnchorEdges.None, it captures the Left/Top/Width/Height margins
ONCE (_anchorCaptured) on the first draw and re-applies that snapshot every
subsequent draw, overwriting whatever PluginSidePanel.LayoutChrome/Reflow had
just set. The grip, the toggle, and each PluginShelfButton entry were
constructed with the default Anchors (Left|Top), so their first-draw
geometry froze. The shelf itself already used AnchorEdges.None for exactly
this reason. Unit tests never caught it because UiRoot.Tick does not draw —
the anchor snapshot only exists after a real Draw pass, and the prior
draw-level toggle tests only ever drew once, before any collapse.

FIX: set Anchors = AnchorEdges.None on _grip, _toggle (PluginSidePanel
constructor) and each PluginShelfButton entry (PluginSidePanel.Add) — the
shelf is the sole layout owner of these children and anchoring is the wrong
mechanism for them, not a per-reflow patch via ResetAnchorCapture().
PluginMinimizeButton is untouched (it is a child of the plugin window and
deliberately anchors Top|Right).

TESTS (tests/AcDream.App.Tests/UI/PluginSidePanelToggleGlyphClipTests.cs):
- Collapse_AfterADraw_RepositionsGripAndToggle_NotFrozenAtExpandedGeometry:
  draws the shelf, collapses via a real UiRoot press/release, draws again,
  and asserts the grip/toggle geometry actually reflects the collapsed
  Width/Height rather than the frozen expanded snapshot. Failed-first
  (pre-fix) at line 364 with "Expected: 8, Actual: 20" (grip.Width frozen at
  the pre-collapse value instead of the new collapsed Width - ToggleWidth).
- MultiColumnReflow_AfterADraw_EveryRemainingButtonMatchesAFreshSinglePassLayout:
  12 entries, draw, unregister one window (a real removal), draw again, and
  compares every surviving button's geometry against an independent
  reference shelf built directly with the same final 11-entry set. Failed-
  first with "Expected: 16, Actual: 48" (a surviving button's Left frozen at
  its stale 12-entry column/row instead of the fresh 11-entry reflow).

Both tests use font: null (bitmap fallback) so they run in every CI lane
without an installed retail DAT, unlike the Lane=InstalledDat tests above.

VERIFY: dotnet build (Release) green for src/AcDream.App and the test
project. Targeted filter (PluginSidePanel|Markup|UiRootInput): 130/130
passed. Full tests/AcDream.App.Tests suite: 7353 passed / 97 skipped / 36
failed - matching the stated baseline (7351/97/36) plus the two new tests;
the 36 failures are the pre-existing environment-gated set (installed-DAT
version mismatch, Linux-only waiter, Lane=Manual live-mount probes) and are
unrelated to this change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 16:04:04 +02:00
..
AcDream.App fix(plugin-ui): shelf children must not anchor — the per-draw anchor pass was undoing collapse/reflow geometry 2026-09-06 16:04:04 +02:00
AcDream.Bake Optimize prepared asset package v2 2026-08-27 20:09:09 +02:00
AcDream.Cli fix: make locale-independence real, not assumed — parsing, casing, comparison 2026-08-19 20:11:32 +02:00
AcDream.Content fix(rendering): carry retail SetSurface state to detail draws 2026-09-05 02:03:13 +02:00
AcDream.Core fix(physics): port ordered part-array building transit 2026-09-05 20:28:52 +02:00
AcDream.Core.Net fix: complete retail parity stability pass 2026-08-28 20:01:39 +02:00
AcDream.Headless fix: complete retail parity stability pass 2026-08-28 20:01:39 +02:00
AcDream.Launcher Optimize prepared asset package v2 2026-08-27 20:09:09 +02:00
AcDream.Launcher.Core fix(rendering): carry retail SetSurface state to detail draws 2026-09-05 02:03:13 +02:00
AcDream.Platform feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugin.Abstractions fix(plugin-ui): Slice B review fixes — no magenta for bad DIDs, contract threshold, integral icon bindings, nearest did art, loud markup errors 2026-09-06 15:43:56 +02:00
AcDream.Plugins.MossTank feat(mosstank): add VTank-style automation PoC 2026-08-27 18:57:21 +02:00
AcDream.Plugins.Smoke fix(plugin-ui): Slice B review fixes — no magenta for bad DIDs, contract threshold, integral icon bindings, nearest did art, loud markup errors 2026-09-06 15:43:56 +02:00
AcDream.Runtime fix(overhaul): integrate reviewed debt-free retirement #475 2026-09-05 11:05:07 +02:00
AcDream.UI.Abstractions feat(rendering): port retail building degrade walk 2026-09-04 22:29:18 +02:00