简单demo继续完善

This commit is contained in:
艾竹
2022-11-30 22:28:22 +08:00
parent 13f30f23d8
commit 992a4bb83b
11 changed files with 652 additions and 190 deletions

View File

@@ -15,6 +15,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
VectorLineDrawMode = vectorLineDrawMode;
Init(sourceConnectorInfo, sinkConnectorInfo);
}
public ConnectorViewModel(FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode vectorLineDrawMode)
@@ -24,11 +25,17 @@ namespace AIStudio.Wpf.DiagramDesigner
}
public static IPathFinder PathFinder { get; set; }
public IPathFinder PathFinder
{
get; set;
}
public bool IsFullConnection
{
get { return _sinkConnectorInfo is FullyCreatedConnectorInfo; }
get
{
return _sinkConnectorInfo is FullyCreatedConnectorInfo;
}
}
private Point _sourceA;
@@ -127,7 +134,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
public DrawMode VectorLineDrawMode { get; set; }
public DrawMode VectorLineDrawMode
{
get; set;
}
public ConnectorInfo ConnectorInfo(ConnectorOrientation orientation, double left, double top, double width, double height, Point position)
{
@@ -191,181 +201,11 @@ namespace AIStudio.Wpf.DiagramDesigner
private void UpdateConnectionPoints()
{
if (VectorLineDrawMode == DrawMode.ConnectingLine)
{
UpdateConnectionPointsByLine();
}
else if (VectorLineDrawMode == DrawMode.BoundaryConnectingLine)
{
UpdateConnectionPointsByBoundary();
}
else
{
UpdateConnectionPointsByCorner();
}
}
private void UpdateConnectionPointsByLine()
{
ConnectionPoints = PointInfoBase.ToList(new List<Point>()
{
new Point(SourceA.X < SourceB.X ? 0d : Area.Width, SourceA.Y < SourceB.Y ? 0d : Area.Height ),
new Point(SourceA.X > SourceB.X ? 0d : Area.Width, SourceA.Y > SourceB.Y ? 0d : Area.Height)
});
StartPoint = ConnectionPoints[0];
ConnectionPoints = PathFinder.UpdateConnectionPoints(Parent, SourceA, SourceB, SourceConnectorInfo, SinkConnectorInfo);
StartPoint = ConnectionPoints.First();
EndPoint = ConnectionPoints.Last();
}
private void UpdateConnectionPointsByCorner()
{
var points = new List<Point>()
{
new Point(SourceA.X < SourceB.X ? 0d : Area.Width, SourceA.Y < SourceB.Y ? 0d : Area.Height ),
new Point(SourceA.X > SourceB.X ? 0d : Area.Width, SourceA.Y > SourceB.Y ? 0d : Area.Height)
};
ConnectorInfo sourceInfo = ConnectorInfo(SourceConnectorInfo.Orientation,
points[0].X,
points[0].Y,
SourceConnectorInfo.DataItem.ItemWidth,
SourceConnectorInfo.DataItem.ItemHeight,
points[0]);
StartPoint = points[0];
if (IsFullConnection)
{
EndPoint = points.Last();
ConnectorInfo sinkInfo = ConnectorInfo(SinkConnectorInfo.Orientation,
points[1].X,
points[1].Y,
((FullyCreatedConnectorInfo)_sinkConnectorInfo).DataItem.ItemWidth,
((FullyCreatedConnectorInfo)_sinkConnectorInfo).DataItem.ItemHeight,
points[1]);
ConnectionPoints = PointInfoBase.ToList(PathFinder.GetConnectionLine(sourceInfo, sinkInfo, false, SourceConnectorInfo.IsInnerPoint));
}
else
{
ConnectionPoints = PointInfoBase.ToList(PathFinder.GetConnectionLine(sourceInfo, points[1], SourceConnectorInfo.Orientation, false, SourceConnectorInfo.IsInnerPoint));
EndPoint = new Point();
}
}
#region
private void UpdateConnectionPointsByBoundary()
{
var points = new List<Point>();
var ends = GetEndPoinds();
points.Add(ends[0]);
points.AddRange(GetMiddlePoints(ends[0], ends[1]));
points.Add(ends[1]);
var res = points.ToArray();
//UpdateEdges(res);
DoShift(res);
ConnectionPoints = PointInfoBase.ToList(res.ToList());
StartPoint = ConnectionPoints[0];
EndPoint = ConnectionPoints.Last();
}
private IEnumerable<Point> GetMiddlePoints(Point start, Point end)
{
var points = new List<Point>();
if (IsFullConnection)
{
var p0 = GetFirstSegment(SourceConnectorInfo, start, Parent.GridCellSize, Parent.GridMargin);
var p1 = GetFirstSegment(SinkConnectorInfo, end, Parent.GridCellSize, Parent.GridMargin);
if (p0 == p1)
return points;
var p2 = new Point(GetNearestCross(p0.X, p1.X), GetNearestCross(p0.Y, p1.Y));
var p3 = new Point(GetNearestCross(p1.X, p0.X), GetNearestCross(p1.Y, p0.Y));
if (p2 == p3)
{
points.Add(p0);
points.Add(p2);
points.Add(p1);
}
else
{
points.Add(p0);
points.Add(p2);
if (!(Math.Abs(p2.X - p3.X) < 0.0001) && !(Math.Abs(p2.Y - p3.Y) < 0.0001))
points.Add(new Point(p2.X, p3.Y));
points.Add(p3);
points.Add(p1);
}
DoScale(points, Parent.GridCellSize, Parent.GridMargin);
}
return points;
}
private Point[] GetEndPoinds()
{
var linePoints = new Point[2];
linePoints[0] = SourceA;
linePoints[1] = SourceB;
return linePoints;
}
private Point GetFirstSegment(ConnectorInfoBase port, Point point, Size cellSize, double margin)
{
double x = (int)((point.X - margin) / cellSize.Width) + 0.5;
double y = (int)((point.Y - margin) / cellSize.Height) + 0.5;
if (port.Orientation == ConnectorOrientation.Top)
return new Point(x, y - 0.5);
else if (port.Orientation == ConnectorOrientation.Bottom)
return new Point(x, y + 0.5);
else if (port.Orientation == ConnectorOrientation.Left)
return new Point(x - 0.5, y);
else
return new Point(x + 0.5, y);
}
private double GetNearestCross(double a, double b)
{
if (Math.Abs(a - b) < 0.0001 && (int)a == a)
return a;
else if (a < b)
return Math.Ceiling(a);
else
return Math.Floor(a);
}
private void DoScale(List<Point> points, Size cellSize, double margin)
{
for (int i = 0; i < points.Count; i++)
{
points[i] = new Point(points[i].X * cellSize.Width + margin,
points[i].Y * cellSize.Height + margin);
}
}
private void DoShift(Point[] points)
{
double left = new Point[] { points.FirstOrDefault(), points.LastOrDefault() }.Min(p => p.X);
double top = new Point[] { points.FirstOrDefault(), points.LastOrDefault() }.Min(p => p.Y);
for (int i = 0; i < points.Length; i++)
{
points[i].X = points[i].X - left;
points[i].Y = points[i].Y - top;
}
}
private Point SegmentMiddlePoint(Point p1, Point p2)
{
return new Point((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2);
}
#endregion
}
private void ConnectorViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
@@ -400,9 +240,20 @@ namespace AIStudio.Wpf.DiagramDesigner
private void Init(FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo)
{
this.Parent = sourceConnectorInfo.DataItem.Parent;
if (VectorLineDrawMode == DrawMode.ConnectingLine)
{
PathFinder = new StraightLinePathFinder();
}
else if (VectorLineDrawMode == DrawMode.BoundaryConnectingLine)
{
PathFinder = new BoundaryPathFinder();
}
else
{
PathFinder = new OrthogonalPathFinder();
}
this.SourceConnectorInfo = sourceConnectorInfo;
this.SinkConnectorInfo = sinkConnectorInfo;
PathFinder = new OrthogonalPathFinder();
this.SinkConnectorInfo = sinkConnectorInfo;
DeleteConnectionCommand = new SimpleCommand(DeleteConnection);
if (sinkConnectorInfo is FullyCreatedConnectorInfo sink && sink.DataItem.ShowArrow == false)
@@ -411,7 +262,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
public SimpleCommand DeleteConnectionCommand { get; set; }
public SimpleCommand DeleteConnectionCommand
{
get; set;
}
private void DeleteConnection(object args)
{
if (this.Parent is IDiagramViewModel)
@@ -439,7 +293,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (diagramVM.DiagramType == DiagramType.FlowChart)
{
var mid = (int)(ConnectionPoints.Count / 2);
var p = SegmentMiddlePoint(ConnectionPoints[mid - 1], ConnectionPoints[mid]);
var p = BoundaryPathFinder.SegmentMiddlePoint(ConnectionPoints[mid - 1], ConnectionPoints[mid]);
textitem.Left = this.Area.Left + p.X + 2;
textitem.Top = this.Area.Top + p.Y - 15;
}