feat(37): expose the all-scenes factory reset

App Settings now offers a clearly described all-scenes reset. It is disabled
while live or recording and reloads the restored layout immediately. The
integration test drives the real VM command and checks the Settings binding.
614 tests green, clean build with 0 warnings.

Reference: OBS Scene Collections are a distinct saved set of scenes and sources:
https://obsproject.com/kb/scene-collections
This commit is contained in:
2026-11-10 18:05:35 -08:00
parent b8eb2b4451
commit 41064bdd13
4 changed files with 72 additions and 1 deletions
+7
View File
@@ -123,6 +123,13 @@
Value="{Binding TransitionDurationMs, Mode=TwoWay}" VerticalAlignment="Center"/>
</DockPanel>
<!-- ═══ LAYOUT DEFAULTS (TASK 37) ═══ -->
<TextBlock Text="Layout defaults" Style="{StaticResource SectionHeader}" Margin="0,10,0,4"/>
<TextBlock Text="Replaces every scene and layer with this build’s factory layout. Your selected webcam stays the same."
Style="{StaticResource PropertyHint}" Margin="10,0,0,6"/>
<Button Content="Restore all scenes" Command="{Binding RestoreAllLayoutDefaultsCommand}"
Style="{StaticResource YtButtonSecondary}" Margin="10,0,0,10" HorizontalAlignment="Left"/>
<!-- Development panel host. Empty in a Release build: the panel itself is excluded
from the Release compile, and the code-behind only fills this inside #if DEBUG. -->
<StackPanel x:Name="DeveloperPanelHost"/>
+1 -1
View File
@@ -13,7 +13,7 @@ See [`schema.md`](../schema.md) for the memory-map conventions.
| `PreviewPane.xaml(.cs)` | Row 2 Col 1 center: 1920×1080 `OverlayCanvas`/`SelectionOverlay`/`BrandFlashLayer`/`SocialBarElement`, static TextOverlay preview image from the shared cached text raster, text drawer, outgoing-picture transition overlay, right-edge Stream Info/YPP/Socials/TEST tabs and drawers, and live controls (TRAX / game / mic meters + sliders + speakers). The list-selected draggable layer is temporarily raised in preview z-order and custom hit-testing; deselection restores the scene's unchanged order (`SelectedLayerPreviewHitTestingTests`). **TASK 57:** dragging/resizing a webcam in the vertical tier routes through `MainViewModel.MoveWebcamInVerticalTier` / `ResizeWebcamInVerticalTier` for the six-spot snap or Chat camera's two sizes. |
| `SceneThumbnailStrip.xaml(.cs)` | Top row over the preview column: five fixed-size scene cards with scene name, hotkey, staged `PROGRAM` badge, orange staged/live border |
| `LeftPanel.xaml(.cs)` | Row 2 Col 0 left panel: explicit EditingActive toggle on → Scene Layers+properties; off → YouTube chat, independent of stream status. Source add/edit/remove, list drag-to-reorder, snapshot revert-accept; TextOverlay properties edit multiline content, font type/family, size, color via the shared palette, emphasis, and horizontal/vertical alignment with a static-text notice; sub-options are indented under their headings. **TASK 51:** the webcam properties carry the Background section — `RemoveBackgroundPill` / `BlurBackgroundPill` (`PillToggle`, radio-exclusive via `WebcamSceneConfig.RemoveBackground`/`BlurBackground`) + `BackgroundStrengthSlider` (0..1, 5% snaps, shown only while an effect is on). **TASK 57:** the webcam properties carry a Geometry section (X/Y/W/H) — manual placement of the camera, bound to the **live** placement (the one the current tier shows), gated on `IsWebcamSelected` (not `SelectedElement.IsWebcam` — the TASK 51 test finds that panel by binding text and would match twice); the Shape button's `Visibility` is bound to `CanToggleClipShape`, so the circle option is NOT OFFERED in the vertical Chat layout. **TASK 58:** every drop-down, check box and field in the properties panel carries the theme's style (`YtComboBox`/`YtCheckBox`/`YtTextBoxCompact`) and paints no colour of its own — the guard is `ytLive.Tests/PropertiesStyleTests.cs`. **TASK 59:** the webcam's properties are a HIERARCHY — a `Shape` title owns the mirror switch and the shape choice (`Rect` | `Circle` as two `SegmentToggle` options, Rect selected by default, the circle option hidden where `CanToggleClipShape` is false), and every titled block (Geometry, Border Color, Border Thickness, Background) owns its content one indent deeper (Strength sits under Blur). **TASK 60:** the border-colour drop-down builds its menu from `Models/BorderColorPalette.cs` — each row is the hex plus the colour's NAME (`#e94560 Crimson`, tooltip "Crimson (#e94560)"); the swatch icon is unchanged. **TASK 61:** the four geometry fields (X/Y/W/H) share one fixed width (44px — the largest value, 1920, plus a sign) and their rows set `LastChildFill="False"`, so Y/H no longer stretch to fill the row. **TASK 62:** the border-colour field shows the palette's name beside the hex (`SelectedElement.BorderColorName`, empty for a custom hex) and keeps a fixed width so the name stays next to the hex. **TASK 63:** the border colour is picked with the **app's own drop-down** (`YtComboBox`) — the `...` button and its code-built `ContextMenu` are gone; the closed box shows the swatch + the colour's NAME, the rows show swatch + hex + name (the panel's own `DataTemplate`s + `Helpers/ClosedBoxTemplateSelector.cs`), and the hex field stays for a custom colour; `IsDescendantOf` falls back to `LogicalTreeHelper.GetParent` / `TemplatedParent` when `VisualTreeHelper.GetParent` returns `null` (at `PopupRoot`) so clicking a popup row does not trigger `MainWindow`'s deselection guard |
| `OverlayHost.xaml(.cs)` | Root-grid overlays: App Settings / Report Bug / Feature Request / About; About includes the output-quality conversion copy and an explicit llamacasty.com link, while the licensing/legal panel remains in-app. App Settings groups recording, brand-logo, preview, and transition controls. `BackToAbout_Click` lives here |
| `OverlayHost.xaml(.cs)` | Root-grid overlays: App Settings / Report Bug / Feature Request / About; About includes the output-quality conversion copy and an explicit llamacasty.com link, while the licensing/legal panel remains in-app. App Settings groups recording, brand-logo, preview, transition, and layout-default controls. `BackToAbout_Click` lives here |
| `SceneThumbnailStrip.xaml.cs` | Code-behind for the strip above |
| `LeftPanel.xaml.cs` | Code-behind for the panel above |