feat(zoom): Ctrl closes the box, and a Follow pill that re-anchors the capture

Two creator directives, 2026-11-01.

**Ctrl-down dismisses an open zoom box.** Window-level PreviewKeyDown, so the same hand that
opened it can put it away. It cannot cancel itself at creation: Ctrl is already held before
the right-click that makes the box, so the keydown fires while nothing is open.

**Follow mode, default Anchor.** A PillToggle in App Settings ("Follow the box"), persisted
as Zoom.FollowBox. Off — the default — keeps the 2026-10-08 model: the capture stays on the
clicked point and dragging only moves the box over it. On, UpdateZoomMove re-anchors the
capture to the box centre (half the box's size, clamped per axis), so the magnifier shows
whatever it hovers. Flipping to Follow while the box is open snaps it immediately.

Three tests: anchor drags leave CaptureX alone, follow moves it to the expected quarter-offset
centre, and the setting round-trips through LayoutStore (tested against the store, not via two
view models — two live VMs fight over the temp DB, which is a fixture problem, not a bug).

Both new test classes share a collection tag: MainViewModel.LayoutPathOverride is static, and
xUnit runs classes in parallel, so without it the two view models collided (one failure in a
combined run, clean when run apart).

Release build 0 warnings; 14 tests pass across zoom, entitlement and preview history. Debug
build is blocked by the running app (PID 47388) — close it and the exe updates.
This commit is contained in:
2026-11-01 08:51:28 -08:00
parent 1d2d58f1d7
commit 15734a5477
9 changed files with 201 additions and 3 deletions
+11
View File
@@ -112,6 +112,17 @@
Value="{Binding TransitionDurationMs, Mode=TwoWay}" VerticalAlignment="Center"/>
</DockPanel>
<!-- Zoom box (creator ruling 2026-11-01): Anchor keeps the magnification on
the point that was clicked; Follow re-anchors it to the box as it is
dragged. Anchor is the default and the persisted norm. -->
<TextBlock Text="Zoom box" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,2"/>
<DockPanel Margin="10,0,0,8">
<ToggleButton DockPanel.Dock="Right" Style="{StaticResource PillToggle}"
IsChecked="{Binding ZoomFollowsBox, Mode=TwoWay}" VerticalAlignment="Center"
ToolTip="Off: the box magnifies the area you clicked. On: it magnifies whatever it hovers over."/>
<TextBlock Text="Follow the box" Foreground="{StaticResource Brush.OnSurface}" FontSize="11" VerticalAlignment="Center"/>
</DockPanel>
<!-- Development panel host. Empty in a Release build: the panel itself is
excluded from the Release compile, and OverlayHost.xaml.cs only fills
this inside #if DEBUG. Never put content here directly. -->