feat(settings): position slide-out notifications
App Settings now chooses one of six ToastArea positions (left/right × top/center/bottom), defaulting to the existing bottom-right. The setting is persisted per profile and the toast area moves immediately; edge gutters keep bottom notifications above the footer. ToastPositionIntegrationTests covers live repositioning and restart persistence. 617 tests green, clean build with 0 warnings. Reference scan: OBS Notifier supports user-configured notification placement: https://github.com/DmitriySalnikov/OBSNotifier
This commit is contained in:
@@ -159,7 +159,7 @@ The app is a **director's control surface**, not an editor. This replaces the OB
|
||||
**Current layout (2026-10-26 redesign commits):** `MainWindow` has a top bar and health banner, then a two-column work area with a fixed 360px left column and preview column. Its top row holds stream readouts/resolution on the left and the five-scene strip above the preview; the lower row holds the left panel and central preview. The bottom bar is now only a height-preserving spacer.
|
||||
|
||||
- **Left panel:** `EditingActive` is an explicit `EDIT` toggle, not a mode inferred from `StreamStatus`. On = scene layers + properties; off = a two-tab panel with **Live Chat** first/default and **Logs** second. Logs is a read-only view of up to 500 `AppLog` entries captured in this process; it does not load older `startup.log` contents or change file logging/rotation. Entries wrap and use the theme's type colors. Explicit Class 1/2 severity is independent of message type/source: Class 1 sorts above Class 2 in the pinned group; acknowledging unpins the entry but retains it in the chronological list. The staged scene is the preview/edit target; `LiveScene` is the program output.
|
||||
- **Settings is a right-edge drawer, not a modal (2026-11-01):** the gear rail tab opens `Controls/SettingsDrawer` in the same animated-width stack as Stream Settings / YPP / Socials / TEST (`SettingsDrawerOpen`, exclusive with the other four). Categories are section headings with their controls indented under them — Zoom holds *Zoom view shape* and *Zoom box follows*. TASK 37 adds **Restore staged scene** and **Restore all scenes** under Layout defaults; both are disabled while live or recording, and restoring a layout preserves the selected webcam. The app menu (Report Bug / Feature Request / About) hangs off a **right-click on the LlamaCasty wordmark**; left-click still opens About. The modal shell keeps only Bug / Feature / About, which is why it no longer needs a scroll viewer.
|
||||
- **Settings is a right-edge drawer, not a modal (2026-11-01):** the gear rail tab opens `Controls/SettingsDrawer` in the same animated-width stack as Stream Settings / YPP / Socials / TEST (`SettingsDrawerOpen`, exclusive with the other four). Categories are section headings with their controls indented under them — Zoom holds *Zoom view shape* and *Zoom box follows*. TASK 37 adds **Restore staged scene** and **Restore all scenes** under Layout defaults; both are disabled while live or recording, and restoring a layout preserves the selected webcam. App Settings also controls slide-out toast placement (six left/right × top/center/bottom positions; bottom-right default). The app menu (Report Bug / Feature Request / About) hangs off a **right-click on the LlamaCasty wordmark**; left-click still opens About. The modal shell keeps only Bug / Feature / About, which is why it no longer needs a scroll viewer.
|
||||
- **Top bar:** the `EDIT` toggle sits beside the REC/ON-AIR session controls; the brand and account surfaces remain at the sides. Its background uses the idle surface color when stopped. Normal ON-AIR stays `Brush.Primary` red while connecting and turns `Brush.Positive` green only after YouTube reports the broadcast `live`; stopping restores the idle color. TEST stays gold for the entire test session. Its **right edge aligns with the layers panel below** (`TopBar` column 0 is a fixed **352** = work-area margin 8 + 360px column − the bar's own 16px padding), so the button and the panel share an edge. The **settings gear moved to the preview rail** (2026-11-01): first tab, orange (`Brush.Attention`), gear icon only — left-click opens the app menu (Settings / Bug / Feature / About), right-click goes straight to App Settings.
|
||||
- **Preview gestures (2026-11-01):** *edit mode* — left selects/drags/resizes, right opens the context menu, **Ctrl+right toggles the zoom box**. *Preview mode* — **left toggles the zoom box**, right opens the context menu; **Ctrl+right does nothing at all** (no chord while live or recording — one hand, always). ⚠️ **Both the Down and the Up event must be handled for a Ctrl+right-click**: WPF's `PopupControlService` opens a context menu on right-button-**up**, so suppressing only the down event leaves the menu appearing under the gesture (found 2026-11-01 in edit mode). Menus exist on the webcam layer and the backdrop; every other layer right-clicks through to the backdrop menu. Left-dragging with the zoom box open moves it, in both modes. **Ctrl-down closes it**: pressing Ctrl while the box is open dismisses it, so the same hand that opened it can put it away (`MainWindow_PreviewKeyDown`; the box cannot cancel itself on creation because Ctrl is already down before it exists). **Follow mode** is a Settings pill, default **off = Anchor**: with Follow on, dragging re-anchors the capture to the box centre (`ZoomFollowsBox`, persisted as the `Zoom.FollowBox` setting). **The gesture activates the box at the cursor**, not merely dismisses it: `ActivateZoom` no longer refuses when idle (it used to return unless `IsLive || IsRecording`, and `ToggleZoom` only ever dismissed — so the gesture did nothing at all outside a session until 2026-11-01). The social bar consumes its own click (toggle top ⇄ bottom), and the preview's tunnelling handler steps aside for it — otherwise the bar is unclickable in preview mode and drags the layer beneath it in edit mode.
|
||||
- **Preview undo/redo (2026-11-01):** `Ctrl+Z` / `Ctrl+Shift+Z`, window-level bindings, live only while `EditingActive` — undo with the preview showing program output would rewrite a scene nobody is looking at. `Models/PreviewHistory` snapshots element **references** plus geometry, visibility, order and membership, so move / resize / reorder / add / remove / hide all undo in one step per gesture (`PushPreviewUndo` is called once at drag or resize start, never inside the move loop). Property edits (colour, opacity, border, font) are **not** captured yet — stated in the type's doc comment so nobody assumes otherwise. The stack clears on layout load. Guard: `ytLive.Tests/PreviewHistoryTests.cs`.
|
||||
@@ -204,8 +204,9 @@ extension methods; `MainViewModel` news up the real `NotificationService` at its
|
||||
MIT — notice #10 in `THIRD-PARTY-NOTICES.txt`). Facts that cost a hunt:
|
||||
- The `NotificationArea` XAML control registers itself with the manager on `Loaded`; routing matches
|
||||
the area's `Name` against the request's `AreaName` — our host is `x:Name="ToastArea"` in MainWindow's
|
||||
root grid (last child = topmost z-order, `Grid.RowSpan=4`, bottom-right above the footer via
|
||||
`Margin="0,0,12,96"`, outside the preview Viewbox). An unknown AreaName silently drops the toast.
|
||||
root grid (last child = topmost z-order, `Grid.RowSpan=4`, global App Settings chooses one of six
|
||||
left/right × top/center/bottom positions; bottom placements leave a 96px footer gap). An unknown
|
||||
AreaName silently drops the toast.
|
||||
- `NeverExpires()` sets `ExpirationTime = TimeSpan.MaxValue` (NOT null); `NotificationColor.ToHex()`
|
||||
returns `#AARRGGBB` (alpha prefix).
|
||||
- Lifetimes: Info/Success ~4s, Warning ~8s auto-dismiss, Error sticky until dismissed (the pure mapping
|
||||
|
||||
Reference in New Issue
Block a user