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