Files
LlamaCasty/Controls/index.md
T
gramps 2273d20160 TASK 58: the properties panel wears the theme (no more light-system chrome)
The creator asked why the Stream Alerts "Display" drop-down was not in the same
style as the other drop-downs. It was never given the theme's YtComboBox style -
only a hand-painted Background/Foreground. Setting colours changes the paint, not
the template, so WPF still drew the light system ComboBox (grey border, system
arrow, white popup list) on top of the dark panel. The chat Font drop-down was a
copy of the same mistake, and every check box was the light system one.

The sweep of the whole properties panel (then the app):
  - ComboBox x2 (chat Font, alert Display) -> YtComboBox, hand-painted colours gone
  - TextBox x16 in the properties panel -> YtTextBoxCompact (new, BasedOn YtTextBox:
    11px / padding 4,2 - the panel is dense, the full 13px box would double it)
  - CheckBox x2 (chat) + x3 (preview broadcast) + x1 (socials dialog) -> YtCheckBox
    (new: a 14x14 rounded box + tick path, accent fill when checked)
  - the layer-rename field -> YtTextBoxCompact via BasedOn, still borderless
  - buttons, pills, sliders: already themed, untouched

The sweep also killed a typo'd foreground (#e0d0e0 for #e0e0e0) and the only
remaining hand-painted colour is the deliberate dimming of the two read-only path
fields.

Guard: ytLive.Tests/PropertiesStyleTests.cs (the ONE Good Dog test) parses the app
XAML and fails if an unstyled drop-down, check box or properties field comes back.
431/431 green, 0 warnings.
2026-10-21 19:46:25 -07:00

5.7 KiB
Raw Blame History

Controls — index

The phase-2 carved pieces of what used to be one monolithic MainWindow.xaml (1,681 lines → a 123-line shell). Each is a UserControl in the ytLive.Controls namespace, extracted one roll-back commit at a time (refactor-commit-12..18). See schema.md for the memory-map conventions.

File Purpose
BottomBar.xaml(.cs) Footer (Row 3): stream stats (bitrate/fps/dropped/duration/health), resolution dropdown (gear menu moved up to TopBar 2026-09-22)
HealthBanner.xaml(.cs) Row 1 status banner + the 7 value→visibility converters live in the app theme, not here
TopBar.xaml(.cs) Row 0 session surface (2026-09-22 redesign): brand + gear menu (left), one segmented REC
PreviewPane.xaml(.cs) Row 1 Col 1 center: the 1920×1080 OverlayCanvas/SelectionOverlay/BrandFlashLayer/SocialBarElement, text pull-out drawer, and the live-controls row (TRAX / game / mic meters + sliders + speakers + socials). TASK 57: dragging a webcam under the vertical tier routes through MainViewModel.MoveWebcamInVerticalTier (the six-spot snap inside the cropped band) instead of free-floating over the master, and a resize re-snaps the tile onto its spot (TASK 57 Unit 2: the resize routes through MainViewModel.ResizeWebcamInVerticalTier — the Chat camera's two sizes, then the snap)
SceneThumbnailStrip.xaml(.cs) Row 0 scene-picker strip (ItemsControl over Scenes), staged-red / live-green border highlight
LeftPanel.xaml(.cs) Row 1 Col 0 left panel: edit mode → layers+properties; live → YouTube chat. Source add/edit/remove, list drag-to-reorder, snapshot revert-accept. 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
OverlayHost.xaml(.cs) Root-grid overlay dialogs: Settings / Report Bug / Feature Request / About (+ licenses + license-key entry). BackToAbout_Click lives here
SceneThumbnailStrip.xaml.cs Code-behind for the strip above
LeftPanel.xaml.cs Code-behind for the panel above

Window ↔ control contract

The shell (MainWindow.xaml(.cs)) wires up each control and routes the few cross-cutting calls through it:

  • Ctor finds each control by x:Name (TopBar, PreviewPane, LeftPanel) AFTER InitializeComponent, before any method touches it (null-ref guard).
  • _previewPane.IsClickInsidePreview/Drawer + _leftPanel.IsClickInside → deselection guard in Window_PreviewMouseLeftButtonDown.
  • _previewPane.UpdateSelectionOverlay(bool) + _leftPanel.OnSelectionChanged(vm) → selection/edit-mode routing from the VM's SelectedElement change.
  • _topBar.RefreshAvatar() on IsConnected/AccountAvatarUrl change.
  • Handlers in moved controls cast (DataContext as MainViewModel) — controls inherit the window's DataContext; never pass the VM through a property.

Gotchas learned the hard way

  • A UserControl cannot see Window.Resources (StaticResource resolves by element lookup, so it stops at the control boundary). The 7 converters (BoolToVis, InverseBoolToVis, NotNullToVis, NullToVis, HiddenBoolToVis, EnumToBool, AllTrueToVis) were promoted from MainWindow.Resources into Themes/Controls.xaml (see Themes/index.md).
  • Moved XAML can lose its namespace: a block cut from MainWindow carries no root xmlns, so any models:/Helpers: ref in it breaks the build with MC2000: Value cannot be null (key). Declare xmlns:models / xmlns:Helpers on each control's root (LeftPanel hit this).
  • Name-looked-up host stubs must stay in the window, not a control: WebViewHostPanel (ctor InitWebView2(WebViewHostPanel)) and ToastArea (NotificationService.InArea("ToastArea")) are resolved by name from the window root — so OverlayHost deliberately leaves them as thin window-root children (Commit 18). Since the 2026-09-14 composition-capture redesign only ToastArea remains — WebViewHostPanel is deleted (web sources no longer host a multiline XAML control; InitWebView2() runs from MainWindow_Loaded with no panel argument).
  • When cutting visual wrappers, don't drop the outer Border's background/glow/margin — Commit 15 initially lost the preview's outer border and had to restore it same-commit.

Related: ViewModels/index.md (MainViewModel the controls bind to), Themes/index.md (styles/converters), Helpers/index.md (ViewModelBase, converters), the MainWindow.xaml shell at repo root that hosts these.