You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

384 lines
12 KiB

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;
/// <summary>
/// 节点画布相关转换器
/// </summary>
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 ColorHexToColorConverter = new ColorHexToColorConverter();
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();
}
/// <summary>
/// 布尔值到边框颜色转换器(选中时显示蓝色边框)
/// </summary>
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();
}
}
/// <summary>
/// 布尔值到边框厚度转换器(选中时显示边框)
/// </summary>
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();
}
}
/// <summary>
/// 过滤输入连接点转换器
/// </summary>
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();
}
}
/// <summary>
/// 非空转换器(用于控制可见性)
/// </summary>
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();
}
}
/// <summary>
/// 空值转换器(用于控制可见性)
/// </summary>
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();
}
}
/// <summary>
/// 将附件圆模式枚举转换为中文描述
/// </summary>
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();
}
}
/// <summary>
/// 过滤节点输入连接点集合
/// </summary>
public class ConnectionPointsToInputsConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is IEnumerable<ConnectionPoint> points)
{
return points
.Where(p => p.Type == ConnectionPointType.Input)
.OrderBy(p => p.Index)
.ToList();
}
return Array.Empty<ConnectionPoint>();
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 过滤节点输出连接点集合
/// </summary>
public class ConnectionPointsToOutputsConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is IEnumerable<ConnectionPoint> points)
{
return points
.Where(p => p.Type == ConnectionPointType.Output)
.OrderBy(p => p.Index)
.ToList();
}
return Array.Empty<ConnectionPoint>();
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 将附件圆定位模式转换为显示文本
/// </summary>
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();
}
}
/// <summary>
/// 根据附件圆定位和尺寸计算 ItemsControl 外边距
/// </summary>
public class ConnectorPlacementMarginConverter : IMultiValueConverter
{
public object? Convert(IList<object?> 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;
// Outside 模式:圆在组件边界外侧
// Inside 模式:圆在组件边界内侧
if (placement == ConnectorPlacementMode.Outside)
{
return side switch
{
"Left" => new Thickness(-size, 0, 0, 0), // 左侧外侧:向左移动 size
"Right" => new Thickness(0, 0, -size, 0), // 右侧外侧:使用负右边距
_ => new Thickness(0)
};
}
else
{
// Inside 模式:不添加额外边距
return new Thickness(0);
}
}
return new Thickness(0);
}
public object? ConvertBack(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// Double 与字符串互转转换器
/// </summary>
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;
}
}
/// <summary>
/// 将 Hex 字符串转换为 SolidColorBrush
/// </summary>
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();
}
}
/// <summary>
/// 将 Hex 字符串与 Avalonia.Media.Color 互转
/// </summary>
public class ColorHexToColorConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string hex && !string.IsNullOrWhiteSpace(hex))
{
try
{
return Color.Parse(hex);
}
catch
{
// ignore parse error
}
}
return Colors.Transparent;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Color color)
{
return $"#{color.R:X2}{color.G:X2}{color.B:X2}";
}
return AvaloniaProperty.UnsetValue;
}
}
/// <summary>
/// 将零基索引转换为显示文本(圆 1、圆 2 ...)
/// </summary>
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();
}
}