using Avalonia.Data.Converters; using Avalonia.Media; using Avalonia; using AuroraDesk.Core.Entities; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; namespace AuroraDesk.Presentation.Converters; /// /// 节点画布相关转换器 /// public static class NodeCanvasConverters { public static readonly IValueConverter BooleanToBorderBrushConverter = new BooleanToBorderBrushConverter(); public static readonly IValueConverter BooleanToBorderThicknessConverter = new BooleanToBorderThicknessConverter(); public static readonly IValueConverter NodeToSelectionTextConverter = new NodeToSelectionTextConverter(); public static readonly IValueConverter IsNotNullConverter = new IsNotNullConverter(); public static readonly IValueConverter IsNullConverter = new IsNullConverter(); public static readonly IValueConverter DoubleToStringConverter = new DoubleToStringConverter(); public static readonly IValueConverter ColorHexToBrushConverter = new ColorHexToBrushConverter(); public static readonly IValueConverter ConnectorAttachmentModeToTextConverter = new ConnectorAttachmentModeToTextConverter(); public static readonly IValueConverter ConnectionPointsToInputsConverter = new ConnectionPointsToInputsConverter(); public static readonly IValueConverter ConnectionPointsToOutputsConverter = new ConnectionPointsToOutputsConverter(); public static readonly IValueConverter ConnectorPlacementToTextConverter = new ConnectorPlacementToTextConverter(); public static readonly IMultiValueConverter ConnectorPlacementMarginConverter = new ConnectorPlacementMarginConverter(); public static readonly IValueConverter IndexToDisplayTextConverter = new IndexToDisplayTextConverter(); } /// /// 布尔值到边框颜色转换器(选中时显示蓝色边框) /// public class BooleanToBorderBrushConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is bool isSelected && isSelected) { // 使用 StaticResource 的颜色,如果无法获取则使用默认蓝色 try { var color = Color.Parse("#3498DB"); // PrimaryBlue return new SolidColorBrush(color); } catch { return new SolidColorBrush(Color.FromRgb(52, 152, 219)); // #3498DB } } return new SolidColorBrush(Colors.Transparent); } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 布尔值到边框厚度转换器(选中时显示边框) /// public class BooleanToBorderThicknessConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is bool isSelected && isSelected) { return new Thickness(2); } return new Thickness(0); } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 过滤输入连接点转换器 /// public class NodeToSelectionTextConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Node node) { return $"已选中1个对象 (节点)"; } return "未选中对象"; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 非空转换器(用于控制可见性) /// public class IsNotNullConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { return value != null; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 空值转换器(用于控制可见性) /// public class IsNullConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { return value == null; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 将附件圆模式枚举转换为中文描述 /// public class ConnectorAttachmentModeToTextConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is ConnectorAttachmentMode mode) { return mode switch { ConnectorAttachmentMode.None => "不显示", ConnectorAttachmentMode.LeftOnly => "仅左侧", ConnectorAttachmentMode.RightOnly => "仅右侧", ConnectorAttachmentMode.Both => "左右两侧", _ => mode.ToString() }; } return string.Empty; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 过滤节点输入连接点集合 /// public class ConnectionPointsToInputsConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is IEnumerable points) { return points .Where(p => p.Type == ConnectionPointType.Input) .OrderBy(p => p.Index) .ToList(); } return Array.Empty(); } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 过滤节点输出连接点集合 /// public class ConnectionPointsToOutputsConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is IEnumerable points) { return points .Where(p => p.Type == ConnectionPointType.Output) .OrderBy(p => p.Index) .ToList(); } return Array.Empty(); } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 将附件圆定位模式转换为显示文本 /// public class ConnectorPlacementToTextConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is ConnectorPlacementMode placement) { return placement switch { ConnectorPlacementMode.Inside => "内侧", ConnectorPlacementMode.Outside => "外侧", _ => placement.ToString() }; } return string.Empty; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 根据附件圆定位和尺寸计算 ItemsControl 外边距 /// public class ConnectorPlacementMarginConverter : IMultiValueConverter { public object? Convert(IList values, Type targetType, object? parameter, CultureInfo culture) { if (values.Count < 2) { return new Thickness(0); } if (values[0] is ConnectorPlacementMode placement && values[1] is double size) { var side = parameter?.ToString() ?? string.Empty; var offset = placement == ConnectorPlacementMode.Outside ? size / 2 : 0; return side switch { "Left" => new Thickness(-offset, 0, 0, 0), "Right" => new Thickness(0, 0, -offset, 0), _ => new Thickness(0) }; } return new Thickness(0); } public object? ConvertBack(IList values, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Double 与字符串互转转换器 /// public class DoubleToStringConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is double d) { return d.ToString("0.##", culture); } return string.Empty; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is string s && double.TryParse(s, NumberStyles.Float, culture, out var result)) { return result; } return AvaloniaProperty.UnsetValue; } } /// /// 将 Hex 字符串转换为 SolidColorBrush /// public class ColorHexToBrushConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is string hex && !string.IsNullOrWhiteSpace(hex)) { try { var color = Color.Parse(hex); return new SolidColorBrush(color); } catch { // ignore parse error } } return new SolidColorBrush(Colors.Transparent); } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// 将零基索引转换为显示文本(圆 1、圆 2 ...) /// public class IndexToDisplayTextConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is int index) { return $"圆 {index + 1}"; } return string.Empty; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } }