using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows.Media.Imaging; namespace ytLive.Models; public class Scene : INotifyPropertyChanged { public string Id { get; init; } = Guid.NewGuid().ToString(); private string _name = string.Empty; private bool _isHidden; private bool _hasBackground; private bool _hasSocialBar; private bool _isStaged; private bool _isLive; private string? _customBackgroundPath; private bool _useDefaultBackground = true; public bool IsStaged { get => _isStaged; set => Set(ref _isStaged, value); } public bool IsLive { get => _isLive; set => Set(ref _isLive, value); } /// /// User-selected background image file path (FQFN). Null means use the app default. /// Stored as a reference only — the image file is not copied into the DB. /// public string? CustomBackgroundPath { get => _customBackgroundPath; set => Set(ref _customBackgroundPath, value); } /// /// When true, the shipped default background image is used and CustomBackgroundPath /// is ignored (but preserved). Toggled by the pill-switch in the properties panel. /// public bool UseDefaultBackground { get => _useDefaultBackground; set => Set(ref _useDefaultBackground, value); } public string Name { get => _name; set => Set(ref _name, value); } public bool IsHidden { get => _isHidden; set => Set(ref _isHidden, value); } /// /// Whether the scene has a live desktop/game background layer. Enforced by /// policy: only the canonical Live scene ever has one (see SceneCatalog). /// public bool HasBackground { get => _hasBackground; set => Set(ref _hasBackground, value); } /// /// Whether the social bar plays on this scene. Toggled by the footer [+]/[-] /// control — the socials themselves are a global resource (see SocialsConfig). /// public bool HasSocialBar { get => _hasSocialBar; set => Set(ref _hasSocialBar, value); } /// /// The scene's rendered elements in z-order (back to front): multi-instance /// Sources plus this scene's webcam usage (), if any. /// public ObservableCollection Elements { get; } = new(); /// This scene's webcam usage, or null if the creator hasn't added the webcam here. public WebcamSceneConfig? WebcamConfig => Elements.OfType().FirstOrDefault(); public bool IsChatScene { get; init; } private BitmapSource? _snapshot; /// /// Cached thumbnail snapshot of this scene for the control surface strip. /// Updated by the compositor when the scene is not live-previewed. /// public BitmapSource? Snapshot { get => _snapshot; set => Set(ref _snapshot, value); } public event PropertyChangedEventHandler? PropertyChanged; private void Set(ref T field, T value, [CallerMemberName] string? propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return; field = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }