using Serein.Library; using Serein.Library.Api; using Serein.Workbench.Extension; using Serein.Workbench.Tool; using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; using Color = System.Windows.Media.Color; using ColorConverter = System.Windows.Media.ColorConverter; using Point = System.Windows.Point; namespace Serein.Workbench.Node.View { #region 连接点相关代码 public class ConnectionModelBase { /// /// 起始节点 /// public IFlowNode StartNode { get; set; } /// /// 目标节点 /// public IFlowNode EndNode { get; set; } /// /// 来源于起始节点的(控制点)类型 /// public JunctionType JoinTypeOfStart { get; set; } /// /// 连接到目标节点的(控制点)类型 /// public JunctionType JoinTypeOfEnd { get; set; } /// /// 连接类型 /// public ConnectionInvokeType Type { get; set; } } public interface IJunctionNode { string BoundNodeGuid { get; } } /// /// 连接点 /// public class JunctionNode : IJunctionNode { /// /// 连接点类型 /// public JunctionType JunctionType { get; } /// /// 对应的视图对象 /// public IFlowNode NodeModel { get; set; } /// /// /// public string BoundNodeGuid { get => NodeModel.Guid; } } #endregion /// /// 连接控件,表示控件的连接关系 /// public class ConnectionControl { /// /// 所在的画布 /// public Canvas Canvas { get; } /// /// 调用方法类型,连接类型 /// public ConnectionInvokeType InvokeType { get; } /// /// 目标节点控制点 /// private INodeJunction EndNode; /// /// 获取参数类型,第几个参数 /// public int ArgIndex { get; set; } = -1; /// /// 参数来源(决定了连接线的样式) /// public ConnectionArgSourceType ArgSourceType { get; set; } /// /// 起始控制点 /// public JunctionControlBase Start { get; set; } /// /// 目标控制点 /// public JunctionControlBase End { get; set; } /// /// 连接线 /// private ConnectionLineShape BezierLine; private LineType LineType; /// /// 关于调用 /// /// /// public ConnectionControl(Canvas Canvas, ConnectionInvokeType invokeType, JunctionControlBase Start, JunctionControlBase End) { this.LineType = LineType.Bezier; this.Canvas = Canvas; this.InvokeType = invokeType; this.Start = Start; this.End = End; InitElementPoint(); } /// /// 关于入参 /// /// /// public ConnectionControl(LineType LineType, Canvas Canvas, int argIndex, ConnectionArgSourceType argSourceType, JunctionControlBase Start, JunctionControlBase End, INodeJunction nodeJunction) { this.LineType = LineType; this.Canvas = Canvas; this.ArgIndex = argIndex; this.ArgSourceType = argSourceType; this.Start = Start; this.End = End; this.EndNode = nodeJunction; InitElementPoint(); } /// /// 绘制 /// public void InitElementPoint() { leftCenterOfEndLocation = Start.MyCenterPoint; rightCenterOfStartLocation = End.MyCenterPoint; (Point startPoint, Point endPoint) = RefreshPoint(Canvas, Start, End); var connectionType = Start.JunctionType.ToConnectyionType(); bool isDotted; Brush brush; if(connectionType == JunctionOfConnectionType.Invoke) { brush = InvokeType.ToLineColor(); isDotted = false; } else { brush = ArgSourceType.ToLineColor(); isDotted = true; // 如果为参数,则绘制虚线 } BezierLine = new ConnectionLineShape(LineType, startPoint, endPoint, brush, isDotted); Grid.SetZIndex(BezierLine, -9999999); // 置底 Canvas.Children.Add(BezierLine); ConfigureLineContextMenu(); //配置右键菜单 } /// /// 配置连接曲线的右键菜单 /// private void ConfigureLineContextMenu() { var contextMenu = new ContextMenu(); contextMenu.Items.Add(WpfFuncTool.CreateMenuItem("删除连线", (s, e) => Remote())); contextMenu.Items.Add(WpfFuncTool.CreateMenuItem("于父节点调用顺序中置顶", (s, e) => Topping())); BezierLine.ContextMenu = contextMenu; } /// /// 删除该连线 /// public void Remote() { Canvas.Children.Remove(BezierLine); var env = Start.MyNode.Env; var canvasGuid = Start.MyNode.CanvasDetails.Guid; var jct = Start.JunctionType.ToConnectyionType(); var jctEnd = End.JunctionType.ToConnectyionType(); if (jct == JunctionOfConnectionType.Invoke) { env.RemoveInvokeConnect(canvasGuid, Start.MyNode.Guid, End.MyNode.Guid, InvokeType); } else if (jct == JunctionOfConnectionType.Arg) { env.RemoveArgSourceConnect(canvasGuid,Start.MyNode.Guid, End.MyNode.Guid, ArgIndex) ; } } /// /// 置顶调用关系 /// public void Topping() { var env = Start.MyNode.Env; if (Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke) { env.SetConnectPriorityInvoke(Start.MyNode.Guid, End.MyNode.Guid, InvokeType); } } /// /// 重新绘制 /// public void RefreshLine() { if(ArgIndex > -1) { End = EndNode.GetJunctionOfArgData(ArgIndex) ?? End; } (Point startPoint, Point endPoint) = RefreshPoint(Canvas, Start, End); BezierLine.UpdatePoints(startPoint, endPoint); } private Point rightCenterOfStartLocation; // 目标节点选择左侧边缘中心 private Point leftCenterOfEndLocation; // 起始节点选择右侧边缘中心 /// /// 刷新坐标 /// private (Point startPoint, Point endPoint) RefreshPoint(Canvas canvas, FrameworkElement startElement, FrameworkElement endElement) { var startPoint = startElement.TranslatePoint(rightCenterOfStartLocation, canvas); // 获取起始节点的中心位置 var endPoint = endElement.TranslatePoint(leftCenterOfEndLocation, canvas); // 计算终点位置 return (startPoint, endPoint); } } }