Zoom: fix preview zoom box + shape-aspect anchoring (Unit: zoom box visuals)
Right-click in the live preview now procs a box that is actually visible and populated with the zoomed region, and each Zoom View Shape sculpts the box per spec. OBS-style derivative: magnifier box shows the composited region and dims the surroundings (same pattern as OBS "zoom" / preview region highlights). Root causes of the invisible box (two WPF traps, recorded in MyMistakes.md): - Empty <VisualBrush Stretch="None"/> used as an OpacityMask paints nothing, so the mask alpha is 0 and the WHOLE box (border included) went transparent. - ZoomBox lived inside CanvasGrid while its VisualBrush sampled CanvasGrid — a circular reference WPF renders as nothing. Hoisted ZoomBox to a sibling of CanvasGrid inside a new PreviewCanvas wrapper (same 1920x1080 space). Shape semantics (MainViewModel.ActivateZoom): - Circle: square, click point = center. - VerticalRectangle (phone): tall 9:16, click point = top-left corner. - HorizontalRectangle (tablet): wide 16:9, click point = top-left corner. - Boxes stay fully inside 1920x1080 via Math.Clamp. UI: ZoomRectOutline/ZoomCircleOutline shapes replace the square Border; circle clips the box to an EllipseGeometry; brush Visual released when inactive. Zoom View Shape dropdown now uses the standard YtComboBox style. Test (Good Dog rule, one integration test): ZoomBoxInteractionTests verifies aspect/anchoring/clamp per shape and the matching outline+clip in the real MainWindow. Full suite 404 passed, 0 warnings. Memory: HANDOFF.md zoom state updated; WPF VisualBrush traps appended to MyMistakes.md.
This commit is contained in:
@@ -1475,3 +1475,22 @@ a cycle debugging a test failure, ask what the machine was doing: an audio test
|
||||
gaming session is an environment fact, not a regression.** (Same family as the known
|
||||
`LayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorder` interactive-desktop
|
||||
flake — both are in the "run it in a quiet session" bucket, and neither is a code defect.)
|
||||
|
||||
## 2026-10-07 — WPF VisualBrush: two silent "invisible box" traps
|
||||
|
||||
Working on the zoom-magnifier box in PreviewPane. Two gold-plated WPF gotchas that made the box
|
||||
render NOTHING (no border, no content):
|
||||
|
||||
1. **An empty `<VisualBrush Stretch="None"/>` used as an `OpacityMask` paints nothing → the mask
|
||||
alpha is 0 → the WHOLE element (border included) becomes transparent.** A VisualBrush without a
|
||||
`Visual` is not "mask = none", it is "mask = fully transparent". An opacity mask wants a tile or a
|
||||
visual source; if you meant "no mask", OMIT the Grid.OpacityMask element entirely.
|
||||
2. **A `VisualBrush` whose `Visual` is an *ancestor* of the element it is painted on is a circular
|
||||
reference — WPF renders nothing (no exception, no content).** The zoom box lived inside CanvasGrid
|
||||
and the brush sampled CanvasGrid. Fix: hoist the box OUT so it becomes a *sibling* of the visual
|
||||
being sampled (wrap CanvasGrid + ZoomBox in a container Canvas, coordinates unchanged since both
|
||||
are in the same 1920x1080 space). Then `VisualBrush.Visual = CanvasGrid` samples cleanly and the
|
||||
box magnifies the already-composited preview.
|
||||
|
||||
Release the retained visual when the box hides (`VisualBrush.Visual = null`) or the long-lived
|
||||
source visual stays pinned for the app lifetime.
|
||||
|
||||
Reference in New Issue
Block a user