// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable enable using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using Microsoft.PowerToys.Settings.UI.Library; using PowerDisplay.Common.Models; namespace Microsoft.PowerToys.Settings.UI.ViewModels { /// /// ViewModel for Profile Editor Dialog /// public class ProfileEditorViewModel : INotifyPropertyChanged { private string _profileName = string.Empty; private ObservableCollection _monitors; public ProfileEditorViewModel(ObservableCollection availableMonitors, string defaultName = "") { _profileName = defaultName; _monitors = new ObservableCollection(); // Set TotalMonitorCount for DisplayName to show monitor numbers when multiple monitors exist int totalCount = availableMonitors.Count; foreach (var monitor in availableMonitors) { monitor.TotalMonitorCount = totalCount; } // Initialize monitor selection items foreach (var monitor in availableMonitors) { var item = new MonitorSelectionItem { SuppressAutoSelection = true, Monitor = monitor, IsSelected = false, Brightness = monitor.CurrentBrightness, Contrast = 50, // Default value (MonitorInfo doesn't store contrast) Volume = 50, // Default value (MonitorInfo doesn't store volume) ColorTemperature = monitor.ColorTemperatureVcp, }; item.SuppressAutoSelection = false; // Subscribe to selection and checkbox changes item.PropertyChanged += OnMonitorItemPropertyChanged; _monitors.Add(item); } } public string ProfileName { get => _profileName; set { if (_profileName != value) { _profileName = value; OnPropertyChanged(); OnPropertyChanged(nameof(CanSave)); } } } public ObservableCollection Monitors { get => _monitors; set { if (_monitors != value) { _monitors = value; OnPropertyChanged(); } } } public bool HasSelectedMonitors => _monitors?.Any(m => m.IsSelected) ?? false; public bool HasValidSettings => _monitors != null && _monitors.Any(m => m.IsSelected) && _monitors.Where(m => m.IsSelected).All(m => m.IncludeBrightness || m.IncludeContrast || m.IncludeVolume || m.IncludeColorTemperature); public bool CanSave => !string.IsNullOrWhiteSpace(_profileName) && HasSelectedMonitors && HasValidSettings; public PowerDisplayProfile CreateProfile() { var settings = _monitors .Where(m => m.IsSelected) .Select(m => new ProfileMonitorSetting( m.Monitor.Id, // Monitor Id (unique identifier) m.IncludeBrightness ? (int?)m.Brightness : null, m.IncludeColorTemperature && m.SupportsColorTemperature ? (int?)m.ColorTemperature : null, m.IncludeContrast && m.SupportsContrast ? (int?)m.Contrast : null, m.IncludeVolume && m.SupportsVolume ? (int?)m.Volume : null)) .ToList(); return new PowerDisplayProfile(_profileName, settings); } public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } /// /// Handle property changes from monitor selection items. /// Centralizes validation state updates to avoid duplication. /// private void OnMonitorItemPropertyChanged(object? sender, PropertyChangedEventArgs e) { // Update selection-dependent properties if (e.PropertyName == nameof(MonitorSelectionItem.IsSelected)) { OnPropertyChanged(nameof(HasSelectedMonitors)); } // Update validation state for relevant property changes if (e.PropertyName == nameof(MonitorSelectionItem.IsSelected) || e.PropertyName == nameof(MonitorSelectionItem.IncludeBrightness) || e.PropertyName == nameof(MonitorSelectionItem.IncludeContrast) || e.PropertyName == nameof(MonitorSelectionItem.IncludeVolume) || e.PropertyName == nameof(MonitorSelectionItem.IncludeColorTemperature)) { OnPropertyChanged(nameof(CanSave)); OnPropertyChanged(nameof(HasValidSettings)); } } } }