using Serein.Library;
using Serein.Library.Api;
using Serein.Workbench.Api;
using Serein.Workbench.Extension;
using Serein.Workbench.Tool;
using Serein.Workbench.ViewModels;
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; }
///
/// 连接线
///
public ConnectionLineShape BezierLine { get;private set; }
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) => Remove()));
contextMenu.Items.Add(WpfFuncTool.CreateMenuItem("于父节点调用顺序中置顶", (s, e) => Topping()));
BezierLine.ContextMenu = contextMenu;
}
///
/// 从画布删除
///
public void RemoveOnCanvas()
{
Canvas.Children.Remove(BezierLine);
}
///
/// 删除该连线
///
public void Remove()
{
/*string startGuid = Start.MyNode.Guid;
string endGuid = End.MyNode.Guid;
if (flowEventSerice is null) flowEventSerice = App.GetService();
NodeConnectChangeHandler handler = null;
handler = (e) =>
{
if(e.ConnectionInvokeType == InvokeType && e.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Remove)
{
}
flowEventSerice.NodeConnectChanged -= handler;
};
flowEventSerice.NodeConnectChanged += handler;*/
//
Canvas.Children.Remove(BezierLine);
var env = App.GetService();
var canvasGuid = ((FlowCanvasViewModel)(Canvas.DataContext)).Model.Guid;
var jct = Start.JunctionType.ToConnectyionType();
var jctEnd = End.JunctionType.ToConnectyionType();
if (jct == JunctionOfConnectionType.Invoke)
{
env.FlowEdit.RemoveInvokeConnect(canvasGuid, Start.NodeGuid, End.NodeGuid, InvokeType);
}
else if (jct == JunctionOfConnectionType.Arg)
{
env.FlowEdit.RemoveArgSourceConnect(canvasGuid, Start.NodeGuid, End.NodeGuid, ArgIndex);
}
}
///
/// 置顶调用关系
///
public void Topping()
{
var env = App.GetService();
if (Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke)
{
env.FlowEdit.SetConnectPriorityInvoke(Start.NodeGuid, End.NodeGuid, 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);
}
}
}