|
|
|
|
using ReactiveUI;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
|
|
|
|
|
namespace AuroraDesk.Core.Entities;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点实体 - 表示画布上的一个可拖拽组件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class Node : ReactiveObject
|
|
|
|
|
{
|
|
|
|
|
private const double MinDimension = 20;
|
|
|
|
|
private const double MaxDimension = 2000;
|
|
|
|
|
private const double MinConnectorSize = 0;
|
|
|
|
|
private const double MaxConnectorSize = 400;
|
|
|
|
|
|
|
|
|
|
private double _x;
|
|
|
|
|
private double _y;
|
|
|
|
|
private double _width = 120;
|
|
|
|
|
private double _height = 80;
|
|
|
|
|
private string _title = string.Empty;
|
|
|
|
|
private string _content = string.Empty;
|
|
|
|
|
private bool _isSelected;
|
|
|
|
|
private readonly NotifyCollectionChangedEventHandler _connectionPointsChangedHandler;
|
|
|
|
|
private ObservableCollection<ConnectionPoint> _connectionPoints = new();
|
|
|
|
|
private double _leftConnectorSize = 10;
|
|
|
|
|
private double _rightConnectorSize = 10;
|
|
|
|
|
private string _leftConnectorColor = "#3498DB";
|
|
|
|
|
private string _rightConnectorColor = "#FF6B6B";
|
|
|
|
|
private ConnectorPlacementMode _leftConnectorPlacement = ConnectorPlacementMode.Inside;
|
|
|
|
|
private ConnectorPlacementMode _rightConnectorPlacement = ConnectorPlacementMode.Inside;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 构造函数
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Node()
|
|
|
|
|
{
|
|
|
|
|
_connectionPointsChangedHandler = (_, _) => RaiseConnectionPointsChanged();
|
|
|
|
|
_connectionPoints.CollectionChanged += _connectionPointsChangedHandler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点唯一标识符
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Id { get; set; } = Guid.NewGuid().ToString();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// X坐标位置
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double X
|
|
|
|
|
{
|
|
|
|
|
get => _x;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _x, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Y坐标位置
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double Y
|
|
|
|
|
{
|
|
|
|
|
get => _y;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _y, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点宽度
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double Width
|
|
|
|
|
{
|
|
|
|
|
get => _width;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
var clamped = Math.Clamp(value, MinDimension, MaxDimension);
|
|
|
|
|
this.RaiseAndSetIfChanged(ref _width, clamped);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点高度
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double Height
|
|
|
|
|
{
|
|
|
|
|
get => _height;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
var clamped = Math.Clamp(value, MinDimension, MaxDimension);
|
|
|
|
|
this.RaiseAndSetIfChanged(ref _height, clamped);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点标题
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Title
|
|
|
|
|
{
|
|
|
|
|
get => _title;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _title, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点内容(显示在节点内部的文本)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Content
|
|
|
|
|
{
|
|
|
|
|
get => _content;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _content, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否被选中
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool IsSelected
|
|
|
|
|
{
|
|
|
|
|
get => _isSelected;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _isSelected, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 连接点集合
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ObservableCollection<ConnectionPoint> ConnectionPoints
|
|
|
|
|
{
|
|
|
|
|
get => _connectionPoints;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (ReferenceEquals(_connectionPoints, value))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_connectionPoints != null)
|
|
|
|
|
{
|
|
|
|
|
_connectionPoints.CollectionChanged -= _connectionPointsChangedHandler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var newCollection = value ?? new ObservableCollection<ConnectionPoint>();
|
|
|
|
|
newCollection.CollectionChanged += _connectionPointsChangedHandler;
|
|
|
|
|
|
|
|
|
|
this.RaiseAndSetIfChanged(ref _connectionPoints, newCollection);
|
|
|
|
|
RaiseConnectionPointsChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 左侧附件圆尺寸
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double LeftConnectorSize
|
|
|
|
|
{
|
|
|
|
|
get => _leftConnectorSize;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
var clamped = Math.Clamp(value, MinConnectorSize, MaxConnectorSize);
|
|
|
|
|
this.RaiseAndSetIfChanged(ref _leftConnectorSize, clamped);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 右侧附件圆尺寸
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double RightConnectorSize
|
|
|
|
|
{
|
|
|
|
|
get => _rightConnectorSize;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
var clamped = Math.Clamp(value, MinConnectorSize, MaxConnectorSize);
|
|
|
|
|
this.RaiseAndSetIfChanged(ref _rightConnectorSize, clamped);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 左侧附件圆颜色(Hex)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string LeftConnectorColor
|
|
|
|
|
{
|
|
|
|
|
get => _leftConnectorColor;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _leftConnectorColor, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 右侧附件圆颜色(Hex)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string RightConnectorColor
|
|
|
|
|
{
|
|
|
|
|
get => _rightConnectorColor;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _rightConnectorColor, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 左侧附件圆定位方式
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ConnectorPlacementMode LeftConnectorPlacement
|
|
|
|
|
{
|
|
|
|
|
get => _leftConnectorPlacement;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _leftConnectorPlacement, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 右侧附件圆定位方式
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ConnectorPlacementMode RightConnectorPlacement
|
|
|
|
|
{
|
|
|
|
|
get => _rightConnectorPlacement;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _rightConnectorPlacement, value);
|
|
|
|
|
}
|
|
|
|
|
private void RaiseConnectionPointsChanged()
|
|
|
|
|
{
|
|
|
|
|
this.RaisePropertyChanged(nameof(ConnectionPoints));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|