Zoom: compose the box as a real 2x layer above the background (Unit: zoom layer + magnification proof)
Right-click now creates a transient ZoomSceneElement at z-index 1 whose pixels are a genuine 2x magnified sample of the backdrop (live capture under art), composited into stream/recording like any layer while the output crop stays the tier. All shapes are centered on the click and clamped to frame; healed on load/scene-create, never persisted, hidden from the layers list + element template (IsZoomLayer). BuildCompositorOptions is now internal = always tier crop (test seam). ZoomFrameBuilder is a pure static sampler (box/2 window centered on the box center, single-slot cache) proven by a banded-backdrop test; LayerReorderPersistenceTests drag resolves rows by item since the collapsed zoom row shifts container indices. Also books TASK 51 (webcam background Remove + Blur) and syncs memory docs (HANDOFF, MyMistakes, indexes). Full suite: 405 passed, 0 warnings.
This commit is contained in:
+23
-25
@@ -1,36 +1,34 @@
|
||||
# HANDOFF — 2026-10-07
|
||||
# HANDOFF — 2026-10-08
|
||||
|
||||
## Branch
|
||||
- main (no feature branch)
|
||||
|
||||
## Dirty files
|
||||
- None (zoom box fix + test committed as a work unit this session).
|
||||
## Dirty files (NOT mine — the in-flight "pinned chat" work unit; do NOT commit or co-edit)
|
||||
- `Models/YouTube.cs`
|
||||
- `ViewModels/MainViewModel.Chat.cs`
|
||||
- `Controls/LeftPanel.xaml` (pinned-message UI; restored via `git stash pop` after this commit)
|
||||
- Untracked: `Helpers/RelayCommandGeneric.cs`
|
||||
|
||||
## What just happened
|
||||
- Fixed the zoom box: right-click in live preview now procs the selected Zoom View
|
||||
Shape with correct anchoring and a visible, populated box (previously invisible —
|
||||
empty OpacityMask made the whole box transparent and the VisualBrush pointed at the
|
||||
CanvasGrid *ancestor*, a circular reference WPF renders as nothing).
|
||||
- Zoom View Shape dropdown now uses the app's standard `YtComboBox` style.
|
||||
- One integration test added (Good Dog Rule): `ZoomBoxInteractionTests` — circle is a
|
||||
centered square, phone is a tall 9:16 rect and tablet a wide 16:9 rect, both anchored
|
||||
top-left at the click, box stays inside 1920x1080 (clamp), and the UI shows the right
|
||||
outline/clip per shape. Full suite: 404 passed, 0 warnings.
|
||||
## What just happened (2026-10-08 zoom build)
|
||||
- **TASK 51 booked (webcam background Remove + Blur as a v1 requirement):** `TASKS/task-51-webcam-bg-effects.md` created; TASKS.md row 51 + the two prior "background removal excluded" rulings (`~line 180` webcam cadence + "Out of product — permanently") reversed 2026-10-08. NVIDIA VFX SDK stays ruled out. Implementation queued after the zoom build.
|
||||
- **Zoom rebuilt from "loupe + output crop" into a REAL composited layer:**
|
||||
- New `Models/ZoomSceneElement.cs` (z-index 1 above the background, below every other layer; `IsZoomActive` flips `Kind` Static→Dynamic; never persisted, never shown in the layers list or element template). `SceneElement.IsZoomLayer` virtual added.
|
||||
- New `ViewModels/MainViewModel.Zoom.cs`: `ActivateZoom` (all shapes CENTERED on the click, clamped to the master), move/dismiss, `HealZoomLayers`/`EnsureZoomLayer` (load + `AddScene`), `BuildZoomFrame` (resolves live-capture-under-art exactly like `SceneCompositor.Render`, single-slot cache keyed on frame identity+Epoch+box ints so the per-tick resolver allocates nothing idle), and the pure static `ZoomFrameBuilder.Build` (2x bilinear sample of the box/2 window centered on the box centre).
|
||||
- `BuildCompositorOptions` now ALWAYS returns the tier crop (internal = test seam); zoom-as-crop branch + `RebuildDimRectsForZoom` old version removed. `ResolveOutputFrameCore` gained the `ZoomSceneElement` case; output composites the zoom like any layer.
|
||||
- Preview: backdrop images wrapped in `BackdropLayer`; `ZoomBox` moved INSIDE `OverlayCanvas` under the element Layers (renders below layers = honest preview); `ZoomVisualBrush` now samples `BackdropLayer` at `(X+W/4, Y+H/4, W/2, H/2)` + `Stretch=Fill` (2x); element template + LeftPanel list collapse `IsZoomLayer`.
|
||||
- Tests: `ZoomBoxInteractionTests` rewritten (center-anchor for all shapes, placeholder at Elements[1], Kind flips, tier crop asserted, dismiss resets); new `ZoomFrameBuilderTests` = the genuine-magnification proof (4-band backdrop, box straddling two bands, all output pixels must be the center band → a 1x or mis-positioned window fails hard). `LayerReorderPersistenceTests` updated: cross-type reload compares persisted elements only (the zoom placeholder never persists), and the real-mouse drag targets rows by ITEM (the collapsed zoom row shifts container indices — the handlers hit-test visually so real dragging is unaffected).
|
||||
- Full suite: **405 passed / 0 failed / 0 warnings**.
|
||||
|
||||
## Zoom feature state
|
||||
- Models/ZoomState.cs + Models/ZoomShape.cs (Circle, VerticalRectangle, HorizontalRectangle)
|
||||
- ViewModel: zoom box activation/move/dismiss; compositor output crops+scales the zoom region; dimming updates
|
||||
- PreviewPane: zoom box is a *sibling* of CanvasGrid inside a new `PreviewCanvas` wrapper
|
||||
(so the VisualBrush can sample CanvasGrid without a circular reference); shape-aware
|
||||
outline (`ZoomRectOutline`/`ZoomCircleOutline`) + ellipse clip for Circle
|
||||
- Shape semantics in `MainViewModel.ActivateZoom`: Circle = click point is center, w=h=min(maxW,maxH);
|
||||
VerticalRectangle = 9:16 tall, HorizontalRectangle = 16:9 wide, both anchored top-left at the click; clamped to frame
|
||||
- Settings (OverlayHost) Zoom View Shape persisted via LayoutStore
|
||||
- Models: `ZoomState.cs`, `ZoomShape.cs` (Circle/VerticalRectangle/HorizontalRectangle), `ZoomSceneElement.cs` (TASK 51 build).
|
||||
- ViewModel (all in `MainViewModel.Zoom.cs`): activation/move/dismiss + layer healing + `BuildZoomFrame`; `MainViewModel.cs` core no longer holds zoom methods.
|
||||
- Output: zoom layer composited at z-index 1; output crop = tier; dim rects show the box frame while active.
|
||||
- Preview: `ZoomBox` samples `BackdropLayer` at 2x, circle→ellipse clip, rect/square outline per shape; `LeftPanel` hides the placeholder row via `IsZoomLayer`.
|
||||
|
||||
## Known issues / follow-ups
|
||||
- Background toggle bug mentioned earlier: when clicking "Use default background" in layer properties, nothing happens. Need to investigate - binding exists (UseDefaultBackground), VM has handler that invalidates bake and updates. May need to look up Source background logic.
|
||||
- **Background "Use default background" toggle still not working** (carried from 2026-10-07): binding exists (`UseDefaultBackground`), VM handler invalidates bake; investigate Source background logic when time permits.
|
||||
- `AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback` flaked once in a full-suite run (passed in isolation 27/27 and in the final full run) — treat as machine-contention flake, not a zoom regression.
|
||||
- `RealMouseDrag_OnTheLayerList_PersistsTheReorder` needs an interactive desktop (documented) — it passes when the window is live; don't read a failure there as a code bug without re-running.
|
||||
|
||||
## Next step
|
||||
- User runs the app live/test to eyeball the zoom box visuals (border shows, region content visible,
|
||||
circle is round, phone/tablet anchored at the click point). Then background "Use default background"
|
||||
toggle if still needed. Otherwise stand down.
|
||||
- User runs the app live/test to eyeball the zoom: right-click preview → centered box per shape, output contains a genuine 2x magnified backdrop under the other layers, dimming + outline correct, layers list unchanged. Then TASK 51 (webcam background Remove + Blur) implementation per `TASKS/task-51-webcam-bg-effects.md`, and the background-toggle investigation if still open.
|
||||
Reference in New Issue
Block a user