部分连接线拖拽完成

This commit is contained in:
艾竹
2023-05-03 09:59:46 +08:00
parent 6de36f2473
commit 1536e5018d
33 changed files with 997 additions and 158 deletions

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Input;
@@ -23,19 +24,19 @@ namespace AIStudio.Wpf.DiagramDesigner
}
public ConnectionViewModel(FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode drawMode = DrawMode.ConnectingLineSmooth, RouterMode routerMode = AIStudio.Wpf.DiagramDesigner.RouterMode.RouterNormal) : this(null, sourceConnectorInfo, sinkConnectorInfo, drawMode, routerMode)
public ConnectionViewModel(ConnectorInfoBase sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode drawMode = DrawMode.ConnectingLineSmooth, RouterMode routerMode = AIStudio.Wpf.DiagramDesigner.RouterMode.RouterNormal) : this(null, sourceConnectorInfo, sinkConnectorInfo, drawMode, routerMode)
{
}
public ConnectionViewModel(IDiagramViewModel root, FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode drawMode = DrawMode.ConnectingLineSmooth, RouterMode routerMode = AIStudio.Wpf.DiagramDesigner.RouterMode.RouterNormal) : base(root)
public ConnectionViewModel(IDiagramViewModel root, ConnectorInfoBase sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode drawMode = DrawMode.ConnectingLineSmooth, RouterMode routerMode = AIStudio.Wpf.DiagramDesigner.RouterMode.RouterNormal) : base(root)
{
_pathMode = drawMode.ToString();
_routerMode = routerMode.ToString();
Init(root, sourceConnectorInfo, sinkConnectorInfo);
}
public ConnectionViewModel(IDiagramViewModel root, FullyCreatedConnectorInfo sourceConnectorInfo, FullyCreatedConnectorInfo sinkConnectorInfo, ConnectionItem designer) : base(root, designer)
public ConnectionViewModel(IDiagramViewModel root, ConnectorInfoBase sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, ConnectionItem designer) : base(root, designer)
{
_pathMode = designer.PathMode;
_routerMode = designer.RouterMode;
@@ -50,13 +51,13 @@ namespace AIStudio.Wpf.DiagramDesigner
return connection;
}
else
else//Todo,半连接线也可序列化
{
return null;
}
}
protected virtual void Init(IDiagramViewModel root, FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo)
protected virtual void Init(IDiagramViewModel root, ConnectorInfoBase sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo)
{
IsLoaded = false;
this.Root = root ?? sourceConnectorInfo.Root;
@@ -244,6 +245,19 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private Thickness _dragThumbMargin;
public Thickness DragThumbMargin
{
get
{
return _dragThumbMargin;
}
private set
{
SetProperty(ref _dragThumbMargin, value);
}
}
private RectangleBase _area;
public RectangleBase Area
{
@@ -357,8 +371,8 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private FullyCreatedConnectorInfo _sourceConnectorInfo;
public FullyCreatedConnectorInfo SourceConnectorInfo
private ConnectorInfoBase _sourceConnectorInfo;
public ConnectorInfoBase SourceConnectorInfo
{
get
{
@@ -367,6 +381,23 @@ namespace AIStudio.Wpf.DiagramDesigner
set
{
SetProperty(ref _sourceConnectorInfo, value);
}
}
public FullyCreatedConnectorInfo SourceConnectorInfoFully
{
get
{
return SourceConnectorInfo as FullyCreatedConnectorInfo;
}
}
public PartCreatedConnectorInfo SourceConnectorInfoPart
{
get
{
return SourceConnectorInfo as PartCreatedConnectorInfo;
}
}
@@ -412,10 +443,11 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get
{
return SinkConnectorInfoFully != null;
return SourceConnectorInfoFully != null && SinkConnectorInfoFully != null;
}
}
public void RaiseFullConnection()
{
RaisePropertyChanged(nameof(IsFullConnection));
@@ -426,7 +458,7 @@ namespace AIStudio.Wpf.DiagramDesigner
public double OrthogonalShapeMargin { get; set; } = 10;
public double OrthogonalGlobalBoundsMargin { get; set; } = 50;
public bool IsPortless => SourceConnectorInfo.IsPortless || SinkConnectorInfoFully?.IsPortless == true;
public bool IsPortless => SourceConnectorInfoFully?.IsPortless == true || SinkConnectorInfoFully?.IsPortless == true;
#endregion
#region
@@ -476,18 +508,29 @@ namespace AIStudio.Wpf.DiagramDesigner
case nameof(SourceConnectorInfo):
if (SourceConnectorInfo != null)
{
SourceA = PointHelper.GetPointForConnector(SourceConnectorInfo);
SourceConnectorInfo.DataItem.PropertyChanged += new WeakINPCEventHandler(Item_PropertyChanged).Handler;
SourceA = SourceConnectorInfo.Position;
if (SourceConnectorInfoFully != null)
{
SourceConnectorInfoFully.DataItem.PropertyChanged += new WeakINPCEventHandler(Item_PropertyChanged).Handler;
}
//else if (SourceConnectorInfoPart != null)
//{
// SourceConnectorInfoPart.PropertyChanged += new WeakINPCEventHandler(Item_PropertyChanged).Handler;
//}
}
break;
case nameof(SinkConnectorInfo):
if (SinkConnectorInfo != null)
{
SourceB = SinkConnectorInfo.Position;
if (IsFullConnection)
if (SinkConnectorInfoFully != null)
{
SinkConnectorInfoFully.DataItem.PropertyChanged += new WeakINPCEventHandler(Item_PropertyChanged).Handler;
}
//else if (SinkConnectorInfoPart != null)
//{
// SinkConnectorInfoPart.PropertyChanged += new WeakINPCEventHandler(Item_PropertyChanged).Handler;
//}
}
break;
case nameof(IsSelected):
@@ -513,7 +556,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (e.PropertyName == nameof(ShapeViewModel.SourceMarker) ||
e.PropertyName == nameof(ShapeViewModel.SinkMarker))
{
UpdatePathGeneratorResult();
UpdateArea();
}
}
else if (sender is DesignerItemViewModelBase)
@@ -527,12 +570,12 @@ namespace AIStudio.Wpf.DiagramDesigner
if (IsFullConnection)
{
//减少触发一次画线
SourceA = PointHelper.GetPointForConnector(this.SourceConnectorInfo);
SourceA = PointHelper.GetPointForConnector(this.SourceConnectorInfoFully);
SourceB = PointHelper.GetPointForConnector(this.SinkConnectorInfoFully);
}
else
{
SourceA = PointHelper.GetPointForConnector(this.SourceConnectorInfo);
SourceA = SourceConnectorInfo.MiddlePosition;
}
break;
}
@@ -570,6 +613,21 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
}
//else if (sender is PartCreatedConnectorInfo)
//{
// if (e.PropertyName == "Position")
// {
// if (sender == SourceConnectorInfoPart)
// {
// SourceA = SourceConnectorInfo.Position;
// }
// else if (sender == SinkConnectorInfoPart)
// {
// SourceB = SinkConnectorInfo.Position;
// }
// UpdatePathGeneratorResult();
// }
//}
else if (sender is ColorViewModel)
{
@@ -613,7 +671,7 @@ namespace AIStudio.Wpf.DiagramDesigner
StartAngle = PathGeneratorResult.SourceMarkerAngle;
EndAngle = PathGeneratorResult.TargetMarkerAngle;
//StartPoint = new PointBase(source.Value.X - Area.Left - SourceConnectorInfo.ConnectorWidth / 2, source.Value.Y - Area.Top - SourceConnectorInfo.ConnectorHeight / 2) ;
//StartPoint = new PointBase(source.Value.X - Area.Left - SourceConnectorInfoFully.ConnectorWidth / 2, source.Value.Y - Area.Top - SourceConnectorInfoFully.ConnectorHeight / 2) ;
//EndPoint = new PointBase(target.Value.X - Area.Left - SinkConnectorInfo.ConnectorWidth / 2 , target.Value.Y - Area.Top - SinkConnectorInfo.ConnectorHeight / 2 );
StartPoint = new PointBase(source.Value.X - Area.Left , source.Value.Y - Area.Top );
@@ -650,6 +708,18 @@ namespace AIStudio.Wpf.DiagramDesigner
{
label.UpdatePosition(paths);
}
double marginwidth = 0;
double marginheight = 0;
if (Area.Width > SourceConnectorInfo.ConnectorWidth + SinkConnectorInfo.ConnectorWidth)
{
marginwidth = (SourceConnectorInfo.ConnectorWidth + SinkConnectorInfo.ConnectorWidth) / 2;
}
if (Area.Height > SourceConnectorInfo.ConnectorHeight + SinkConnectorInfo.ConnectorHeight)
{
marginheight = (SourceConnectorInfo.ConnectorHeight + SinkConnectorInfo.ConnectorHeight) / 2;
}
DragThumbMargin = new Thickness(marginwidth, marginheight, marginwidth, marginheight);
}
private void DeleteConnection(object args)
@@ -665,17 +735,17 @@ namespace AIStudio.Wpf.DiagramDesigner
{
if (IsPortless) // Portless
{
if (SourceConnectorInfo.DataItem == null || (IsFullConnection && SinkConnectorInfoFully.DataItem == null))
if (SourceConnectorInfoFully?.DataItem == null || SinkConnectorInfoFully?.DataItem == null)
return (null, null);
var sourceCenter = SourceConnectorInfo.IsPortless ? SourceConnectorInfo.DataItem.MiddlePosition : SourceConnectorInfo.MiddlePosition;
var sourceCenter = SourceConnectorInfoFully.IsPortless ? SourceConnectorInfoFully.DataItem.MiddlePosition : SourceConnectorInfoFully.MiddlePosition;
var targetCenter = SinkConnectorInfoFully?.IsPortless == true ? SinkConnectorInfoFully?.DataItem?.MiddlePosition ?? OnGoingPosition : SinkConnectorInfoFully?.MiddlePosition ?? OnGoingPosition;
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 sourceIntersections = SourceConnectorInfoFully.DataItem.GetShape().GetIntersectionsWithLine(sourceLine);
var targetIntersections = SinkConnectorInfoFully?.DataItem?.GetShape()?.GetIntersectionsWithLine(targetLine) ?? new PointBase[] { OnGoingPosition };
var sourceIntersection = GetClosestPointTo(sourceIntersections, firstPt);
var targetIntersection = GetClosestPointTo(targetIntersections, secondPt);
@@ -683,7 +753,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
else
{
var source = SourceConnectorInfo.MiddlePosition;//GetPortPositionBasedOnAlignment(SourceConnectorInfo, ColorViewModel.LeftArrowSizeStyle);
var source = SourceConnectorInfo.MiddlePosition;//GetPortPositionBasedOnAlignment(SourceConnectorInfoFully, ColorViewModel.LeftArrowSizeStyle);
var target = SinkConnectorInfo.MiddlePosition;// GetPortPositionBasedOnAlignment(SinkConnectorInfoFully, ColorViewModel.RightArrowSizeStyle);
return (source, target);
}
@@ -749,6 +819,22 @@ namespace AIStudio.Wpf.DiagramDesigner
SinkConnectorInfo = port;
}
public void SetPartPostion(PointBase? sourcePoint, PointBase? sinkPoint)
{
if (sourcePoint != null)
{
SourceConnectorInfoPart.Position = sourcePoint.Value;
_sourceA = SourceConnectorInfoPart.Position;
}
if (sinkPoint != null)
{
SinkConnectorInfoPart.Position = sinkPoint.Value;
_sourceB = SinkConnectorInfoPart.Position;
}
UpdateArea();
}
public void UpdateConnectionMode(FullyCreatedConnectorInfo source, FullyCreatedConnectorInfo sink, string pathmode, string routermode)
{
//先置空,避免更新

View File

@@ -65,7 +65,7 @@ namespace AIStudio.Wpf.DiagramDesigner
#region
public virtual PointBase Position
{
get;
get;set;
}
public virtual PointBase MiddlePosition

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
@@ -16,20 +17,23 @@ namespace AIStudio.Wpf.DiagramDesigner
public PartCreatedConnectorInfo(IDiagramViewModel root, double X, double Y) : base(root, ConnectorOrientation.None)
{
this.position = new PointBase(X, Y);
this._position = new PointBase(X, Y);
}
private PointBase position;
private PointBase _position;
public override PointBase Position
{
get
{
return position;
return _position;
}
set
{
SetProperty(ref _position, value);
}
}
}
}

View File

@@ -1636,7 +1636,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
if (!selectedConnections.Contains(connection))
{
DesignerItemViewModelBase sourceItem = selectedDesignerItems.FirstOrDefault(p => p.Id == connection.SourceConnectorInfo.DataItem.Id);
DesignerItemViewModelBase sourceItem = selectedDesignerItems.FirstOrDefault(p => p.Id == connection.SourceConnectorInfoFully?.DataItem.Id);
DesignerItemViewModelBase sinkItem = selectedDesignerItems.FirstOrDefault(p => p.Id == connection.SinkConnectorInfoFully?.DataItem?.Id);
if (sourceItem != null && sinkItem != null && BelongToSameGroup(sourceItem, sinkItem))
{