2021-07-23 09:42:22 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2023-01-15 11:59:51 +08:00
|
|
|
|
using System.Collections.ObjectModel;
|
2021-07-23 09:42:22 +08:00
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
|
using System.Linq;
|
2023-01-15 11:59:51 +08:00
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Input;
|
2021-07-23 09:42:22 +08:00
|
|
|
|
using System.Windows.Media;
|
2023-01-23 22:05:51 +08:00
|
|
|
|
using AIStudio.Wpf.DiagramDesigner.Controls;
|
2023-01-12 23:02:53 +08:00
|
|
|
|
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
2022-10-28 22:45:39 +08:00
|
|
|
|
using AIStudio.Wpf.DiagramDesigner.Helpers;
|
2023-01-22 21:46:59 +08:00
|
|
|
|
using SvgPathProperties;
|
2021-07-23 09:42:22 +08:00
|
|
|
|
|
2022-10-28 22:45:39 +08:00
|
|
|
|
namespace AIStudio.Wpf.DiagramDesigner
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
2023-02-12 21:30:16 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// DefaultLink
|
|
|
|
|
|
/// </summary>
|
2023-01-24 17:53:04 +08:00
|
|
|
|
public class ConnectionViewModel : SelectableDesignerItemViewModelBase
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
2023-01-27 14:54:03 +08:00
|
|
|
|
public ConnectionViewModel(FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode drawMode = DrawMode.ConnectingLineSmooth, RouterMode routerMode = AIStudio.Wpf.DiagramDesigner.RouterMode.RouterNormal) : this(null, sourceConnectorInfo, sinkConnectorInfo, drawMode, routerMode)
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
2023-01-27 14:54:03 +08:00
|
|
|
|
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-27 14:54:03 +08:00
|
|
|
|
public ConnectionViewModel(IDiagramViewModel root, FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode drawMode = DrawMode.ConnectingLineSmooth, RouterMode routerMode = AIStudio.Wpf.DiagramDesigner.RouterMode.RouterNormal) : base(root)
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
2023-01-27 14:54:03 +08:00
|
|
|
|
PathMode = drawMode.ToString();
|
|
|
|
|
|
RouterMode = routerMode.ToString();
|
2023-03-24 22:32:42 +08:00
|
|
|
|
Init(root, sourceConnectorInfo, sinkConnectorInfo);
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-25 23:55:30 +08:00
|
|
|
|
public ConnectionViewModel(IDiagramViewModel root, FullyCreatedConnectorInfo sourceConnectorInfo, FullyCreatedConnectorInfo sinkConnectorInfo, ConnectionItem designer) : base(root, designer)
|
2022-12-08 20:54:45 +08:00
|
|
|
|
{
|
2023-01-25 23:55:30 +08:00
|
|
|
|
PathMode = designer.PathMode;
|
|
|
|
|
|
RouterMode = designer.RouterMode;
|
2023-03-24 22:32:42 +08:00
|
|
|
|
Init(root, sourceConnectorInfo, sinkConnectorInfo);
|
2022-12-08 20:54:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-25 11:11:27 +08:00
|
|
|
|
public override SelectableItemBase GetSerializableObject()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsFullConnection)
|
|
|
|
|
|
{
|
|
|
|
|
|
ConnectionItem connection = new ConnectionItem(this);
|
|
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-24 22:32:42 +08:00
|
|
|
|
protected virtual void Init(IDiagramViewModel root, FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo)
|
2023-01-12 23:02:53 +08:00
|
|
|
|
{
|
2023-03-24 22:32:42 +08:00
|
|
|
|
this.Root = root?? sourceConnectorInfo.Root;
|
2023-02-04 11:16:39 +08:00
|
|
|
|
|
2023-01-16 22:38:58 +08:00
|
|
|
|
if (sinkConnectorInfo is FullyCreatedConnectorInfo sink && sink.DataItem.ShowArrow == false)
|
|
|
|
|
|
{
|
2023-02-19 21:38:28 +08:00
|
|
|
|
this.ShapeViewModel.SinkMarker = new LinkMarker("", 10, 10, ArrowPathStyle.None, ArrowSizeStyle.Middle);
|
2023-01-16 22:38:58 +08:00
|
|
|
|
}
|
2023-01-26 18:27:17 +08:00
|
|
|
|
this.ColorViewModel.PropertyChanged += ConnectorViewModel_PropertyChanged;
|
|
|
|
|
|
this.ShapeViewModel.PropertyChanged += ConnectorViewModel_PropertyChanged;
|
2023-01-21 22:01:10 +08:00
|
|
|
|
this.PropertyChanged += ConnectorViewModel_PropertyChanged;
|
2023-01-12 23:02:53 +08:00
|
|
|
|
|
2023-03-25 22:10:49 +08:00
|
|
|
|
var routetype = TypeHelper.GetType(RouterMode);
|
2023-01-14 21:52:05 +08:00
|
|
|
|
Router = routetype != null ? (System.Activator.CreateInstance(routetype) as IRouter) : new RouterNormal();
|
2023-01-12 23:02:53 +08:00
|
|
|
|
|
2023-03-25 22:10:49 +08:00
|
|
|
|
var pathGeneratortype = TypeHelper.GetType(PathMode);
|
2023-01-14 21:52:05 +08:00
|
|
|
|
PathGenerator = pathGeneratortype != null ? (System.Activator.CreateInstance(pathGeneratortype) as IPathGenerator) : new ConnectingLineSmooth();
|
2023-01-12 23:02:53 +08:00
|
|
|
|
|
|
|
|
|
|
this.SourceConnectorInfo = sourceConnectorInfo;
|
|
|
|
|
|
this.SinkConnectorInfo = sinkConnectorInfo;
|
2023-01-25 23:55:30 +08:00
|
|
|
|
DeleteConnectionCommand = new SimpleCommand(Command_Enable, DeleteConnection);
|
|
|
|
|
|
AddVertexCommand = new SimpleCommand(Command_Enable, AddVertex);
|
2023-01-26 18:27:17 +08:00
|
|
|
|
AddLabelCommand = new SimpleCommand(Command_Enable, para => AddLabel());
|
2023-01-20 22:43:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-25 11:59:31 +08:00
|
|
|
|
protected override void InitNew()
|
|
|
|
|
|
{
|
|
|
|
|
|
base.InitNew();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-27 14:54:03 +08:00
|
|
|
|
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
|
2023-01-20 22:43:08 +08:00
|
|
|
|
{
|
2023-01-27 14:54:03 +08:00
|
|
|
|
base.LoadDesignerItemViewModel(designerbase);
|
2023-01-21 23:25:42 +08:00
|
|
|
|
|
2023-01-24 17:53:04 +08:00
|
|
|
|
if (designerbase is ConnectionItem designer)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vertices = new ObservableCollection<ConnectorVertexModel>(designer.Vertices.Select(p => new ConnectorVertexModel(this.Root, this, designer)));
|
|
|
|
|
|
Labels = new ObservableCollection<ConnectorLabelModel>(designer.Labels.Select(p => new ConnectorLabelModel(this.Root, this, designer)));
|
|
|
|
|
|
}
|
2023-01-25 23:55:30 +08:00
|
|
|
|
}
|
2021-07-23 09:42:22 +08:00
|
|
|
|
|
2023-01-21 22:01:10 +08:00
|
|
|
|
#region 属性
|
2023-01-24 16:20:39 +08:00
|
|
|
|
private string _text;
|
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
|
[CanDo]
|
|
|
|
|
|
public override string Text
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
var text = _text;
|
|
|
|
|
|
if (Labels?.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
text = Labels[0].Text;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (FontViewModel.FontCase == FontCase.Upper)
|
|
|
|
|
|
{
|
|
|
|
|
|
return text?.ToUpper();
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (FontViewModel.FontCase == FontCase.Lower)
|
|
|
|
|
|
{
|
|
|
|
|
|
return text?.ToLower();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return text;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SetProperty(ref _text, value))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!string.IsNullOrEmpty(_text))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Labels?.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Labels[0].Text = _text;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
AddLabel(_text);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-03-13 19:44:30 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2023-04-08 21:48:43 +08:00
|
|
|
|
ClearLabel();
|
2023-03-13 19:44:30 +08:00
|
|
|
|
}
|
2023-01-24 16:20:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 09:22:37 +08:00
|
|
|
|
private PointBase _sourceA;
|
|
|
|
|
|
public PointBase SourceA
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _sourceA;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
2023-01-21 22:01:10 +08:00
|
|
|
|
SetProperty(ref _sourceA, value);
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 09:22:37 +08:00
|
|
|
|
private PointBase _sourceB;
|
|
|
|
|
|
public PointBase SourceB
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _sourceB;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
2023-01-22 21:46:59 +08:00
|
|
|
|
SetProperty(ref _sourceB, value);
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 09:22:37 +08:00
|
|
|
|
private PointBase _startPoint;
|
|
|
|
|
|
public PointBase StartPoint
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _startPoint;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _startPoint, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 09:22:37 +08:00
|
|
|
|
private PointBase _endPoint;
|
|
|
|
|
|
public PointBase EndPoint
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _endPoint;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _endPoint, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-15 11:59:51 +08:00
|
|
|
|
private double _startAngle;
|
|
|
|
|
|
public double StartAngle
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _startAngle;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _startAngle, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private double _endAngle;
|
|
|
|
|
|
public double EndAngle
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _endAngle;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _endAngle, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-02-04 12:17:03 +08:00
|
|
|
|
private RectangleBase _startRectangle;
|
|
|
|
|
|
public RectangleBase StartRectangle
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _startRectangle;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _startRectangle, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private RectangleBase _endRectangle;
|
|
|
|
|
|
public RectangleBase EndRectangle
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _endRectangle;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _endRectangle, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 09:22:37 +08:00
|
|
|
|
private RectangleBase _area;
|
|
|
|
|
|
public RectangleBase Area
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _area;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
2023-01-22 21:46:59 +08:00
|
|
|
|
SetProperty(ref _area, value);
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-05 23:22:34 +08:00
|
|
|
|
private string _pathMode;
|
2023-01-12 23:02:53 +08:00
|
|
|
|
public string PathMode
|
|
|
|
|
|
{
|
2023-03-05 23:22:34 +08:00
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _pathMode;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _pathMode, value);
|
|
|
|
|
|
}
|
2023-01-12 23:02:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-05 23:22:34 +08:00
|
|
|
|
private string _routerMode;
|
2023-01-12 23:02:53 +08:00
|
|
|
|
public string RouterMode
|
|
|
|
|
|
{
|
2023-03-05 23:22:34 +08:00
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _routerMode;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _routerMode, value);
|
|
|
|
|
|
}
|
2023-01-12 23:02:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public IRouter Router
|
2022-11-30 22:28:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
get; set;
|
|
|
|
|
|
}
|
2021-08-06 18:12:05 +08:00
|
|
|
|
|
2023-01-12 23:02:53 +08:00
|
|
|
|
public IPathGenerator PathGenerator
|
|
|
|
|
|
{
|
|
|
|
|
|
get; set;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private PathGeneratorResult _pathGeneratorResult;
|
|
|
|
|
|
public PathGeneratorResult PathGeneratorResult
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _pathGeneratorResult;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _pathGeneratorResult, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-15 11:59:51 +08:00
|
|
|
|
private bool _shouldInsertAnchor;
|
|
|
|
|
|
public bool ShouldInsertAnchor
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _shouldInsertAnchor;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _shouldInsertAnchor, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 09:22:37 +08:00
|
|
|
|
//待完善这两处
|
2023-01-22 22:10:39 +08:00
|
|
|
|
private ObservableCollection<ConnectorVertexModel> _vertices = new ObservableCollection<ConnectorVertexModel>();
|
|
|
|
|
|
public ObservableCollection<ConnectorVertexModel> Vertices
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _vertices;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _vertices, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-22 22:10:39 +08:00
|
|
|
|
private ObservableCollection<ConnectorLabelModel> _labels = new ObservableCollection<ConnectorLabelModel>();
|
|
|
|
|
|
public ObservableCollection<ConnectorLabelModel> Labels
|
2023-01-22 21:46:59 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _labels;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _labels, value);
|
|
|
|
|
|
}
|
2023-01-23 22:05:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-06 21:28:42 +08:00
|
|
|
|
public virtual Dictionary<string, string> PropertiesSetting
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Dictionary<string, string>()
|
|
|
|
|
|
{
|
|
|
|
|
|
{ "Text","文本" },
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-23 09:42:22 +08:00
|
|
|
|
private FullyCreatedConnectorInfo _sourceConnectorInfo;
|
|
|
|
|
|
public FullyCreatedConnectorInfo SourceConnectorInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _sourceConnectorInfo;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
2023-01-21 22:01:10 +08:00
|
|
|
|
SetProperty(ref _sourceConnectorInfo, value);
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private ConnectorInfoBase _sinkConnectorInfo;
|
|
|
|
|
|
public ConnectorInfoBase SinkConnectorInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _sinkConnectorInfo;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
2023-01-21 22:01:10 +08:00
|
|
|
|
SetProperty(ref _sinkConnectorInfo, value);
|
2023-01-22 21:46:59 +08:00
|
|
|
|
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 09:22:37 +08:00
|
|
|
|
public FullyCreatedConnectorInfo SinkConnectorInfoFully
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return SinkConnectorInfo as FullyCreatedConnectorInfo;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-24 17:53:04 +08:00
|
|
|
|
public PartCreatedConnectorInfo SinkConnectorInfoPart
|
2023-01-08 09:22:37 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
2023-01-24 17:53:04 +08:00
|
|
|
|
return SinkConnectorInfo as PartCreatedConnectorInfo;
|
2023-01-08 09:22:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-12 23:02:53 +08:00
|
|
|
|
public PointBase OnGoingPosition
|
2023-01-08 09:22:37 +08:00
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
2023-01-15 20:27:39 +08:00
|
|
|
|
return SinkConnectorInfoPart?.MiddlePosition ?? PointBase.Zero;
|
2023-01-08 09:22:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsFullConnection
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return SinkConnectorInfoFully != null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-27 14:54:03 +08:00
|
|
|
|
public void RaiseFullConnection()
|
|
|
|
|
|
{
|
|
|
|
|
|
RaisePropertyChanged(nameof(IsFullConnection));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-02-19 21:38:28 +08:00
|
|
|
|
public double SmoothMargin { get; set; } = 125;
|
|
|
|
|
|
public double SmoothAutoSlope { get; set; } = 1;
|
2023-03-19 23:26:14 +08:00
|
|
|
|
public double OrthogonalShapeMargin { get; set; } = 10;
|
|
|
|
|
|
public double OrthogonalGlobalBoundsMargin { get; set; } = 50;
|
2023-02-19 21:38:28 +08:00
|
|
|
|
|
2023-01-27 20:10:17 +08:00
|
|
|
|
public bool IsPortless => SourceConnectorInfo.IsPortless || SinkConnectorInfoFully?.IsPortless == true;
|
2023-01-21 22:01:10 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 方法
|
2023-03-24 22:32:42 +08:00
|
|
|
|
public ICommand DeleteConnectionCommand
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
|
|
|
|
|
get; set;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-24 22:32:42 +08:00
|
|
|
|
public ICommand AddVertexCommand
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
|
|
|
|
|
get; set;
|
|
|
|
|
|
}
|
2023-01-22 22:10:39 +08:00
|
|
|
|
|
2023-03-24 22:32:42 +08:00
|
|
|
|
public ICommand AddLabelCommand
|
2023-01-22 22:10:39 +08:00
|
|
|
|
{
|
|
|
|
|
|
get; set;
|
|
|
|
|
|
}
|
2023-01-21 22:01:10 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
private void ConnectorViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
|
|
|
|
{
|
2023-01-24 17:53:04 +08:00
|
|
|
|
if (sender is ConnectionViewModel)
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
|
|
|
|
|
switch (e.PropertyName)
|
|
|
|
|
|
{
|
|
|
|
|
|
case nameof(SourceA):
|
|
|
|
|
|
case nameof(SourceB):
|
|
|
|
|
|
UpdateArea();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case nameof(Area):
|
|
|
|
|
|
UpdatePathGeneratorResult();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case nameof(Vertices):
|
|
|
|
|
|
foreach (var vertice in Vertices)
|
|
|
|
|
|
{
|
|
|
|
|
|
vertice.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
2023-01-22 21:46:59 +08:00
|
|
|
|
case nameof(Labels):
|
|
|
|
|
|
foreach (var label in Labels)
|
|
|
|
|
|
{
|
|
|
|
|
|
label.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
2023-01-21 22:01:10 +08:00
|
|
|
|
case nameof(SourceConnectorInfo):
|
2023-03-05 21:30:53 +08:00
|
|
|
|
if (SourceConnectorInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
SourceA = PointHelper.GetPointForConnector(SourceConnectorInfo);
|
|
|
|
|
|
SourceConnectorInfo.DataItem.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
|
|
|
|
|
}
|
2023-01-21 22:01:10 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case nameof(SinkConnectorInfo):
|
2023-03-05 21:30:53 +08:00
|
|
|
|
if (SinkConnectorInfo != null)
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
2023-03-05 21:30:53 +08:00
|
|
|
|
SourceB = SinkConnectorInfo.Position;
|
|
|
|
|
|
if (IsFullConnection)
|
|
|
|
|
|
{
|
|
|
|
|
|
SinkConnectorInfoFully.DataItem.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
|
|
|
|
|
}
|
2023-02-04 11:16:39 +08:00
|
|
|
|
}
|
2023-01-21 22:01:10 +08:00
|
|
|
|
break;
|
2023-01-22 21:46:59 +08:00
|
|
|
|
case nameof(IsSelected):
|
|
|
|
|
|
if (IsSelected == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
Labels.FirstOrDefault()?.AddToSelection(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
2023-02-20 23:01:26 +08:00
|
|
|
|
case nameof(RouterMode):
|
2023-03-25 22:10:49 +08:00
|
|
|
|
var routetype = TypeHelper.GetType(RouterMode);
|
2023-02-20 23:01:26 +08:00
|
|
|
|
Router = routetype != null ? (System.Activator.CreateInstance(routetype) as IRouter) : new RouterNormal();
|
|
|
|
|
|
UpdatePathGeneratorResult();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case nameof(PathMode):
|
2023-03-25 22:10:49 +08:00
|
|
|
|
var pathGeneratortype = TypeHelper.GetType(PathMode);
|
2023-02-20 23:01:26 +08:00
|
|
|
|
PathGenerator = pathGeneratortype != null ? (System.Activator.CreateInstance(pathGeneratortype) as IPathGenerator) : new ConnectingLineSmooth();
|
|
|
|
|
|
UpdatePathGeneratorResult();
|
|
|
|
|
|
break;
|
2023-01-21 22:01:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-01-26 18:27:17 +08:00
|
|
|
|
else if (sender is ShapeViewModel)
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
2023-01-26 18:27:17 +08:00
|
|
|
|
if (e.PropertyName == nameof(ShapeViewModel.SourceMarker) ||
|
|
|
|
|
|
e.PropertyName == nameof(ShapeViewModel.SinkMarker))
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
|
|
|
|
|
UpdatePathGeneratorResult();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (sender is DesignerItemViewModelBase)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (e.PropertyName)
|
|
|
|
|
|
{
|
|
|
|
|
|
case nameof(DesignerItemViewModelBase.ItemHeight):
|
|
|
|
|
|
case nameof(DesignerItemViewModelBase.ItemWidth):
|
|
|
|
|
|
case nameof(DesignerItemViewModelBase.Left):
|
|
|
|
|
|
case nameof(DesignerItemViewModelBase.Top):
|
|
|
|
|
|
if (IsFullConnection)
|
|
|
|
|
|
{
|
2023-02-04 16:38:56 +08:00
|
|
|
|
//减少触发一次画线
|
|
|
|
|
|
SourceA = PointHelper.GetPointForConnector(this.SourceConnectorInfo);
|
2023-01-21 22:01:10 +08:00
|
|
|
|
SourceB = PointHelper.GetPointForConnector(this.SinkConnectorInfoFully);
|
|
|
|
|
|
}
|
2023-02-04 16:38:56 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SourceA = PointHelper.GetPointForConnector(this.SourceConnectorInfo);
|
|
|
|
|
|
}
|
2023-01-21 22:01:10 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-01-22 22:10:39 +08:00
|
|
|
|
else if (sender is ConnectorVertexModel)
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
|
|
|
|
|
switch (e.PropertyName)
|
|
|
|
|
|
{
|
2023-01-24 16:20:39 +08:00
|
|
|
|
case nameof(ConnectorPointModel.X):
|
|
|
|
|
|
case nameof(ConnectorPointModel.Y):
|
2023-01-21 22:01:10 +08:00
|
|
|
|
UpdatePathGeneratorResult();
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-01-22 22:10:39 +08:00
|
|
|
|
else if (sender is ConnectorLabelModel linkLabelModel)
|
2023-01-22 21:46:59 +08:00
|
|
|
|
{
|
|
|
|
|
|
switch (e.PropertyName)
|
|
|
|
|
|
{
|
2023-01-24 16:20:39 +08:00
|
|
|
|
case nameof(ConnectorPointModel.X):
|
2023-01-22 21:46:59 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
|
|
|
|
|
|
{
|
|
|
|
|
|
linkLabelModel.UpdateOffsetX((double)valuePropertyChangedEventArgs.OldValue, (double)valuePropertyChangedEventArgs.NewValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2023-01-24 16:20:39 +08:00
|
|
|
|
case nameof(ConnectorPointModel.Y):
|
2023-01-22 21:46:59 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
|
|
|
|
|
|
{
|
|
|
|
|
|
linkLabelModel.UpdateOffsetY((double)valuePropertyChangedEventArgs.OldValue, (double)valuePropertyChangedEventArgs.NewValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-01-27 14:54:03 +08:00
|
|
|
|
else if (sender is ColorViewModel)
|
|
|
|
|
|
{
|
2023-02-04 16:38:56 +08:00
|
|
|
|
|
2023-01-27 14:54:03 +08:00
|
|
|
|
}
|
2023-01-21 22:01:10 +08:00
|
|
|
|
}
|
2023-01-08 09:22:37 +08:00
|
|
|
|
|
2021-07-23 09:42:22 +08:00
|
|
|
|
private void UpdateArea()
|
|
|
|
|
|
{
|
2023-01-08 09:22:37 +08:00
|
|
|
|
Area = new RectangleBase(SourceA, SourceB);
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-20 22:43:08 +08:00
|
|
|
|
private void UpdatePathGeneratorResult()
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
2023-01-14 21:52:05 +08:00
|
|
|
|
if (SourceConnectorInfo == null || SinkConnectorInfo == null)
|
|
|
|
|
|
return;
|
2021-07-23 09:42:22 +08:00
|
|
|
|
|
2023-01-24 16:20:39 +08:00
|
|
|
|
var route = Router.Get(Root, this);
|
2023-01-14 21:52:05 +08:00
|
|
|
|
|
2023-01-12 23:02:53 +08:00
|
|
|
|
(var source, var target) = FindConnectionPoints(route);
|
2023-01-20 22:43:08 +08:00
|
|
|
|
if (source == null || target == null)
|
|
|
|
|
|
return;
|
2023-01-08 09:22:37 +08:00
|
|
|
|
|
2023-01-24 16:20:39 +08:00
|
|
|
|
PathGeneratorResult = PathGenerator.Get(Root, this, route, source.Value, target.Value);
|
2023-01-20 22:43:08 +08:00
|
|
|
|
|
2023-02-04 12:17:03 +08:00
|
|
|
|
var startMiddle = new RectangleBase
|
|
|
|
|
|
(
|
2023-02-11 10:03:06 +08:00
|
|
|
|
(PathGeneratorResult.SourceMarkerPosition.X + (source.Value.X - Area.Left)) / 2,
|
|
|
|
|
|
(PathGeneratorResult.SourceMarkerPosition.Y + (source.Value.Y - Area.Top)) / 2,
|
2023-02-04 12:17:03 +08:00
|
|
|
|
0,
|
|
|
|
|
|
0
|
|
|
|
|
|
);
|
|
|
|
|
|
var endMiddle = new RectangleBase
|
2023-02-04 11:16:39 +08:00
|
|
|
|
(
|
2023-02-11 10:03:06 +08:00
|
|
|
|
(PathGeneratorResult.TargetMarkerPosition.X + (target.Value.X - Area.Left)) / 2,
|
|
|
|
|
|
(PathGeneratorResult.TargetMarkerPosition.Y + (target.Value.Y - Area.Top)) / 2,
|
2023-02-04 12:17:03 +08:00
|
|
|
|
0,
|
|
|
|
|
|
0
|
2023-02-04 11:16:39 +08:00
|
|
|
|
);
|
2023-02-04 12:17:03 +08:00
|
|
|
|
StartRectangle = startMiddle.InflateRectangle(GetSourceMarkerWidth() / 2, GetSourceMarkerHeight() / 2);
|
|
|
|
|
|
EndRectangle = endMiddle.InflateRectangle(GetSinkMarkerWidth() / 2, GetSinkMarkerHeight() / 2);
|
2023-02-04 11:16:39 +08:00
|
|
|
|
|
2023-01-15 11:59:51 +08:00
|
|
|
|
StartAngle = PathGeneratorResult.SourceMarkerAngle;
|
|
|
|
|
|
EndAngle = PathGeneratorResult.TargetMarkerAngle;
|
2023-01-22 21:46:59 +08:00
|
|
|
|
|
|
|
|
|
|
var paths = Labels.Count > 0 ? PathGeneratorResult.Paths.Select(p => new SvgPath(p)).ToArray() : Array.Empty<SvgPath>();
|
|
|
|
|
|
foreach (var label in Labels)
|
|
|
|
|
|
{
|
|
|
|
|
|
label.UpdatePosition(paths);
|
|
|
|
|
|
}
|
2023-01-14 21:52:05 +08:00
|
|
|
|
}
|
2021-07-23 09:42:22 +08:00
|
|
|
|
|
|
|
|
|
|
private void DeleteConnection(object args)
|
|
|
|
|
|
{
|
2023-01-24 16:20:39 +08:00
|
|
|
|
if (this.Root is IDiagramViewModel)
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
2023-01-24 16:20:39 +08:00
|
|
|
|
var diagramVM = this.Root as IDiagramViewModel;
|
2021-07-23 09:42:22 +08:00
|
|
|
|
diagramVM.RemoveItemCommand.Execute(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-12 23:02:53 +08:00
|
|
|
|
private (PointBase? source, PointBase? target) FindConnectionPoints(PointBase[] route)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsPortless) // Portless
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SourceConnectorInfo.DataItem == null || (IsFullConnection && SinkConnectorInfoFully.DataItem == null))
|
|
|
|
|
|
return (null, null);
|
2023-02-04 11:16:39 +08:00
|
|
|
|
|
2023-02-11 10:03:06 +08:00
|
|
|
|
var sourceCenter = SourceConnectorInfo.IsPortless ? SourceConnectorInfo.DataItem.MiddlePosition : SourceConnectorInfo.MiddlePosition;
|
|
|
|
|
|
var targetCenter = SinkConnectorInfoFully?.IsPortless == true ? SinkConnectorInfoFully?.DataItem?.MiddlePosition ?? OnGoingPosition : SinkConnectorInfoFully?.MiddlePosition ?? OnGoingPosition;
|
2023-01-12 23:02:53 +08:00
|
|
|
|
var firstPt = route.Length > 0 ? route[0] : targetCenter;
|
|
|
|
|
|
var secondPt = route.Length > 0 ? route[0] : sourceCenter;
|
|
|
|
|
|
var sourceLine = new LineBase(firstPt, sourceCenter);
|
|
|
|
|
|
var targetLine = new LineBase(secondPt, targetCenter);
|
|
|
|
|
|
var sourceIntersections = SourceConnectorInfo.DataItem.GetShape().GetIntersectionsWithLine(sourceLine);
|
|
|
|
|
|
var targetIntersections = SinkConnectorInfoFully.DataItem.GetShape()?.GetIntersectionsWithLine(targetLine) ?? new PointBase[] { OnGoingPosition };
|
|
|
|
|
|
var sourceIntersection = GetClosestPointTo(sourceIntersections, firstPt);
|
|
|
|
|
|
var targetIntersection = GetClosestPointTo(targetIntersections, secondPt);
|
2023-01-27 20:10:17 +08:00
|
|
|
|
|
2023-02-04 11:16:39 +08:00
|
|
|
|
return (sourceIntersection ?? sourceCenter, targetIntersection ?? targetCenter);
|
2023-01-12 23:02:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2023-01-15 22:17:46 +08:00
|
|
|
|
var source = SourceConnectorInfo.MiddlePosition;//GetPortPositionBasedOnAlignment(SourceConnectorInfo, ColorViewModel.LeftArrowSizeStyle);
|
|
|
|
|
|
var target = SinkConnectorInfo.MiddlePosition;// GetPortPositionBasedOnAlignment(SinkConnectorInfoFully, ColorViewModel.RightArrowSizeStyle);
|
|
|
|
|
|
return (source, target);
|
2023-01-12 23:02:53 +08:00
|
|
|
|
}
|
2023-01-27 20:10:17 +08:00
|
|
|
|
|
2023-02-04 11:16:39 +08:00
|
|
|
|
|
2023-01-12 23:02:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private PointBase? GetPortPositionBasedOnAlignment(ConnectorInfoBase port, ArrowSizeStyle marker)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (port == null)
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
2023-01-22 21:46:59 +08:00
|
|
|
|
if (marker == 0)
|
2023-01-15 20:27:39 +08:00
|
|
|
|
return port.MiddlePosition;
|
2023-01-12 23:02:53 +08:00
|
|
|
|
|
2023-01-15 20:27:39 +08:00
|
|
|
|
var pt = port.Position;
|
2023-01-12 23:02:53 +08:00
|
|
|
|
switch (port.Orientation)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ConnectorOrientation.Top:
|
|
|
|
|
|
return new PointBase(pt.X + port.ConnectorWidth / 2, pt.Y);
|
|
|
|
|
|
case ConnectorOrientation.TopRight:
|
|
|
|
|
|
return new PointBase(pt.X + port.ConnectorWidth, pt.Y);
|
|
|
|
|
|
case ConnectorOrientation.Right:
|
|
|
|
|
|
return new PointBase(pt.X + port.ConnectorWidth, pt.Y + port.ConnectorHeight / 2);
|
|
|
|
|
|
case ConnectorOrientation.BottomRight:
|
|
|
|
|
|
return new PointBase(pt.X + port.ConnectorWidth, pt.Y + port.ConnectorHeight);
|
|
|
|
|
|
case ConnectorOrientation.Bottom:
|
|
|
|
|
|
return new PointBase(pt.X + port.ConnectorWidth / 2, pt.Y + port.ConnectorHeight);
|
|
|
|
|
|
case ConnectorOrientation.BottomLeft:
|
|
|
|
|
|
return new PointBase(pt.X, pt.Y + port.ConnectorHeight);
|
|
|
|
|
|
case ConnectorOrientation.Left:
|
|
|
|
|
|
return new PointBase(pt.X, pt.Y + port.ConnectorHeight / 2);
|
|
|
|
|
|
default:
|
|
|
|
|
|
return pt;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private PointBase? GetClosestPointTo(IEnumerable<PointBase> points, PointBase point)
|
|
|
|
|
|
{
|
|
|
|
|
|
var minDist = double.MaxValue;
|
|
|
|
|
|
PointBase? minPoint = null;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var pt in points)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dist = pt.DistanceTo(point);
|
|
|
|
|
|
if (dist < minDist)
|
|
|
|
|
|
{
|
|
|
|
|
|
minDist = dist;
|
|
|
|
|
|
minPoint = pt;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return minPoint;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-26 18:27:17 +08:00
|
|
|
|
public void SetSourcePort(FullyCreatedConnectorInfo port)
|
|
|
|
|
|
{
|
|
|
|
|
|
SourceConnectorInfo = port;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetSinkPort(FullyCreatedConnectorInfo port)
|
|
|
|
|
|
{
|
|
|
|
|
|
SinkConnectorInfo = port;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-19 23:26:14 +08:00
|
|
|
|
public void UpdateConnectionMode(FullyCreatedConnectorInfo source, FullyCreatedConnectorInfo sink, string pathmode, string routermode)
|
|
|
|
|
|
{
|
|
|
|
|
|
//先置空,避免更新
|
|
|
|
|
|
SourceConnectorInfo = null;
|
|
|
|
|
|
SinkConnectorInfo = null;
|
|
|
|
|
|
PathMode = pathmode;
|
|
|
|
|
|
RouterMode = routermode;
|
|
|
|
|
|
SourceConnectorInfo = source;
|
|
|
|
|
|
SinkConnectorInfo = sink;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-25 22:10:49 +08:00
|
|
|
|
public void SetPathGeneratorParameter(double smoothMargin, double smoothAutoSlope, double orthogonalShapeMargin, double orthogonalGlobalBoundsMargin)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool hasChanged = false;
|
|
|
|
|
|
if (SmoothMargin != smoothMargin)
|
|
|
|
|
|
{
|
|
|
|
|
|
hasChanged = true;
|
|
|
|
|
|
SmoothMargin = smoothMargin;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (SmoothAutoSlope != smoothAutoSlope)
|
|
|
|
|
|
{
|
|
|
|
|
|
hasChanged = true;
|
|
|
|
|
|
SmoothAutoSlope = smoothAutoSlope;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (OrthogonalShapeMargin != orthogonalShapeMargin)
|
|
|
|
|
|
{
|
|
|
|
|
|
hasChanged = true;
|
|
|
|
|
|
OrthogonalShapeMargin = orthogonalShapeMargin;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (OrthogonalGlobalBoundsMargin != orthogonalGlobalBoundsMargin)
|
|
|
|
|
|
{
|
|
|
|
|
|
hasChanged = true;
|
|
|
|
|
|
OrthogonalGlobalBoundsMargin = orthogonalGlobalBoundsMargin;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (hasChanged)
|
|
|
|
|
|
{
|
|
|
|
|
|
UpdatePathGeneratorResult();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-02-27 20:18:58 +08:00
|
|
|
|
public void SetVisible(bool visible)
|
|
|
|
|
|
{
|
|
|
|
|
|
Visible = visible;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-26 18:27:17 +08:00
|
|
|
|
public double GetSourceMarkerWidth()
|
|
|
|
|
|
{
|
2023-02-04 11:16:39 +08:00
|
|
|
|
if (!IsFullConnection || string.IsNullOrEmpty(ShapeViewModel.SourceMarker.Path))
|
2023-01-26 18:27:17 +08:00
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return ShapeViewModel.SourceMarker.Width;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-02-04 11:16:39 +08:00
|
|
|
|
public double GetSourceMarkerHeight()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!IsFullConnection || string.IsNullOrEmpty(ShapeViewModel.SourceMarker.Path))
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return ShapeViewModel.SourceMarker.Height;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-26 18:27:17 +08:00
|
|
|
|
public double GetSinkMarkerWidth()
|
|
|
|
|
|
{
|
2023-02-04 11:16:39 +08:00
|
|
|
|
if (!IsFullConnection || string.IsNullOrEmpty(ShapeViewModel.SinkMarker.Path))
|
2023-01-26 18:27:17 +08:00
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return ShapeViewModel.SinkMarker.Width;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-02-04 11:16:39 +08:00
|
|
|
|
public double GetSinkMarkerHeight()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!IsFullConnection || string.IsNullOrEmpty(ShapeViewModel.SinkMarker.Path))
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return ShapeViewModel.SinkMarker.Height;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-21 22:01:10 +08:00
|
|
|
|
#region 双击添加
|
2023-01-22 21:46:59 +08:00
|
|
|
|
private void AddVertex(object parameter)
|
|
|
|
|
|
{
|
|
|
|
|
|
MouseButtonEventArgs mosueArg = ((EventToCommandArgs)parameter).EventArgs as MouseButtonEventArgs;
|
|
|
|
|
|
var position = mosueArg.GetPosition(((EventToCommandArgs)parameter).Sender as IInputElement);
|
|
|
|
|
|
|
2023-01-26 22:25:48 +08:00
|
|
|
|
AddVertex(position, false);
|
2023-01-22 21:46:59 +08:00
|
|
|
|
|
|
|
|
|
|
if (!((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control))
|
|
|
|
|
|
{
|
|
|
|
|
|
ShouldInsertAnchor = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-26 22:25:48 +08:00
|
|
|
|
public void AddVertex(PointBase pointBase, bool absolute = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (absolute)
|
|
|
|
|
|
{
|
|
|
|
|
|
pointBase = new PointBase(pointBase.X - Area.Left, pointBase.Y - Area.Top);
|
|
|
|
|
|
}
|
|
|
|
|
|
var vertice = new ConnectorVertexModel(this, pointBase);
|
|
|
|
|
|
vertice.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
|
|
|
|
|
Vertices.Add(vertice);
|
|
|
|
|
|
UpdatePathGeneratorResult();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-08 21:48:43 +08:00
|
|
|
|
public void RemoveVertex(ConnectorVertexModel vertice)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vertices.Remove(vertice);
|
|
|
|
|
|
UpdatePathGeneratorResult();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-21 22:01:10 +08:00
|
|
|
|
protected override void ExecuteEditCommand(object param)
|
|
|
|
|
|
{
|
2023-01-23 15:43:44 +08:00
|
|
|
|
AddLabel();
|
2023-01-21 22:01:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-26 18:27:17 +08:00
|
|
|
|
public void AddLabel(string text = null, double? distance = null, PointBase? offset = null)
|
2023-01-21 22:01:10 +08:00
|
|
|
|
{
|
2023-01-26 18:27:17 +08:00
|
|
|
|
var label = new ConnectorLabelModel(this, text?.ToString(), distance, offset);
|
2023-01-22 21:46:59 +08:00
|
|
|
|
label.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
|
|
|
|
|
label.IsSelected = true;
|
|
|
|
|
|
Labels.Add(label);
|
2023-01-21 22:01:10 +08:00
|
|
|
|
|
2023-01-25 14:42:01 +08:00
|
|
|
|
var paths = Labels.Count > 0 ? PathGeneratorResult?.Paths.Select(p => new SvgPath(p)).ToArray() : Array.Empty<SvgPath>();
|
2023-01-22 21:46:59 +08:00
|
|
|
|
label.UpdatePosition(paths);
|
2023-01-21 22:01:10 +08:00
|
|
|
|
}
|
2023-01-23 15:43:44 +08:00
|
|
|
|
|
2023-04-08 21:48:43 +08:00
|
|
|
|
public void RemoveLabel(ConnectorLabelModel label)
|
|
|
|
|
|
{
|
|
|
|
|
|
Labels.Remove(label);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ClearLabel()
|
2023-03-13 19:44:30 +08:00
|
|
|
|
{
|
|
|
|
|
|
Labels?.Clear();
|
|
|
|
|
|
}
|
2023-01-21 22:01:10 +08:00
|
|
|
|
#endregion
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|