using Inspectron.Settings; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using Inspectron.Settings.Attributes; using VisionBuilder.UI.Common; namespace VisionBuilder.UI.IOCommander.Settings { public class IOCommanderCameraSettings:ISettings { public string CameraName { get; } public List ProcessingEvents { get; set; } = [ new (EProcessingEvent.SessionStarted), new (EProcessingEvent.SessionEnded), new (EProcessingEvent.ErrorOccurred), new (EProcessingEvent.GoodOccured), new (EProcessingEvent.ErrorsInSequenceAlarm), ]; [SettingDescription(@" Overrides pin values during test mode. ")] public List TestModeOverride { get; set; } = new List(); public List GPIOCommands { get; set; } = new List(); public IOCommanderCameraSettings(string cameraName) { CameraName = cameraName; } public void RegisterSettings(InspectronSettings settings) { foreach (var processingEvent in ProcessingEvents) { settings.RegisterSimple(processingEvent, () => processingEvent.Actions, CameraName + "/IOCommander/Outputs/"+processingEvent.Event.ToString(), nameof(processingEvent.Actions)); } settings.RegisterSimple(this, () => TestModeOverride, CameraName + "/IOCommander/Outputs/" + nameof(TestModeOverride), nameof(TestModeOverride)); settings.RegisterSimple(this, () => GPIOCommands, CameraName + "/IOCommander/Inputs", nameof(GPIOCommands)); } } public class IOCommanderCommandListConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string stringValue) { // Check if we're converting to a single IOCommanderCommand if (context?.PropertyDescriptor?.PropertyType == typeof(IOCommanderCommand)) { return ConvertFromString(context, culture, stringValue); } // Otherwise, convert to a list of IOCommanderCommand var commands = new List(); if (!string.IsNullOrEmpty(stringValue)) { var lines = stringValue.Split('\n', StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var command = ConvertFromString(context, culture, line.Trim()); if (command != null) commands.Add(command); } } return commands; } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { // Handle single IOCommanderCommand if (value is IOCommanderCommand command) { return ConvertToString(context, culture, command); } // Handle list of IOCommanderCommand if (value is List commands) { var lines = commands.Select(c => ConvertToString(context, culture, c) ).Where(line => !string.IsNullOrEmpty(line)); return string.Join("\n", lines); } } return base.ConvertTo(context, culture, value, destinationType); } /// /// Convert a single string to IOCommanderCommand /// private IOCommanderCommand ConvertFromString(ITypeDescriptorContext context, CultureInfo culture, string stringValue) { if (string.IsNullOrEmpty(stringValue)) return null; var parts = stringValue.Split(','); if (parts.Length == 3) { if (int.TryParse(parts[0], out int pin) && bool.TryParse(parts[1], out bool onHigh) && Enum.TryParse(parts[2], out EGPIOCommand command)) { return new IOCommanderCommand { Pin = pin, OnHigh = onHigh, Command = command }; } } return null; } /// /// Convert a single IOCommanderCommand to string /// private string ConvertToString(ITypeDescriptorContext context, CultureInfo culture, IOCommanderCommand command) { if (command == null) return null; return $"{command.Pin},{command.OnHigh},{command.Command}"; } } }