Control Surface UX: pill toggle, background rename, per-scene properties
- Sliding pill toggle (green ON / red OFF) replaces checkbox - Geometry mismatch error for custom backgrounds - Backdrop -> Background: C# rename, SQL column rename with migration - Source.IsBackground: new -> override (fixes WPF binding) - Legacy 'Backdrop' display name migrated to 'Background' - Per-scene UseDefaultBackground + CustomBackgroundPath - Asset files renamed backdrop -> background - StagedScene/LiveScene split, thumbnail strip, edit gating - TransitionService (Cut/Fade/Move) - Context menu: Capture Desktop, Refresh Desktop - Resolution badge removed, ON-AIR status light added
This commit is contained in:
+25
-27
@@ -26,8 +26,6 @@ public partial class MainWindow : Window
|
||||
_viewModel = (MainViewModel)DataContext;
|
||||
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
|
||||
_viewModel.ChatMessages.CollectionChanged += OnChatMessagesChanged;
|
||||
// When a focused scene is deleted, never land focus on a hidden scene.
|
||||
SceneList.IsSelectable = item => item is Scene { IsHidden: false };
|
||||
UpdateTaskbarOverlay();
|
||||
UpdateSelectionOverlay();
|
||||
LoadAvatarImage();
|
||||
@@ -39,6 +37,12 @@ public partial class MainWindow : Window
|
||||
AppLog.Write("MainWindow loaded");
|
||||
}
|
||||
|
||||
private void Window_ContextMenuOpening(object sender, ContextMenuEventArgs e)
|
||||
{
|
||||
if (!_viewModel.IsEditMode)
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(MainViewModel.IsLive))
|
||||
@@ -57,7 +61,7 @@ public partial class MainWindow : Window
|
||||
|
||||
private void MainWindow_Activated(object? sender, EventArgs e)
|
||||
{
|
||||
_viewModel.RefreshBackdropAutoCapture();
|
||||
_viewModel.RefreshBackgroundAutoCapture();
|
||||
}
|
||||
|
||||
private void MainWindow_Deactivated(object? sender, EventArgs e)
|
||||
@@ -102,15 +106,6 @@ public partial class MainWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private void SceneList_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count > 0 && e.AddedItems[0] is Scene { IsHidden: true } hidden)
|
||||
{
|
||||
var list = (ListBox)sender;
|
||||
list.SelectedItem = _viewModel.ActiveScene;
|
||||
}
|
||||
}
|
||||
|
||||
private void VolumeSlider_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is Slider slider)
|
||||
@@ -234,17 +229,13 @@ public partial class MainWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private void AddSceneButton_Click(object sender, RoutedEventArgs e)
|
||||
// ─── Preview image selection / move / resize ───
|
||||
private void Thumbnail_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is Button { ContextMenu: { } menu } button)
|
||||
{
|
||||
menu.PlacementTarget = button;
|
||||
menu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
|
||||
menu.IsOpen = true;
|
||||
}
|
||||
if (sender is Border { DataContext: Scene scene })
|
||||
_viewModel.TransitionToScene(scene);
|
||||
}
|
||||
|
||||
// ─── Preview image selection / move / resize ───
|
||||
private bool _isDraggingOverlay;
|
||||
private bool _isResizing;
|
||||
private Point _grabOffset;
|
||||
@@ -268,6 +259,11 @@ public partial class MainWindow : Window
|
||||
|
||||
private void UpdateSelectionOverlay()
|
||||
{
|
||||
if (!_viewModel.IsEditMode)
|
||||
{
|
||||
SelectionOverlay.Visibility = Visibility.Collapsed;
|
||||
return;
|
||||
}
|
||||
var selected = _viewModel.SelectedElement is { } s && IsDraggableElement(s);
|
||||
SelectionOverlay.Visibility = selected ? Visibility.Visible : Visibility.Collapsed;
|
||||
if (selected)
|
||||
@@ -441,14 +437,14 @@ public partial class MainWindow : Window
|
||||
_viewModel.RemoveSourceCommand.Execute(element);
|
||||
}
|
||||
|
||||
private void BackdropMenu_ChangeCapture(object sender, RoutedEventArgs e)
|
||||
private void BackgroundMenu_ChangeCapture(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_ = _viewModel.ChangeBackdropCaptureAsync();
|
||||
_ = _viewModel.ChangeBackgroundCaptureAsync();
|
||||
}
|
||||
|
||||
private void BackdropMenu_RefreshCapture(object sender, RoutedEventArgs e)
|
||||
private void BackgroundMenu_RefreshCapture(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_viewModel.RefreshBackdropAutoCapture();
|
||||
_viewModel.RefreshBackgroundAutoCapture();
|
||||
}
|
||||
|
||||
private void SourceMenu_Remove(object sender, RoutedEventArgs e)
|
||||
@@ -471,6 +467,7 @@ public partial class MainWindow : Window
|
||||
|
||||
private void Preview_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (!_viewModel.IsEditMode) return;
|
||||
var grid = (Grid)sender;
|
||||
var toCanvas = CanvasGrid.TransformToVisual(grid).Inverse;
|
||||
var p = toCanvas.Transform(e.GetPosition(grid));
|
||||
@@ -501,6 +498,7 @@ public partial class MainWindow : Window
|
||||
|
||||
private void Preview_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!_viewModel.IsEditMode) return;
|
||||
if (!_isDraggingOverlay && !_isResizing) return;
|
||||
|
||||
var grid = (Grid)sender;
|
||||
@@ -527,8 +525,8 @@ public partial class MainWindow : Window
|
||||
var isWebcam = selected is WebcamSceneConfig;
|
||||
var isRound = selected.ClipShape == ClipShape.Round;
|
||||
var proportional = isRound || Keyboard.Modifiers.HasFlag(ModifierKeys.Shift);
|
||||
var maxW = isWebcam ? MainViewModel.MaxWebcamWidthFor(_viewModel.ActiveScene?.Name) : 1920;
|
||||
var maxH = isWebcam ? MainViewModel.MaxWebcamHeightFor(_viewModel.ActiveScene?.Name) : 1080;
|
||||
var maxW = isWebcam ? MainViewModel.MaxWebcamWidthFor(_viewModel.StagedScene?.Name) : 1920;
|
||||
var maxH = isWebcam ? MainViewModel.MaxWebcamHeightFor(_viewModel.StagedScene?.Name) : 1080;
|
||||
var newW = Math.Clamp(p.X - selected.X, 32, maxW);
|
||||
var newH = proportional ? newW / _resizeAspect : Math.Clamp(p.Y - selected.Y, 32, maxH);
|
||||
if (proportional && newH > maxH)
|
||||
@@ -560,7 +558,7 @@ public partial class MainWindow : Window
|
||||
|
||||
private SceneElement? HitElement(Point p)
|
||||
{
|
||||
var scene = _viewModel.ActiveScene;
|
||||
var scene = _viewModel.StagedScene;
|
||||
if (scene == null) return null;
|
||||
for (var i = scene.Elements.Count - 1; i >= 0; i--)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user