修改暂存一下

This commit is contained in:
艾竹
2023-01-12 23:02:53 +08:00
parent 5d7717cc2b
commit 6a4c31106a
58 changed files with 776 additions and 468 deletions

View File

@@ -25,17 +25,31 @@ namespace AIStudio.Wpf.DiagramDesigner
private Point? rubberbandSelectionStartPoint = null;
private DrawMode VectorLineDrawMode
private DrawMode DrawMode
{
get
{
if (_viewModel.DrawModeViewModel?.VectorLineDrawMode != null)
if (_viewModel.DrawModeViewModel?.LineDrawMode != null)
{
return _viewModel.DrawModeViewModel.VectorLineDrawMode;
return _viewModel.DrawModeViewModel.LineDrawMode;
}
else
{
return _service.DrawModeViewModel.VectorLineDrawMode;
return _service.DrawModeViewModel.LineDrawMode;
}
}
}
private RouterMode RouterMode
{
get
{
if (_viewModel.DrawModeViewModel?.LineRouterMode != null)
{
return _viewModel.DrawModeViewModel.LineRouterMode;
}
else
{
return _service.DrawModeViewModel.LineRouterMode;
}
}
}
@@ -203,7 +217,7 @@ namespace AIStudio.Wpf.DiagramDesigner
Rect rectangleBounds = sourceConnector.TransformToVisual(this).TransformBounds(new Rect(sourceConnector.RenderSize));
Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2),
rectangleBounds.Bottom + (rectangleBounds.Height / 2));
partialConnection = new ConnectorViewModel(_viewModel, sourceDataItem, new PartCreatedConnectionInfo(point.X, point.Y), VectorLineDrawMode);
partialConnection = new ConnectorViewModel(_viewModel, sourceDataItem, new PartCreatedConnectionInfo(point.X, point.Y), DrawMode, RouterMode);
_viewModel.DirectAddItemCommand.Execute(partialConnection);
}
@@ -225,7 +239,7 @@ namespace AIStudio.Wpf.DiagramDesigner
Rect rectangleBounds = new Rect(sourceConnectorInfo.DataItem.Left, sourceConnectorInfo.DataItem.Top, 3, 3);
Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2),
rectangleBounds.Bottom + (rectangleBounds.Height / 2));
partialConnection = new ConnectorViewModel(_viewModel, sourceConnectorInfo, new PartCreatedConnectionInfo(point.X, point.Y), VectorLineDrawMode);
partialConnection = new ConnectorViewModel(_viewModel, sourceConnectorInfo, new PartCreatedConnectionInfo(point.X, point.Y), DrawMode, RouterMode);
_viewModel.DirectAddItemCommand.Execute(partialConnection);
}
}
@@ -270,7 +284,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
e.Handled = true;
if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.ConnectingLine)
if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.SmoothConnectingLine)
{
if (connectorsHit.Count == 0)
{
@@ -362,9 +376,9 @@ namespace AIStudio.Wpf.DiagramDesigner
int indexOfLastTempConnection = sinkDataItem.DataItem.Parent.Items.Count - 1;
sinkDataItem.DataItem.Parent.DirectRemoveItemCommand.Execute(
sinkDataItem.DataItem.Parent.Items[indexOfLastTempConnection]);
sinkDataItem.DataItem.Parent.AddItemCommand.Execute(new ConnectorViewModel(_viewModel, sourceDataItem, sinkDataItem, VectorLineDrawMode));
sinkDataItem.DataItem.Parent.AddItemCommand.Execute(new ConnectorViewModel(_viewModel, sourceDataItem, sinkDataItem, DrawMode, RouterMode));
}
else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.ConnectingLine && connectorsHit.Count() == 1)
else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.SmoothConnectingLine && connectorsHit.Count() == 1)
{
LinkPointDesignerItemViewModel pointItemView = new LinkPointDesignerItemViewModel(e.GetPosition(this));
FullyCreatedConnectorInfo sinkDataItem = pointItemView.TopConnector;
@@ -373,7 +387,7 @@ namespace AIStudio.Wpf.DiagramDesigner
_viewModel.DirectRemoveItemCommand.Execute(_viewModel.Items[indexOfLastTempConnection]);
_viewModel.DirectAddItemCommand.Execute(pointItemView);
var connector = new ConnectorViewModel(_viewModel, sourceDataItem, sinkDataItem, VectorLineDrawMode);
var connector = new ConnectorViewModel(_viewModel, sourceDataItem, sinkDataItem, DrawMode, RouterMode);
_viewModel.AddItemCommand.Execute(connector);
sourceDataItem.DataItem.ZIndex++;

View File

@@ -7,6 +7,7 @@ using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
@@ -26,53 +27,19 @@ namespace AIStudio.Wpf.DiagramDesigner
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
PathGeometry pathGeometry = new PathGeometry();
//if (values[0] != null)
//{
// List<ConnectorPoint> points = (List<ConnectorPoint>)values[0];
if (values[0] != null)
{
List<ConnectorPoint> points = (List<ConnectorPoint>)values[0];
// PathFigure figure = new PathFigure();
// figure.StartPoint = points[0];
// if (values[1]?.ToString() == DrawMode.RadiusConnectingLine.ToString())
// {
// for (var i = 0; i < points.Count - 1; i++)
// {
// int current = i, last = i - 1, next = i + 1, next2 = i + 2;
// if (last == -1)
// {
// last = 0;
// }
// if (next == points.Count)
// {
// next = points.Count - 1;
// }
// if (next2 == points.Count)
// {
// next2 = points.Count - 1;
// }
// var bzs = SegmentHelper.GetBezierSegment(points[current], points[last], points[next], points[next2]);
// figure.Segments.Add(bzs);
// }
// //贝塞尔曲线的简单连接
// //var start = points[0];
// //var end = points.Last();
// //var width = end.X - start.X;
// //var height = end.Y - start.Y;
// //var ctrlPos = 0.382 * width + 0.309 * height;
// //figure.Segments.Add(new BezierSegment(new Point(ctrlPos - 1, 1), new Point(width - ctrlPos + 1, height - 1), new Point(width - 1, height - 1), true));
// }
// else
// {
// for (int i = 0; i < points.Count; i++)
// {
// LineSegment arc = new LineSegment(points[i], true);
// figure.Segments.Add(arc);
// }
// }
// pathGeometry.Figures.Add(figure);
//}
PathFigure figure = new PathFigure();
figure.StartPoint = (PointBase)points[0];
for (int i = 0; i < points.Count; i++)
{
LineSegment arc = new LineSegment((PointBase)points[i], true);
figure.Segments.Add(arc);
}
pathGeometry.Figures.Add(figure);
}
return pathGeometry;
}

View File

@@ -1,16 +1,17 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
[ValueConversion(typeof(List<Point>), typeof(PathSegmentCollection))]
public class ConnectionPathConverter : IValueConverter
public class ConnectionPathConverter : IMultiValueConverter
{
static ConnectionPathConverter()
{
@@ -23,21 +24,22 @@ namespace AIStudio.Wpf.DiagramDesigner
private set;
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
List<ConnectorPoint> points = (List<ConnectorPoint>)value;
PointCollection pointCollection = new PointCollection();
if (points != null)
GeometryGroup geometryGroup = new GeometryGroup();
if (values[0] is PathGeneratorResult result)
{
foreach (var point in points)
foreach (var path in result.Paths)
{
pointCollection.Add(new Point(point.X, point.Y));
PathGeometry pathGeometry = PathGeometry.CreateFromGeometry(Geometry.Parse(path));
geometryGroup.Children.Add(pathGeometry);
}
}
return pointCollection;
return geometryGroup;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace AIStudio.Wpf.DiagramDesigner
{
[ValueConversion(typeof(List<Point>), typeof(PointCollection))]
public class ConnectionPointConverter : IValueConverter
{
static ConnectionPointConverter()
{
Instance = new ConnectionPointConverter();
}
public static ConnectionPointConverter Instance
{
get;
private set;
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
List<Point> points = (List<Point>)value;
PointCollection pointCollection = new PointCollection();
if (points != null)
{
foreach (var point in points)
{
pointCollection.Add(new Point(point.X, point.Y));
}
}
return pointCollection;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -13,10 +13,10 @@ namespace AIStudio.Wpf.DiagramDesigner
Polyline = 4,
Polygon = 5,
DirectLine = 6,
ConnectingLine = 10,
CornerConnectingLine = 11,
BoundaryConnectingLine = 12,
RadiusConnectingLine = 13,
SmoothConnectingLine = 10,
StraightConnectingLine = 11,
CornerConnectingLine = 12,
BoundaryConnectingLine = 13,
Text = 20,
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AIStudio.Wpf.DiagramDesigner
{
public enum RouterMode
{
Normal,
Orthogonal
}
}

View File

@@ -1,6 +1,6 @@
using System;
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
/// <summary>
/// Bezier Spline methods

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
public class EllipseBase : IShape
{

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
public interface IShape
{

View File

@@ -1,4 +1,4 @@
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
public struct LineBase
{
@@ -11,7 +11,7 @@
public PointBase Start { get; }
public PointBase End { get; }
public PointBase GetIntersection(LineBase line)
public PointBase? GetIntersection(LineBase line)
{
var pt1Dir = new PointBase(End.X - Start.X, End.Y - Start.Y);
var pt2Dir = new PointBase(line.End.X - line.Start.X, line.End.Y - line.Start.Y);
@@ -21,18 +21,18 @@
var beta = (deltaPt.X * pt1Dir.Y) - (deltaPt.Y * pt1Dir.X);
if (det == 0 || alpha * det < 0 || beta * det < 0)
return PointBase.Empty;
return null;
if (det > 0)
{
if (alpha > det || beta > det)
return PointBase.Empty;
return null;
}
else
{
if (alpha < det || beta < det)
return PointBase.Empty;
return null;
}
return new PointBase(Start.X + (alpha * pt1Dir.X / det), Start.Y + (alpha * pt1Dir.Y / det));

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Text;
using System.Windows;
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
[Serializable]
public struct PointBase : IFormattable

View File

@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
[Serializable]
public struct RectangleBase : IShape, IFormattable
{
public static RectangleBase Zero { get; } = new RectangleBase(0, 0, 0, 0);
public static RectangleBase Zero { get; } = new RectangleBase(0, 0, 0, 0, true);
public RectangleBase(double left, double top, double right, double bottom, bool lefttoprightbottom)
{
@@ -85,7 +85,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Geometry
}
public RectangleBase InflateRectangle(double horizontal, double vertical)
=> new RectangleBase(Left - horizontal, Top - vertical, Right + horizontal, Bottom + vertical);
=> new RectangleBase(Left - horizontal, Top - vertical, Right + horizontal, Bottom + vertical, true);
public RectangleBase UnionRectangle(RectangleBase r)
{
@@ -93,7 +93,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Geometry
var x2 = Math.Max(Left + Width, r.Left + r.Width);
var y1 = Math.Min(Top, r.Top);
var y2 = Math.Max(Top + Height, r.Top + r.Height);
return new RectangleBase(x1, y1, x2, y2);
return new RectangleBase(x1, y1, x2, y2, true);
}
public bool ContainsPoint(PointBase point) => ContainsPoint(point.X, point.Y);
@@ -114,7 +114,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Geometry
{
var intersectionPt = borders[i].GetIntersection(line);
if (intersectionPt != null)
yield return intersectionPt;
yield return intersectionPt.Value;
}
}

View File

@@ -1,6 +1,6 @@
using AIStudio.Wpf.DiagramDesigner.Models;
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
public delegate IShape ShapeDefiner(DesignerItemViewModelBase node);

View File

@@ -1,7 +1,7 @@
using System;
using System.Windows;
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
[Serializable]
public struct SizeBase : IFormattable

View File

@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace AIStudio.Wpf.DiagramDesigner.Geometry
namespace AIStudio.Wpf.DiagramDesigner.Geometrys
{
[Serializable]
public struct VectorBase : IFormattable

View File

@@ -1,4 +1,4 @@
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
@@ -13,5 +13,17 @@ namespace AIStudio.Wpf.DiagramDesigner
public SizeBase DesignerItemSize { get; set; }
public PointBase Position { get; set; }
public ConnectorOrientation Orientation { get; set; }
public static ConnectorInfo GetConnectorInfo(ConnectorOrientation orientation, double left, double top, double width, double height, PointBase position)
{
return new ConnectorInfo()
{
Orientation = orientation,
DesignerItemSize = new SizeBase(width, height),
DesignerItemLeft = left,
DesignerItemTop = top,
Position = position
};
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace AIStudio.Wpf.DiagramDesigner
{
/// <summary>
///
/// </summary>
public static class GlobalType
{
static GlobalType()
{
string rootPath = System.AppDomain.CurrentDomain.BaseDirectory;
AllAssemblies = Directory.GetFiles(rootPath, "*.dll")
.Where(x => AssemblyPattern.Any(y => new FileInfo(x).Name.Contains(y)))
.Select(x => Assembly.LoadFrom(x))
.Where(x => !x.IsDynamic)
.ToList();
AllAssemblies.ForEach(aAssembly => {
try
{
AllTypes.AddRange(aAssembly.GetTypes());
}
catch
{
}
});
}
/// <summary>
/// 解决方案程序集匹配名
/// </summary>
public static readonly List<string> AssemblyPattern = new List<string> { "AIStudio" };
/// <summary>
/// 解决方案所有程序集
/// </summary>
public static readonly List<Assembly> AllAssemblies;
/// <summary>
/// 解决方案所有自定义类
/// </summary>
public static readonly List<Type> AllTypes = new List<Type>();
}
}

View File

@@ -17,10 +17,33 @@ namespace AIStudio.Wpf.DiagramDesigner
{
}
//public ConnectionItem(Guid id, Guid sourceId, ConnectorOrientation sourceOrientation, Type sourceType, double sourceXRatio, double sourceYRatio, bool sourceInnerPoint,
// Guid sinkId, ConnectorOrientation sinkOrientation, Type sinkType, double sinkXRatio, double sinkYRatio, bool sinkInnerPoint,
// int zIndex, bool isGroup, Guid parentId, DrawMode vectorLineDrawMode, ColorViewModel colorViewModel, FontViewModel fontViewModel) : base(id, zIndex, isGroup, parentId, colorViewModel, fontViewModel)
public ConnectionItem(ConnectorViewModel viewmodel) : base(viewmodel)
{
this.SourceId = viewmodel.SourceConnectorInfo.DataItem.Id;
this.SourceOrientation = viewmodel.SourceConnectorInfo.Orientation;
this.SourceType = viewmodel.SourceConnectorInfo.DataItem.GetType();
this.SourceTypeName = viewmodel.SourceConnectorInfo.DataItem.GetType().FullName;
this.SourceXRatio = viewmodel.SourceConnectorInfo.GetXRatioFromConnector();
this.SourceYRatio = viewmodel.SourceConnectorInfo.GetYRatioFromConnector();
this.SourceInnerPoint = viewmodel.SourceConnectorInfo.IsInnerPoint;
this.SinkId = viewmodel.SinkConnectorInfoFully.DataItem.Id;
this.SinkOrientation = viewmodel.SinkConnectorInfoFully.Orientation;
this.SinkType = viewmodel.SinkConnectorInfoFully.DataItem.GetType();
this.SinkTypeName = viewmodel.SinkConnectorInfoFully.DataItem.GetType().FullName;
this.SinkXRatio = viewmodel.SinkConnectorInfoFully.GetXRatioFromConnector();
this.SinkYRatio = viewmodel.SinkConnectorInfoFully.GetYRatioFromConnector();
this.SinkInnerPoint = viewmodel.SinkConnectorInfoFully.IsInnerPoint;
this.RouterMode = viewmodel.RouterMode;
this.PathMode = viewmodel.PathMode;
}
//public ConnectionItem(Guid sourceId, ConnectorOrientation sourceOrientation, Type sourceType, double sourceXRatio, double sourceYRatio, bool sourceInnerPoint,
// Guid sinkId, ConnectorOrientation sinkOrientation, Type sinkType, double sinkXRatio, double sinkYRatio, bool sinkInnerPoint, ConnectorViewModel viewmodel) : base(viewmodel)
//{
// this.SourceId = sourceId;
// this.SourceOrientation = sourceOrientation;
// this.SourceType = sourceType;
@@ -31,35 +54,15 @@ namespace AIStudio.Wpf.DiagramDesigner
// this.SinkId = sinkId;
// this.SinkOrientation = sinkOrientation;
// this.SinkType = sinkType;
// this.SinkType = sinkType;
// this.SinkTypeName = sinkType.FullName;
// this.SinkXRatio = sinkXRatio;
// this.SinkYRatio = sinkYRatio;
// this.SinkInnerPoint = sinkInnerPoint;
// this.VectorLineDrawMode = vectorLineDrawMode;
// this.RouterMode = viewmodel.RouterMode;
// this.DrawMode = viewmodel.DrawMode;
//}
public ConnectionItem(Guid sourceId, ConnectorOrientation sourceOrientation, Type sourceType, double sourceXRatio, double sourceYRatio, bool sourceInnerPoint,
Guid sinkId, ConnectorOrientation sinkOrientation, Type sinkType, double sinkXRatio, double sinkYRatio, bool sinkInnerPoint, ConnectorViewModel viewmodel) : base(viewmodel)
{
this.SourceId = sourceId;
this.SourceOrientation = sourceOrientation;
this.SourceType = sourceType;
this.SourceTypeName = sourceType.FullName;
this.SourceXRatio = sourceXRatio;
this.SourceYRatio = sourceYRatio;
this.SourceInnerPoint = sourceInnerPoint;
this.SinkId = sinkId;
this.SinkOrientation = sinkOrientation;
this.SinkType = sinkType;
this.SinkTypeName = sinkType.FullName;
this.SinkXRatio = sinkXRatio;
this.SinkYRatio = sinkYRatio;
this.SinkInnerPoint = sinkInnerPoint;
this.VectorLineDrawMode = viewmodel.VectorLineDrawMode;
}
[XmlAttribute]
public Guid SourceId { get; set; }
@@ -103,6 +106,15 @@ namespace AIStudio.Wpf.DiagramDesigner
public bool SinkInnerPoint { get; set; }
[XmlAttribute]
public DrawMode VectorLineDrawMode { get; set; }
public string RouterMode
{
get; set;
}
[XmlAttribute]
public string PathMode
{
get; set;
}
}
}

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Windows;
namespace AIStudio.Wpf.DiagramDesigner.Helpers
namespace AIStudio.Wpf.DiagramDesigner
{
public class ToolBoxData
{

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Windows.Controls;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public interface IPathGenerator
{
PathGeneratorResult Get(IDiagramViewModel _, ConnectorViewModel link, PointBase[] route, PointBase source, PointBase target);
}
}

View File

@@ -1,4 +1,4 @@
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -1,5 +1,6 @@
using System;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using System.Linq;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
@@ -19,7 +20,9 @@ namespace AIStudio.Wpf.DiagramDesigner
double? targetAngle = null;
sourceAngle = SourceMarkerAdjustement(route, (double)link.ColorViewModel.LeftArrowSizeStyle);
targetAngle = TargetMarkerAdjustement(route, (double)link.ColorViewModel.RightArrowPathStyle);
targetAngle = TargetMarkerAdjustement(route, (double)link.ColorViewModel.RightArrowPathStyle);
DoShift(route, link);
var path = FormattableString.Invariant($"M {route[0].X} {route[0].Y} C {route[1].X} {route[1].Y}, {route[2].X} {route[2].Y}, {route[3].X} {route[3].Y}");
return new PathGeneratorResult(new[] { path }, sourceAngle, route[0], targetAngle, route[route.Length - 1]);
@@ -33,7 +36,7 @@ namespace AIStudio.Wpf.DiagramDesigner
sourceAngle = SourceMarkerAdjustement(route, (double)link.ColorViewModel.LeftArrowSizeStyle);
targetAngle = TargetMarkerAdjustement(route, (double)link.ColorViewModel.RightArrowPathStyle);
Geometry.BezierSpline.GetCurveControlPoints(route, out var firstControlPoints, out var secondControlPoints);
BezierSpline.GetCurveControlPoints(route, out var firstControlPoints, out var secondControlPoints);
var paths = new string[firstControlPoints.Length];
for (var i = 0; i < firstControlPoints.Length; i++)
@@ -88,5 +91,7 @@ namespace AIStudio.Wpf.DiagramDesigner
default: return new PointBase(cX, cY);
};
}
}
}

View File

@@ -1,5 +1,5 @@
using System;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
@@ -14,6 +14,8 @@ namespace AIStudio.Wpf.DiagramDesigner
sourceAngle = SourceMarkerAdjustement(route, (double)link.ColorViewModel.LeftArrowSizeStyle);
targetAngle = TargetMarkerAdjustement(route, (double)link.ColorViewModel.RightArrowPathStyle);
DoShift(route, link);
var paths = new string[route.Length - 1];
for (var i = 0; i < route.Length - 1; i++)
{
@@ -21,6 +23,6 @@ namespace AIStudio.Wpf.DiagramDesigner
}
return new PathGeneratorResult(paths, sourceAngle, route[0], targetAngle, route[route.Length - 1]);
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using System.Linq;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
@@ -28,8 +29,20 @@ namespace AIStudio.Wpf.DiagramDesigner
var result = new PointBase[route.Length + 2];
result[0] = source;
route.CopyTo(result, 1);
result[route.Length - 1] = target;
result[result.Length - 1] = target;
return result;
}
private static void DoShift(PointBase[] points, ConnectorViewModel link)
{
double left = link.Area.Left;
double top = link.Area.Top;
for (int i = 0; i < points.Length; i++)
{
points[i].X = points[i].X - left;
points[i].Y = points[i].Y - top;
}
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public class SmoothPathGenerator : IPathGenerator
{
public PathGeneratorResult Get(IDiagramViewModel _, ConnectorViewModel link, PointBase[] route, PointBase source, PointBase target)
{
return PathGenerators.Smooth(_, link, route, source, target);
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public class StraightPathGenerator : IPathGenerator
{
public PathGeneratorResult Get(IDiagramViewModel _, ConnectorViewModel link, PointBase[] route, PointBase source, PointBase target)
{
return PathGenerators.Straight(_, link, route, source, target);
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public interface IRouter
{
PointBase[] Get(IDiagramViewModel _, ConnectorViewModel link);
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public class NormalRouter : IRouter
{
public PointBase[] Get(IDiagramViewModel _, ConnectorViewModel link)
{
return Routers.Normal(_, link);
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public class OrthogonalRouter : IRouter
{
public PointBase[] Get(IDiagramViewModel _, ConnectorViewModel link)
{
return Routers.Orthogonal(_, link);
}
}
}

View File

@@ -1,5 +1,5 @@
using System.Linq;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
// Implementation taken from the JS version: https://gist.github.com/menendezpoo/4a8894c152383b9d7a870c24a04447e4
// Todo: Make it more c#, Benchmark A* vs Dijkstra, Add more options
@@ -122,12 +122,12 @@ namespace AIStudio.Wpf.DiagramDesigner
{
foreach (var x in verticals)
{
result.Set(row, column++, new RectangleBase(lastX, lastY, x, y));
result.Set(row, column++, new RectangleBase(lastX, lastY, x, y, true));
lastX = x;
}
// Last cell of the row
result.Set(row, column, new RectangleBase(lastX, lastY, bounds.Right, y));
result.Set(row, column, new RectangleBase(lastX, lastY, bounds.Right, y, true));
lastX = bounds.Left;
lastY = y;
column = 0;
@@ -139,12 +139,12 @@ namespace AIStudio.Wpf.DiagramDesigner
// Last fow of cells
foreach (var x in verticals)
{
result.Set(row, column++, new RectangleBase(lastX, lastY, x, bounds.Bottom));
result.Set(row, column++, new RectangleBase(lastX, lastY, x, bounds.Bottom, true));
lastX = x;
}
// Last cell of last row
result.Set(row, column, new RectangleBase(lastX, lastY, bounds.Right, bounds.Bottom));
result.Set(row, column, new RectangleBase(lastX, lastY, bounds.Right, bounds.Bottom, true));
return result;
}

View File

@@ -1,4 +1,4 @@
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Models;
namespace AIStudio.Wpf.DiagramDesigner
@@ -7,7 +7,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
public static PointBase GetPortPositionBasedOnAlignment(ConnectorInfoBase port)
{
var pt = port.Position;
var pt = port.Location.Position;
switch (port.Orientation)
{
case ConnectorOrientation.Top:

View File

@@ -78,7 +78,7 @@
<Setter.Value>
<ControlTemplate>
<Polyline
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPathConverter.Instance}}"
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPointConverter.Instance}}"
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
StrokeThickness="{Binding ColorViewModel.LineWidth}"
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
@@ -93,7 +93,7 @@
<Setter.Value>
<ControlTemplate>
<Polygon
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPathConverter.Instance}}"
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPointConverter.Instance}}"
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
StrokeThickness="{Binding ColorViewModel.LineWidth}"
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
@@ -108,7 +108,7 @@
<Setter.Value>
<ControlTemplate>
<Polyline
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPathConverter.Instance}}"
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPointConverter.Instance}}"
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
StrokeThickness="{Binding ColorViewModel.LineWidth}"
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"

View File

@@ -540,21 +540,20 @@
<Canvas.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding EditCommand}" CommandParameter="{Binding }" />
</Canvas.InputBindings>
<Polyline x:Name="poly"
Points="{Binding Path=ConnectionPoints, Converter={x:Static s:ConnectionPathConverter.Instance}}"
<!--<Polyline x:Name="poly"
Points="{Binding Path=ConnectionPoints, Converter={x:Static s:ConnectionPointConverter.Instance}}"
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
StrokeThickness="{Binding ColorViewModel.LineWidth}"
StrokeDashArray="{Binding ColorViewModel.LineDashStyle,Converter={StaticResource LineDashConverter}}" />
<!--<Path x:Name="poly" Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
StrokeDashArray="{Binding ColorViewModel.LineDashStyle,Converter={StaticResource LineDashConverter}}" />-->
<Path x:Name="poly" Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
StrokeThickness="{Binding ColorViewModel.LineWidth}"
StrokeDashArray="{Binding ColorViewModel.LineDashStyle,Converter={StaticResource LineDashConverter}}">
<Path.Data>
<MultiBinding Converter="{x:Static s:ConnectionDataConverter.Instance}">
<Binding Path="ConnectionPoints"/>
<Binding Path="VectorLineDrawMode"/>
<MultiBinding Converter="{x:Static s:ConnectionPathConverter.Instance}">
<Binding Path="PathGeneratorResult"/>
</MultiBinding>
</Path.Data>
</Path>-->
</Path>
<Path x:Name="rightarrow"
Data="{Binding ColorViewModel.RightArrowPathStyle,Converter={StaticResource ArrowPathConverter}}"
Visibility="{Binding Path=IsFullConnection, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"

View File

@@ -12,9 +12,9 @@ namespace AIStudio.Wpf.DiagramDesigner
{
return CursorDrawMode;
}
else if (VectorLineDrawModeSelected)
else if (LineDrawModeSelected)
{
return VectorLineDrawMode;
return LineDrawMode;
}
else if (ShapeDrawModeSelected)
{
@@ -52,16 +52,29 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private bool _vectorLineDrawModeSelected;
public bool VectorLineDrawModeSelected
private bool _lineDrawModeSelected;
public bool LineDrawModeSelected
{
get
{
return _vectorLineDrawModeSelected;
return _lineDrawModeSelected;
}
set
{
SetProperty(ref _vectorLineDrawModeSelected, value);
SetProperty(ref _lineDrawModeSelected, value);
}
}
private bool _vectorRouterModeSelected;
public bool LineRouterModeSelected
{
get
{
return _vectorRouterModeSelected;
}
set
{
SetProperty(ref _vectorRouterModeSelected, value);
}
}
@@ -105,17 +118,30 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private DrawMode _vectorLineDrawMode = DrawMode.CornerConnectingLine;
public DrawMode VectorLineDrawMode
private DrawMode _lineDrawMode = DrawMode.CornerConnectingLine;
public DrawMode LineDrawMode
{
get
{
return _vectorLineDrawMode;
return _lineDrawMode;
}
set
{
SetProperty(ref _vectorLineDrawMode, value);
VectorLineDrawModeSelected = true;
SetProperty(ref _lineDrawMode, value);
LineDrawModeSelected = true;
}
}
private RouterMode _lineRouterMode = RouterMode.Normal;
public RouterMode LineRouterMode
{
get
{
return _lineRouterMode;
}
set
{
SetProperty(ref _lineRouterMode, value);
}
}

View File

@@ -11,7 +11,19 @@ namespace AIStudio.Wpf.DiagramDesigner
void ResetDrawMode();
CursorMode CursorMode { get; set; }
DrawMode VectorLineDrawMode { get; set; }
CursorMode CursorMode
{
get; set;
}
DrawMode LineDrawMode
{
get; set;
}
RouterMode LineRouterMode
{
get; set;
}
}
}

View File

@@ -4,13 +4,13 @@ using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public abstract class ConnectorInfoBase : BindableBase
{
public virtual PointBase Position
public virtual ConnectorPoint Location
{
get;
}

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -4,51 +4,62 @@ using System.ComponentModel;
using System.Linq;
//using System.Windows;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Helpers;
namespace AIStudio.Wpf.DiagramDesigner
{
public class ConnectorViewModel : SelectableDesignerItemViewModelBase
{
public ConnectorViewModel(IDiagramViewModel parent, FullyCreatedConnectorInfo sourceConnectorInfo, FullyCreatedConnectorInfo sinkConnectorInfo,
SelectableDesignerItemBase designer, DrawMode vectorLineDrawMode) : base(parent, designer)
{
VectorLineDrawMode = vectorLineDrawMode;
Init(sourceConnectorInfo, sinkConnectorInfo);
}
public ConnectorViewModel(IDiagramViewModel parent, FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode vectorLineDrawMode)
public ConnectorViewModel(IDiagramViewModel parent, FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode drawMode, RouterMode routerMode)
{
Parent = parent;
VectorLineDrawMode = vectorLineDrawMode;
PathMode = drawMode.ToString().Replace("ConnectingLine","");
RouterMode = routerMode.ToString();
Init(sourceConnectorInfo, sinkConnectorInfo);
}
public ConnectorViewModel( FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode vectorLineDrawMode):this(null, sourceConnectorInfo, sinkConnectorInfo, vectorLineDrawMode)
public ConnectorViewModel(IDiagramViewModel parent, FullyCreatedConnectorInfo sourceConnectorInfo, FullyCreatedConnectorInfo sinkConnectorInfo, ConnectionItem designer) : base(parent, designer)
{
PathMode = designer.PathMode;
RouterMode = designer.RouterMode;
Init(sourceConnectorInfo, sinkConnectorInfo);
}
public ConnectorViewModel(FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo, DrawMode drawMode, RouterMode routerMode) :this(null, sourceConnectorInfo, sinkConnectorInfo, drawMode, routerMode)
{
}
private void Init(FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo)
{
this.Parent = sourceConnectorInfo.DataItem.Parent;
var routetype = GlobalType.AllTypes.Where(p => typeof(IRouter).IsAssignableFrom(p)).FirstOrDefault(p => p.Name == RouterMode);
Router = routetype != null ? (System.Activator.CreateInstance(routetype) as IRouter) : new NormalRouter();
var pathGeneratortype = GlobalType.AllTypes.Where(p => typeof(IPathGenerator).IsAssignableFrom(p)).FirstOrDefault(p => p.Name == PathMode);
PathGenerator = pathGeneratortype != null ? (System.Activator.CreateInstance(pathGeneratortype) as IPathGenerator) : new SmoothPathGenerator();
this.SourceConnectorInfo = sourceConnectorInfo;
this.SinkConnectorInfo = sinkConnectorInfo;
DeleteConnectionCommand = new SimpleCommand(DeleteConnection);
if (Parent != null && Parent.ColorViewModel != null)
{
this.ColorViewModel = CopyHelper.Mapper(Parent.ColorViewModel);
}
if (sinkConnectorInfo is FullyCreatedConnectorInfo sink && sink.DataItem.ShowArrow == false)
{
this.ColorViewModel.RightArrowPathStyle = ArrowPathStyle.None;
}
}
public override SelectableDesignerItemBase ToXmlObject()
{
if (IsFullConnection)
{
ConnectionItem connection = new ConnectionItem(
SourceConnectorInfo.DataItem.Id,
SourceConnectorInfo.Orientation,
SourceConnectorInfo.DataItem.GetType(),
GetXRatioFromConnector(SourceConnectorInfo),
GetYRatioFromConnector(SourceConnectorInfo),
SourceConnectorInfo.IsInnerPoint,
SinkConnectorInfoFully.DataItem.Id,
SinkConnectorInfoFully.Orientation,
SinkConnectorInfoFully.DataItem.GetType(),
GetXRatioFromConnector(SinkConnectorInfoFully),
GetYRatioFromConnector(SinkConnectorInfoFully),
SinkConnectorInfoFully.IsInnerPoint,
this);
ConnectionItem connection = new ConnectionItem(this);
return connection;
}
@@ -61,12 +72,7 @@ namespace AIStudio.Wpf.DiagramDesigner
public override Type ToXmlType()
{
return typeof(ConnectionItem);
}
public IPathFinder PathFinder
{
get; set;
}
}
private PointBase _sourceA;
public PointBase SourceA
@@ -165,11 +171,39 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
public DrawMode VectorLineDrawMode
public string PathMode
{
get; set;
}
public string RouterMode
{
get; set;
}
public IRouter Router
{
get; set;
}
public IPathGenerator PathGenerator
{
get; set;
}
private PathGeneratorResult _pathGeneratorResult;
public PathGeneratorResult PathGeneratorResult
{
get
{
return _pathGeneratorResult;
}
private set
{
SetProperty(ref _pathGeneratorResult, value);
}
}
//待完善这两处
public List<LinkVertexModel> Vertices { get; } = new List<LinkVertexModel>();
public List<LinkLabelModel> Labels { get; set; } = new List<LinkLabelModel>();
@@ -185,20 +219,6 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
public ConnectorInfo ConnectorInfo(ConnectorOrientation orientation, double left, double top, double width, double height, PointBase position)
{
return new ConnectorInfo()
{
Orientation = orientation,
DesignerItemSize = new SizeBase(width, height),
DesignerItemLeft = left,
DesignerItemTop = top,
Position = position
};
}
private FullyCreatedConnectorInfo _sourceConnectorInfo;
public FullyCreatedConnectorInfo SourceConnectorInfo
{
@@ -227,15 +247,11 @@ namespace AIStudio.Wpf.DiagramDesigner
{
if (SetProperty(ref _sinkConnectorInfo, value))
{
SourceB = _sinkConnectorInfo.Location;
if (_sinkConnectorInfo is FullyCreatedConnectorInfo)
{
SourceB = PointHelper.GetPointForConnector((FullyCreatedConnectorInfo)_sinkConnectorInfo);
{
(((FullyCreatedConnectorInfo)_sinkConnectorInfo).DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
}
else
{
SourceB = SinkConnectorInfoPart.Position;
}
}
}
}
@@ -256,11 +272,11 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
public ConnectorPoint OnGoingPosition
public PointBase OnGoingPosition
{
get
{
return SinkConnectorInfoPart?.Position;
return SinkConnectorInfoPart?.Location?.MiddlePosition ?? PointBase.Zero;
}
}
@@ -274,52 +290,6 @@ namespace AIStudio.Wpf.DiagramDesigner
public bool IsPortless => SourceConnectorInfo?.DataItem?.Connectors?.Count() == 0;
public double GetXRatioFromConnector(FullyCreatedConnectorInfo info)
{
if (info.IsInnerPoint)
{
return info.XRatio;
}
else
{
switch (info.Orientation)
{
case ConnectorOrientation.Top:
return 0.5;
case ConnectorOrientation.Left:
return 0;
case ConnectorOrientation.Bottom:
return 0.5;
case ConnectorOrientation.Right:
return 1;
default: return info.XRatio;
}
}
}
public double GetYRatioFromConnector(FullyCreatedConnectorInfo info)
{
if (info.IsInnerPoint)
{
return info.YRatio;
}
else
{
switch (info.Orientation)
{
case ConnectorOrientation.Top:
return 0;
case ConnectorOrientation.Left:
return 0.5;
case ConnectorOrientation.Bottom:
return 1;
case ConnectorOrientation.Right:
return 0.5;
default: return info.YRatio;
}
}
}
private void UpdateArea()
{
Area = new RectangleBase(SourceA, SourceB);
@@ -327,13 +297,17 @@ namespace AIStudio.Wpf.DiagramDesigner
private void UpdateConnectionPoints()
{
ConnectionPoints = PathFinder.UpdateConnectionPoints(Parent, SourceA, SourceB, SourceConnectorInfo, SinkConnectorInfo);
StartPoint = ConnectionPoints.First();
EndPoint = ConnectionPoints.Last();
//ConnectionPoints = PathFinder.UpdateConnectionPoints(Parent, SourceA, SourceB, SourceConnectorInfo, SinkConnectorInfo);
//StartPoint = ConnectionPoints.First();
//EndPoint = ConnectionPoints.Last();
//var router = Routers.Normal(Parent, this);
//var pathGenerator = PathGenerators.Smooth(Parent, this, router, SourceA, SourceB);
var route = Router.Get(Parent, this);
(var source, var target) = FindConnectionPoints(route);
if (source == null || target == null)
return;
PathGeneratorResult = PathGenerator.Get(Parent, this, route, source.Value, target.Value);
}
private void ConnectorViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
@@ -364,36 +338,7 @@ namespace AIStudio.Wpf.DiagramDesigner
break;
}
}
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;
DeleteConnectionCommand = new SimpleCommand(DeleteConnection);
if (Parent != null && Parent.ColorViewModel != null)
{
this.ColorViewModel = CopyHelper.Mapper(Parent.ColorViewModel);
}
if (sinkConnectorInfo is FullyCreatedConnectorInfo sink && sink.DataItem.ShowArrow == false)
{
this.ColorViewModel.RightArrowPathStyle = ArrowPathStyle.None;
}
}
}
public SimpleCommand DeleteConnectionCommand
{
@@ -461,34 +406,82 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
//private (PointInfoBase source, PointInfoBase target) FindConnectionPoints(PointInfoBase[] route)
//{
// if (IsPortless) // Portless
// {
// if (SourceConnectorInfo.DataItem == null || (IsFullConnection && SinkConnectorInfoFully.DataItem == null))
// return (null, null);
private (PointBase? source, PointBase? target) FindConnectionPoints(PointBase[] route)
{
if (IsPortless) // Portless
{
if (SourceConnectorInfo.DataItem == null || (IsFullConnection && SinkConnectorInfoFully.DataItem == null))
return (null, null);
var sourceCenter = SourceConnectorInfo.DataItem.GetBounds().Center;
var targetCenter = SinkConnectorInfoFully?.DataItem?.GetBounds().Center ?? 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 sourceIntersection = GetClosestPointTo(sourceIntersections, firstPt);
var targetIntersection = GetClosestPointTo(targetIntersections, secondPt);
return (sourceIntersection ?? sourceCenter, targetIntersection ?? targetCenter);
}
else
{
var source = GetPortPositionBasedOnAlignment(SourceConnectorInfo, ColorViewModel.LeftArrowSizeStyle);
var target = GetPortPositionBasedOnAlignment(SinkConnectorInfoFully, ColorViewModel.RightArrowSizeStyle);
return (source, target ?? OnGoingPosition);
}
}
private PointBase? GetPortPositionBasedOnAlignment(ConnectorInfoBase port, ArrowSizeStyle marker)
{
if (port == null)
return null;
if (marker == null)
return port.Location.MiddlePosition;
var pt = port.Location.Position;
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;
}
// var sourceCenter = SourceConnectorInfo.DataItem.GetBounds().Center;
// var targetCenter = SinkConnectorInfoFully?.DataItem?.GetBounds().Center ?? SinkConnectorInfoFully.Position;
// var firstPt = route.Length > 0 ? route[0] : targetCenter;
// var secondPt = route.Length > 0 ? route[0] : sourceCenter;
// var sourceLine = new Line(firstPt, sourceCenter);
// var targetLine = new Line(secondPt, targetCenter);
// var sourceIntersections = Link.SourceNode.GetShape().GetIntersectionsWithLine(sourceLine);
// var targetIntersections = Link.TargetNode.GetShape().GetIntersectionsWithLine(targetLine);
// var sourceIntersection = GetClosestPointTo(sourceIntersections, firstPt);
// var targetIntersection = GetClosestPointTo(targetIntersections, secondPt);
// return (sourceIntersection ?? sourceCenter, targetIntersection ?? targetCenter);
// }
// else
// {
// if (!Link.SourcePort.Initialized || Link.TargetPort?.Initialized == false)
// return (null, null);
// var source = GetPortPositionBasedOnAlignment(Link.SourcePort, Link.SourceMarker);
// var target = GetPortPositionBasedOnAlignment(Link.TargetPort, Link.TargetMarker);
// return (source, target ?? Link.OnGoingPosition);
// }
//}
}
}

View File

@@ -7,7 +7,7 @@ using System.Windows;
using System.Linq;
using System.Reactive.Linq;
using AIStudio.Wpf.DiagramDesigner.Models;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
@@ -15,14 +15,17 @@ namespace AIStudio.Wpf.DiagramDesigner
{
public DesignerItemViewModelBase() : base()
{
ShapeDefiner = Shapes.Rectangle;
}
public DesignerItemViewModelBase(IDiagramViewModel parent, DesignerItemBase designer) : base(parent, designer)
{
ShapeDefiner = Shapes.Rectangle;
}
public DesignerItemViewModelBase(IDiagramViewModel parent, string json) : base(parent, json)
{
ShapeDefiner = Shapes.Rectangle;
}
protected override void Init()
@@ -415,21 +418,23 @@ namespace AIStudio.Wpf.DiagramDesigner
public RectangleBase GetBounds(bool includePorts = false)
{
if (!includePorts)
return new RectangleBase(Left, Top, ItemWidth, ItemHeight);
return new RectangleBase(Position, Size);
var leftPort = LeftConnector;
var topPort = TopConnector;
var rightPort = RightConnector;
var bottomPort = BottomConnector;
var left = leftPort == null ? Left: Math.Min(Left, leftPort.Position.X);
var top = topPort == null ? Top : Math.Min(Left, topPort.Position.Y);
var right = rightPort == null ? Left + ItemWidth :
Math.Max(rightPort.Position.X + rightPort.ConnectorWidth, Left + ItemWidth);
var bottom = bottomPort == null ? Top + ItemHeight :
Math.Max(bottomPort.Position.Y + bottomPort.ConnectorHeight, Top + ItemHeight);
var left = leftPort == null ? Position.X: Math.Min(Position.X, leftPort.Location.Position.X);
var top = topPort == null ? Position.Y : Math.Min(Position.Y, topPort.Location.Position.Y);
var right = rightPort == null ? Position.X + ItemWidth :
Math.Max(rightPort.Location.Position.X + rightPort.ConnectorWidth, Position.X + ItemWidth);
var bottom = bottomPort == null ? Position.Y + ItemHeight :
Math.Max(bottomPort.Location.Position.Y + bottomPort.ConnectorHeight, Position.Y + ItemHeight);
return new RectangleBase(left, top, right, bottom);
return new RectangleBase(left, top, right, bottom, true);
}
public IShape GetShape() => ShapeDefiner(this);
}
}

View File

@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Helpers;
using AIStudio.Wpf.DiagramDesigner.Models;
using Newtonsoft.Json;
@@ -1489,7 +1489,7 @@ namespace AIStudio.Wpf.DiagramDesigner
ConnectorOrientation sinkConnectorOrientation = connectionItem.SinkOrientation;
FullyCreatedConnectorInfo sinkConnectorInfo = GetFullConnectorInfo(connectionItem.Id, sinkItem, sinkConnectorOrientation, connectionItem.SinkXRatio, connectionItem.SinkYRatio, connectionItem.SinkInnerPoint);
ConnectorViewModel connectionVM = new ConnectorViewModel(this, sourceConnectorInfo, sinkConnectorInfo, connectionItem, connectionItem.VectorLineDrawMode);
ConnectorViewModel connectionVM = new ConnectorViewModel(this, sourceConnectorInfo, sinkConnectorInfo, connectionItem);
connectors.Add(connectionVM);
DesignerItemViewModelBase textItem = items.OfType<DesignerItemViewModelBase>().FirstOrDefault(x => x.ParentId == connectionItem.Id);

View File

@@ -3,13 +3,13 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public class FullyCreatedConnectorInfo : ConnectorInfoBase
{
public override PointBase Position
public override ConnectorPoint Location
{
get
{
@@ -152,6 +152,52 @@ namespace AIStudio.Wpf.DiagramDesigner
return menuOptions;
}
}
public double GetXRatioFromConnector()
{
if (IsInnerPoint)
{
return XRatio;
}
else
{
switch (Orientation)
{
case ConnectorOrientation.Top:
return 0.5;
case ConnectorOrientation.Left:
return 0;
case ConnectorOrientation.Bottom:
return 0.5;
case ConnectorOrientation.Right:
return 1;
default: return XRatio;
}
}
}
public double GetYRatioFromConnector()
{
if (IsInnerPoint)
{
return YRatio;
}
else
{
switch (Orientation)
{
case ConnectorOrientation.Top:
return 0;
case ConnectorOrientation.Left:
return 0.5;
case ConnectorOrientation.Bottom:
return 1;
case ConnectorOrientation.Right:
return 0.5;
default: return YRatio;
}
}
}
}

View File

@@ -1,4 +1,4 @@
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{

View File

@@ -3,24 +3,24 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using AIStudio.Wpf.DiagramDesigner.Geometry;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public class PartCreatedConnectionInfo : ConnectorInfoBase
{
private PointBase position;
public override PointBase Position
private ConnectorPoint location;
public override ConnectorPoint Location
{
get
{
return position;
return location;
}
}
public PartCreatedConnectionInfo(double X, double Y) : base(ConnectorOrientation.None)
{
this.position = new PointBase(X, Y);
this.location = new ConnectorPoint(X, Y);
}
}
}