using CMM.Library.Config; using CMM.Library.Method; using CMM.Library.ViewModel; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace DellMonitorControl; public partial class ConfigWindow : Window { private readonly string _serialNumber; private readonly string _monitorName; private readonly List _availablePorts; private readonly List _portRows = new(); public bool ConfigChanged { get; private set; } public ConfigWindow(string serialNumber, string monitorName, List availablePorts) { InitializeComponent(); _serialNumber = serialNumber; _monitorName = monitorName; _availablePorts = availablePorts; tbHeader.Text = $"Configure: {monitorName}"; LoadPortConfiguration(); } private void LoadPortConfiguration() { var config = MonitorConfigManager.GetMonitorConfig(_serialNumber); spPorts.Children.Clear(); _portRows.Clear(); // Show unsupported message if no ports available if (_availablePorts == null || _availablePorts.Count == 0) { spPorts.Children.Add(new TextBlock { Text = "Unsupported", Foreground = Brushes.Gray, FontSize = 16, FontStyle = FontStyles.Italic, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0, 40, 0, 40) }); return; } foreach (var port in _availablePorts) { var existingPortConfig = config.Ports.FirstOrDefault(p => p.VcpValue == port.Value); var row = new PortConfigRow { VcpValue = port.Value, DefaultName = port.Name, CustomLabel = existingPortConfig?.CustomLabel ?? "", IsHidden = existingPortConfig?.IsHidden ?? false, ShowInQuickSwitch = existingPortConfig?.ShowInQuickSwitch ?? false }; _portRows.Add(row); spPorts.Children.Add(CreatePortRow(row)); } } private UIElement CreatePortRow(PortConfigRow row) { var container = new Border { Background = new SolidColorBrush(Color.FromRgb(60, 60, 60)), CornerRadius = new CornerRadius(4), Padding = new Thickness(10), Margin = new Thickness(0, 0, 0, 8) }; var grid = new Grid(); grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); // Row 1: Port name and Hide checkbox var row1 = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 0, 0, 6) }; row1.Children.Add(new TextBlock { Text = row.DefaultName, Foreground = Brushes.White, FontWeight = FontWeights.SemiBold, FontSize = 13, Width = 120, VerticalAlignment = VerticalAlignment.Center }); var hideCheck = new CheckBox { Content = "Hide", IsChecked = row.IsHidden, Foreground = Brushes.LightGray, VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(10, 0, 0, 0) }; hideCheck.Checked += (s, e) => row.IsHidden = true; hideCheck.Unchecked += (s, e) => row.IsHidden = false; row1.Children.Add(hideCheck); Grid.SetRow(row1, 0); grid.Children.Add(row1); // Row 2: Custom label var row2 = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 0, 0, 6) }; row2.Children.Add(new TextBlock { Text = "Label:", Foreground = Brushes.LightGray, FontSize = 12, Width = 50, VerticalAlignment = VerticalAlignment.Center }); var labelBox = new TextBox { Text = row.CustomLabel, Width = 200, Background = new SolidColorBrush(Color.FromRgb(50, 50, 50)), Foreground = Brushes.White, BorderBrush = new SolidColorBrush(Color.FromRgb(80, 80, 80)), Padding = new Thickness(6, 4, 6, 4) }; labelBox.TextChanged += (s, e) => row.CustomLabel = labelBox.Text; row2.Children.Add(labelBox); Grid.SetRow(row2, 1); grid.Children.Add(row2); // Row 3: Quick switch checkbox var quickSwitchCheck = new CheckBox { Content = "Show in quick-switch toolbar", IsChecked = row.ShowInQuickSwitch, Foreground = Brushes.LightGray, FontSize = 12 }; quickSwitchCheck.Checked += (s, e) => row.ShowInQuickSwitch = true; quickSwitchCheck.Unchecked += (s, e) => row.ShowInQuickSwitch = false; Grid.SetRow(quickSwitchCheck, 2); grid.Children.Add(quickSwitchCheck); container.Child = grid; return container; } private void SaveButton_Click(object sender, RoutedEventArgs e) { var config = new MonitorConfig { SerialNumber = _serialNumber, MonitorName = _monitorName, Ports = _portRows.Select(r => new PortConfig { VcpValue = r.VcpValue, DefaultName = r.DefaultName, CustomLabel = r.CustomLabel, IsHidden = r.IsHidden, ShowInQuickSwitch = r.ShowInQuickSwitch }).ToList() }; MonitorConfigManager.SaveMonitorConfig(config); ConfigChanged = true; Close(); } private void CancelButton_Click(object sender, RoutedEventArgs e) { Close(); } private void ResetButton_Click(object sender, RoutedEventArgs e) { // Reset all port rows to default values foreach (var row in _portRows) { row.CustomLabel = ""; row.IsHidden = false; row.ShowInQuickSwitch = false; } // Reload the UI to reflect changes LoadPortConfiguration(); // Clear any discovered ports from config var config = MonitorConfigManager.GetMonitorConfig(_serialNumber); config.Ports.Clear(); MonitorConfigManager.SaveMonitorConfig(config); MonitorConfigManager.ClearCache(); } private async void DetectButton_Click(object sender, RoutedEventArgs e) { btnDetect.IsEnabled = false; btnDetect.Content = "..."; try { // Common VCP 60 values: 15=DP1, 16=DP2, 17=HDMI1, 18=HDMI2, 3=DVI1, 4=DVI2, 1=VGA1, 2=VGA2 var commonPorts = new[] { 15, 16, 17, 18, 3, 4, 1, 2 }; var detectedPorts = new List(); // Get current input so we can restore it var currentInput = await CMMCommand.GetInputSource(_serialNumber); foreach (var vcpValue in commonPorts) { // Skip ports we already know about if (_availablePorts.Any(p => p.Value == vcpValue)) continue; try { // Try to set the input - if it succeeds, the port exists await CMMCommand.SetInputSource(_serialNumber, vcpValue); await Task.Delay(500); // Give monitor time to respond // Check if the input actually changed var newInput = await CMMCommand.GetInputSource(_serialNumber); if (newInput == vcpValue) { detectedPorts.Add(vcpValue); } } catch { // Port doesn't exist or isn't supported } } // Restore original input if we have one if (currentInput.HasValue) { await CMMCommand.SetInputSource(_serialNumber, currentInput.Value); } if (detectedPorts.Count > 0) { // Add detected ports to the available list and config foreach (var vcpValue in detectedPorts) { var name = CMMCommand.GetInputSourceName(vcpValue); _availablePorts.Add(new InputSourceOption(vcpValue, name)); MonitorConfigManager.AddDiscoveredPort(_serialNumber, _monitorName, vcpValue, name); } // Reload to show new ports MonitorConfigManager.ClearCache(); LoadPortConfiguration(); MessageBox.Show($"Detected {detectedPorts.Count} new port(s):\n" + string.Join("\n", detectedPorts.Select(v => $" • {CMMCommand.GetInputSourceName(v)}")), "Detection Complete", MessageBoxButton.OK, MessageBoxImage.Information); } else { MessageBox.Show("No additional ports were detected.", "Detection Complete", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { MessageBox.Show($"Detection failed: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { btnDetect.Content = "Detect"; btnDetect.IsEnabled = true; } } private class PortConfigRow { public int VcpValue { get; set; } public string DefaultName { get; set; } = ""; public string CustomLabel { get; set; } = ""; public bool IsHidden { get; set; } public bool ShowInQuickSwitch { get; set; } } }