vv webcam Unit 2: the Chat scene in the vertical tier - rect only, tile or one whole 607x540 area
The creator's locked table (2026-10-17) gives the Chat scene its own rules in the 9:16 tier: RECT ONLY - the circle option is not offered - and a size that is either the normal small tile or ENLARGED to fill one whole 607x540 area (top or bottom). Unit 1 shipped the per-scene placement; this unit is the Chat scene's own variant of it. The rule lives on the MODEL, not on the button: - Models/SceneElement.cs: ClipShape and ToggleClipShape() are now virtual. - Models/WebcamSceneConfig.cs: VerticalShapeLocked (set per scene by the VM) OVERRIDES the ClipShape property, so no writer can slip a circle in - the toggle, the Shape button and the placement swap all go through it. The lock is cleared BEFORE the 16:9 layout comes back, so the desktop shape returns. - ViewModels/MainViewModel.Webcam.cs: CanToggleClipShape (the circle is NOT offered in the vertical Chat layout - the Shape button disappears, it is not merely greyed out), IsChatSceneCamera, ResizeWebcamInVerticalTier. - Models/VerticalCameraLayout.cs: FillsArea (the "enlarged" state, derived - no new column) and SizeFor - the Chat camera's TWO sizes, the tile or the whole area, whichever is nearer the requested width, so the resize handle has two detents instead of any size in between. - An enlarged camera FILLS the area its centre is in (top or bottom), so dragging it up/down swaps the areas. - The Chat camera is auto-tiled like the Live one when the vertical tier is picked - otherwise the vertical chat stream has no camera at all. - Controls/PreviewPane.xaml.cs: the resize routes through the VM; the drag assigns, lets the model clamp into the band, then snaps (so the enlarged camera can be dragged from the top area to the bottom one). Test: ytLive.Tests/VerticalChatCameraLayoutTests.cs - the ONE Good Dog test for the unit: the vertical tier is picked -> the Chat camera comes into the band as a small RECT tile -> the circle option is not offered and cannot be set even on the model -> dragged up and enlarged it fills the TOP area exactly -> back to 16:9 the desktop layout is restored exactly and the circle option is offered again. 430/430 tests pass, 0 warnings. Research (the creator's table is the established practice, not our invention): - Streamlabs' vertical guide: "splitting the screen in half horizontally, placing the camera feed in the top half and the main content on the bottom (or vice versa) may be the bet", and a just-chatting vertical wants the camera "to take up most of the screen" (streamlabs.com/content-hub/post/overlays-vertical-and-horizontal-streaming) - Bloopbot's vertical overlay docs describe the same per-layer model we use at scene granularity: "move or resize a layer on Vertical and it stops being Auto-placed. It keeps the place you gave it, and the horizontal layout is not touched" (bloopbot.com/docs/vertical-overlays-twitch-dual-format) - our swap-at-tier-change, stored per scene. - Landmine recorded: "about the bottom 560 px of the vertical video can be covered by Twitch's chat and player controls on phones" (Bloopbot) - the Chat camera's enlarged BOTTOM area may be half-hidden by the platform chrome; TASK 53's safe-zone work decides that. Memory in the same commit: ai.md (the Chat rules, the shape lock, the tests), TASKS.md + TASKS/task-57-vertical-camera-layout.md (TASK 57 complete), HANDOFF.md, MyMistakes.md (3 recipes: lock the model property not the UI button; two detents for a discrete size set; the edit tool cannot match an oldString with an em dash), Models/ViewModels/Controls index rows.
This commit is contained in:
@@ -717,7 +717,7 @@ which also `ScheduleSave`s). Per raw frame a background worker (latest-frame-dro
|
||||
(`BlurRadius(0.5)` = 2, `BlurRadius(1)` = 6) and the behaviour at a step edge: default smears
|
||||
light ~9px into the dark half vs ~26px at full strength.
|
||||
|
||||
### Vertical (9:16) tier camera placement (TASK 57 — "vv" Unit 1, built 2026-10-21)
|
||||
### Vertical (9:16) tier camera placement (TASK 57 — "vv" Units 1+2, built 2026-10-21)
|
||||
|
||||
**The problem.** The vertical tier (1080×1920) is a centred **band crop** of the SAME 1920×1080
|
||||
master: `OutputRect*` = x 656.25, y 0, w 607.5, h 1080. A camera placed for 16:9 (the default
|
||||
@@ -732,7 +732,7 @@ exactly:
|
||||
|---|---|---|---|
|
||||
| 16:9 | as today | as today | as today |
|
||||
| **vv · Live** | circle **or** rect (the creator's choice, per scene) | small tile | one of **six** spots: top/bottom × left/centre/right |
|
||||
| vv · Chat | *Unit 2* (rect only; normal, or enlarged to one 607×540 area) | — | — |
|
||||
| vv · Chat | **rect only** (the circle option is not offered) | the small tile (normal), or enlarged to fill one 607×540 area | the same six spots; enlarged fills the top or the bottom area |
|
||||
| Starting / BRB / Ending | unchanged | unchanged | unchanged |
|
||||
|
||||
**Design — geometry only, no render-path change.** The preview and the compositor both read the
|
||||
@@ -761,6 +761,17 @@ spot — the corner the 16:9 default webcam uses. The Live scene gets that tile
|
||||
first time the vertical tier is picked (otherwise the vertical stream has no camera at all); the
|
||||
other scenes keep their 16:9 placement until the creator drags them into the band.
|
||||
|
||||
**The Chat scene's own rules (Unit 2).** In the vertical tier the Chat camera is **rect only**:
|
||||
the circle is not *offered* (`MainViewModel.CanToggleClipShape` is false → the Shape button
|
||||
disappears) and the model refuses it too — `WebcamSceneConfig.ClipShape` is **overridden**, so a
|
||||
locked camera cannot become Round by ANY writer (the toggle, the button, the placement swap). The
|
||||
lock is `WebcamSceneConfig.VerticalShapeLocked`, set by the VM per scene and cleared **before** the
|
||||
16:9 layout comes back, so the desktop shape is restored. Its **size is discrete**: the small tile
|
||||
(normal) or one whole 607×540 area (enlarged) — the resize handle snaps to the nearer of the two
|
||||
(`VerticalCameraLayout.SizeFor`), and an enlarged camera **fills the area its centre is in** (top
|
||||
or bottom). The Chat scene also gets its tile automatically the first time the vertical tier is
|
||||
picked (like Live) — otherwise the vertical chat stream has no camera at all.
|
||||
|
||||
**Manual entry** (creator rule): the webcam's Layers properties gained a **Geometry** section
|
||||
(X/Y/W/H) — it edits the LIVE placement, i.e. the one the current tier shows. The webcam's
|
||||
geometry setters clamp it into the band, so a typed value can never push the camera out of the
|
||||
@@ -773,11 +784,15 @@ built-in way to store separate layouts per aspect ratio, so you rely on manual w
|
||||
plugins" — streamyard.com/blog/dual-aspect-ratio-streaming-tool). Our per-scene, per-tier stored
|
||||
placement, resolved on the tier change, is the step past that.
|
||||
|
||||
**Tests.** `VerticalWebcamLayoutTests` — the ONE integration test for the unit: the vertical tier
|
||||
**Tests.** `VerticalWebcamLayoutTests` — the ONE integration test for Unit 1: the vertical tier
|
||||
is picked → the Live camera comes INTO the band as a small tile → dragged to the top-right it
|
||||
lands top-right inside the band → back to 16:9 the desktop layout is restored exactly → and both
|
||||
placements survive a save + reload. (The store writes the webcam rows only when the app has a
|
||||
webcam identity — the config rows hang off it — so the test supplies one.)
|
||||
`VerticalChatCameraLayoutTests` — the ONE integration test for Unit 2: the vertical tier is picked
|
||||
→ the Chat camera comes into the band as a small RECT tile → the circle option is not offered and
|
||||
cannot be set even on the model → dragged up and enlarged it fills the **top** area exactly → back
|
||||
to 16:9 the desktop layout is restored exactly and the circle option is offered again.
|
||||
|
||||
**Known trap (see `MyMistakes.md`):** a second properties panel bound to `SelectedElement.IsWebcam`
|
||||
broke `WebcamBackgroundPillTests` — that test finds the webcam's panel by **binding text**, so a
|
||||
|
||||
Reference in New Issue
Block a user