mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-03 23:06:34 +08:00
实现了拖拽式设置方法调用顺序、方法入参参数来源
This commit is contained in:
222
Workbench/Node/Junction/BezierLine.cs
Normal file
222
Workbench/Node/Junction/BezierLine.cs
Normal file
@@ -0,0 +1,222 @@
|
||||
using Serein.Library;
|
||||
using Serein.Workbench.Extension;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
/// <summary>
|
||||
/// 连接线的类型
|
||||
/// </summary>
|
||||
public enum LineType
|
||||
{
|
||||
/// <summary>
|
||||
/// 贝塞尔曲线
|
||||
/// </summary>
|
||||
Bezier,
|
||||
/// <summary>
|
||||
/// 半圆线
|
||||
/// </summary>
|
||||
Semicircle,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 贝塞尔曲线
|
||||
/// </summary>
|
||||
public class BezierLine : Shape
|
||||
{
|
||||
private readonly double strokeThickness;
|
||||
|
||||
private readonly LineType lineType;
|
||||
|
||||
/// <summary>
|
||||
/// 确定起始坐标和目标坐标、外光样式的曲线
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="brush"></param>
|
||||
/// <param name="strokeThickness"></param>
|
||||
public BezierLine(LineType lineType, Point start, Point end, Brush brush, double strokeThickness = 4)
|
||||
{
|
||||
this.lineType = lineType;
|
||||
this.brush = brush;
|
||||
startPoint = start;
|
||||
endPoint = end;
|
||||
this.strokeThickness = strokeThickness;
|
||||
InitElementPoint();
|
||||
InvalidateVisual(); // 触发重绘
|
||||
}
|
||||
public void InitElementPoint()
|
||||
{
|
||||
hitVisiblePen = new Pen(Brushes.Transparent, 1.0); // 初始化碰撞检测线
|
||||
hitVisiblePen.Freeze(); // Freeze以提高性能
|
||||
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
|
||||
visualPen.Freeze(); // Freeze以提高性能
|
||||
linkSize = 4; // 整线条粗细
|
||||
Panel.SetZIndex(this, -9999999); // 置底
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新线条落点位置
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
public void UpdatePoints(Point start, Point end)
|
||||
{
|
||||
startPoint = start;
|
||||
endPoint = end;
|
||||
InvalidateVisual(); // 触发重绘
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新线条落点位置
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
public void UpdateEndPoints(Point point)
|
||||
{
|
||||
endPoint = point;
|
||||
InvalidateVisual(); // 触发重绘
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新线条落点位置
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
public void UpdateStartPoints(Point point)
|
||||
{
|
||||
startPoint = point;
|
||||
InvalidateVisual(); // 触发重绘
|
||||
}
|
||||
/// <summary>
|
||||
/// 控件重绘事件
|
||||
/// </summary>
|
||||
/// <param name="drawingContext"></param>
|
||||
protected override void OnRender(DrawingContext drawingContext)
|
||||
{
|
||||
// 刷新线条显示位置
|
||||
switch (this.lineType)
|
||||
{
|
||||
case LineType.Bezier:
|
||||
DrawBezierCurve(drawingContext, startPoint, endPoint, linkSize);
|
||||
break;
|
||||
case LineType.Semicircle:
|
||||
DrawBezierCurve(drawingContext, startPoint, endPoint);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private readonly StreamGeometry streamGeometry = new StreamGeometry();
|
||||
private Point rightCenterOfStartLocation; // 目标节点选择左侧边缘中心
|
||||
private Point leftCenterOfEndLocation; // 起始节点选择右侧边缘中心
|
||||
private Pen hitVisiblePen; // 初始化碰撞检测线
|
||||
private Pen visualPen; // 默认可视化Pen
|
||||
private Point startPoint; // 连接线的起始节点
|
||||
private Point endPoint; // 连接线的终点
|
||||
private Brush brush; // 线条颜色
|
||||
double linkSize; // 根据缩放比例调整线条粗细
|
||||
protected override Geometry DefiningGeometry => streamGeometry;
|
||||
|
||||
#region 工具方法
|
||||
|
||||
|
||||
private Point c0, c1; // 用于计算贝塞尔曲线控制点逻辑
|
||||
private Vector axis = new Vector(1, 0);
|
||||
private Vector startToEnd;
|
||||
private void DrawBezierCurve(DrawingContext drawingContext,
|
||||
Point start,
|
||||
Point end,
|
||||
double linkSize,
|
||||
bool isHitTestVisible = false,
|
||||
double strokeThickness = 1.0,
|
||||
bool isMouseOver = false,
|
||||
double dashOffset = 0.0)
|
||||
{
|
||||
// 控制点的计算逻辑
|
||||
double power = 100; // 控制贝塞尔曲线的“拉伸”强度
|
||||
|
||||
// 计算轴向向量与起点到终点的向量
|
||||
//var axis = new Vector(1, 0);
|
||||
startToEnd = (end.ToVector() - start.ToVector()).NormalizeTo();
|
||||
|
||||
// 计算拉伸程度k,拉伸与水平夹角正相关
|
||||
var k = 1 - Math.Pow(Math.Max(0, axis.DotProduct(startToEnd)), 10.0);
|
||||
|
||||
// 如果起点x大于终点x,增加额外的偏移量,避免重叠
|
||||
var bias = start.X > end.X ? Math.Abs(start.X - end.X) * 0.25 : 0;
|
||||
|
||||
// 控制点的实际计算
|
||||
c0 = new Point(+(power + bias) * k + start.X, start.Y);
|
||||
c1 = new Point(-(power + bias) * k + end.X, end.Y);
|
||||
|
||||
// 准备StreamGeometry以用于绘制曲线
|
||||
streamGeometry.Clear();
|
||||
using (var context = streamGeometry.Open())
|
||||
{
|
||||
context.BeginFigure(start, true, false); // 曲线起点
|
||||
context.BezierTo(c0, c1, end, true, false); // 画贝塞尔曲线
|
||||
}
|
||||
|
||||
drawingContext.DrawGeometry(null, visualPen, streamGeometry);
|
||||
|
||||
// 绘制碰撞检测线
|
||||
//if (true)
|
||||
//{
|
||||
// //hitVisiblePen = new Pen(Brushes.Transparent, linkSize + strokeThickness);
|
||||
// //hitVisiblePen.Freeze();
|
||||
// drawingContext.DrawGeometry(null, hitVisiblePen, streamGeometry);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
private void DrawBezierCurve(DrawingContext drawingContext, Point start, Point end)
|
||||
{
|
||||
// 计算中心点和半径
|
||||
// 计算圆心和半径
|
||||
double x = 35 ;
|
||||
// 创建一个弧线路径
|
||||
streamGeometry.Clear();
|
||||
using (var context = streamGeometry.Open())
|
||||
{
|
||||
// 开始绘制
|
||||
context.BeginFigure(start, false, false);
|
||||
|
||||
// 生成弧线
|
||||
context.ArcTo(
|
||||
end, // 结束点
|
||||
new Size(x, x), // 椭圆的半径
|
||||
0, // 椭圆的旋转角度
|
||||
false, // 是否大弧
|
||||
SweepDirection.Counterclockwise, // 方向
|
||||
true, // 是否连接到起始点
|
||||
true // 是否使用高质量渲染
|
||||
);
|
||||
|
||||
// 结束绘制
|
||||
context.LineTo(start, false, false); // 连接到起始点(可选)
|
||||
}
|
||||
|
||||
// 绘制弧线
|
||||
drawingContext.DrawGeometry(null, visualPen, streamGeometry);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
using Serein.Library;
|
||||
using Serein.Library.Utils;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
|
||||
|
||||
|
||||
public abstract class JunctionControlBase : UserControl
|
||||
{
|
||||
|
||||
public double _MyWidth = 20;
|
||||
public double _MyHeight = 20;
|
||||
|
||||
protected JunctionControlBase()
|
||||
{
|
||||
//this.Width = 20;
|
||||
//this.Height = 20;
|
||||
this.MouseDown += ControlPointBase_MouseDown;
|
||||
this.MouseMove += ControlPointBase_MouseMove; ;
|
||||
}
|
||||
#region 控件属性,所在的节点
|
||||
public static readonly DependencyProperty NodeGuidProperty =
|
||||
DependencyProperty.Register("NodeGuid", typeof(string), typeof(JunctionControlBase), new PropertyMetadata(default(string)));
|
||||
|
||||
/// <summary>
|
||||
/// 所在的节点
|
||||
/// </summary>
|
||||
public string NodeGuid
|
||||
{
|
||||
get { return (string)GetValue(NodeGuidProperty); }
|
||||
set { SetValue(NodeGuidProperty, value.ToString()); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 控件属性,连接器类型
|
||||
public static readonly DependencyProperty JunctionTypeProperty =
|
||||
DependencyProperty.Register("JunctionType", typeof(string), typeof(JunctionControlBase), new PropertyMetadata(default(string)));
|
||||
|
||||
public JunctionType JunctionType
|
||||
{
|
||||
get { return EnumHelper.ConvertEnum<JunctionType>(GetValue(JunctionTypeProperty).ToString()); }
|
||||
set { SetValue(JunctionTypeProperty, value.ToString()); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
public abstract void Render();
|
||||
private void ControlPointBase_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (GlobalJunctionData.MyGlobalData is null) return;
|
||||
GlobalJunctionData.MyGlobalData.ChangingJunction = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在碰撞点上按下鼠标控件开始进行移动
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void ControlPointBase_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
GlobalJunctionData.MyGlobalData = new ConnectingData();
|
||||
var myDataType = GlobalJunctionData.MyGlobalData;
|
||||
myDataType.StartJunction = this;
|
||||
var canvas = MainWindow.GetParentOfType<Canvas>(this);
|
||||
myDataType.StartPoint = this.TranslatePoint(new Point(this.Width /2 , this.Height /2 ), canvas);
|
||||
myDataType.VirtualLine = new MyLine(canvas, new Line // 虚拟线
|
||||
{
|
||||
Stroke = Brushes.OldLace,
|
||||
StrokeThickness = 2
|
||||
});
|
||||
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
134
Workbench/Node/Junction/JunctionControlBase.cs
Normal file
134
Workbench/Node/Junction/JunctionControlBase.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using Serein.Library;
|
||||
using Serein.Library.Utils;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
|
||||
|
||||
|
||||
public abstract class JunctionControlBase : Shape
|
||||
{
|
||||
|
||||
|
||||
protected JunctionControlBase()
|
||||
{
|
||||
this.Width = 25;
|
||||
this.Height = 20;
|
||||
this.MouseDown += ControlPointBase_MouseDown;
|
||||
this.MouseMove += ControlPointBase_MouseMove;
|
||||
}
|
||||
#region 控件属性,所在的节点
|
||||
public static readonly DependencyProperty NodeProperty =
|
||||
DependencyProperty.Register(nameof(MyNode), typeof(NodeModelBase), typeof(JunctionControlBase), new PropertyMetadata(default(NodeModelBase)));
|
||||
|
||||
/// <summary>
|
||||
/// 所在的节点
|
||||
/// </summary>
|
||||
public NodeModelBase MyNode
|
||||
{
|
||||
get { return (NodeModelBase)GetValue(NodeProperty); }
|
||||
set { SetValue(NodeProperty, value); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 控件属性,连接器类型
|
||||
public static readonly DependencyProperty JunctionTypeProperty =
|
||||
DependencyProperty.Register(nameof(JunctionType), typeof(string), typeof(JunctionControlBase), new PropertyMetadata(default(string)));
|
||||
|
||||
/// <summary>
|
||||
/// 控制点类型
|
||||
/// </summary>
|
||||
public JunctionType JunctionType
|
||||
{
|
||||
get { return EnumHelper.ConvertEnum<JunctionType>(GetValue(JunctionTypeProperty).ToString()); }
|
||||
set { SetValue(JunctionTypeProperty, value.ToString()); }
|
||||
}
|
||||
#endregion
|
||||
protected readonly StreamGeometry StreamGeometry = new StreamGeometry();
|
||||
protected override Geometry DefiningGeometry => StreamGeometry;
|
||||
|
||||
/// <summary>
|
||||
/// 重绘方法
|
||||
/// </summary>
|
||||
/// <param name="drawingContext"></param>
|
||||
public abstract void Render(DrawingContext drawingContext);
|
||||
/// <summary>
|
||||
/// 中心点
|
||||
/// </summary>
|
||||
public abstract Point MyCenterPoint { get; }
|
||||
|
||||
// 处理鼠标悬停状态
|
||||
private bool _isMouseOver;
|
||||
public bool IsMouseOver
|
||||
{
|
||||
get => _isMouseOver;
|
||||
set
|
||||
{
|
||||
_isMouseOver = value;
|
||||
InvalidateVisual();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 控件重绘事件
|
||||
/// </summary>
|
||||
/// <param name="drawingContext"></param>
|
||||
protected override void OnRender(DrawingContext drawingContext)
|
||||
{
|
||||
Render(drawingContext);
|
||||
}
|
||||
|
||||
|
||||
protected void ControlPointBase_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (GlobalJunctionData.MyGlobalConnectingData is null) return;
|
||||
GlobalJunctionData.MyGlobalConnectingData.CurrentJunction = this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 在碰撞点上按下鼠标控件开始进行移动
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
protected void ControlPointBase_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
GlobalJunctionData.MyGlobalConnectingData = new ConnectingData();
|
||||
var myDataType = GlobalJunctionData.MyGlobalConnectingData;
|
||||
myDataType.StartJunction = this;
|
||||
var canvas = MainWindow.GetParentOfType<Canvas>(this);
|
||||
if (canvas != null)
|
||||
{
|
||||
//myDataType.StartPoint = this.MyCenterPoint;
|
||||
myDataType.StartPoint = this.TranslatePoint(new Point(this.Width / 2, this.Height / 2), canvas);
|
||||
var bezierLine = new BezierLine(LineType.Bezier, myDataType.StartPoint, myDataType.StartPoint, Brushes.Green);
|
||||
myDataType.VirtualLine = new MyLine(canvas, bezierLine);
|
||||
}
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private Point GetStartPoint()
|
||||
{
|
||||
return new Point(this.ActualWidth / 2, this.ActualHeight / 2); // 起始节点选择右侧边缘中心
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace Serein.Workbench.Node.View
|
||||
#region Model,不科学的全局变量
|
||||
public class MyLine
|
||||
{
|
||||
public MyLine(Canvas canvas, Line line)
|
||||
public MyLine(Canvas canvas, BezierLine line)
|
||||
{
|
||||
Canvas = canvas;
|
||||
VirtualLine = line;
|
||||
@@ -21,7 +21,7 @@ namespace Serein.Workbench.Node.View
|
||||
}
|
||||
|
||||
public Canvas Canvas { get; set; }
|
||||
public Line VirtualLine { get; set; }
|
||||
public BezierLine VirtualLine { get; set; }
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
@@ -32,33 +32,98 @@ namespace Serein.Workbench.Node.View
|
||||
public class ConnectingData
|
||||
{
|
||||
public JunctionControlBase StartJunction { get; set; }
|
||||
public JunctionControlBase ChangingJunction { get; set; }
|
||||
public JunctionControlBase CurrentJunction { get; set; }
|
||||
public Point StartPoint { get; set; }
|
||||
public MyLine VirtualLine { get; set; }
|
||||
}
|
||||
|
||||
public static class GlobalJunctionData
|
||||
{
|
||||
private static ConnectingData? myGlobalData;
|
||||
/// <summary>
|
||||
/// 是否允许连接
|
||||
/// </summary>
|
||||
|
||||
public static ConnectingData? MyGlobalData
|
||||
{
|
||||
get => myGlobalData;
|
||||
set
|
||||
public bool IsCanConnected { get
|
||||
{
|
||||
if (myGlobalData == null)
|
||||
if(StartJunction is null
|
||||
|| CurrentJunction is null
|
||||
)
|
||||
{
|
||||
myGlobalData = value;
|
||||
return false;
|
||||
}
|
||||
if (!StartPoint.Equals(CurrentJunction))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 自己连接自己的情况下,只能是从arg控制点连接到execute控制点。
|
||||
if (CurrentJunction.JunctionType == Library.JunctionType.Execute
|
||||
&& StartJunction.JunctionType == Library.JunctionType.ArgData)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CurrentJunction.JunctionType == Library.JunctionType.ArgData
|
||||
&& StartJunction.JunctionType == Library.JunctionType.Execute)
|
||||
{
|
||||
// 需要是自己连接自己,且只能是从arg控制点连接到execute控制点。
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新临时的连接线
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
public void UpdatePoint(Point point)
|
||||
{
|
||||
if (StartJunction is null
|
||||
|| CurrentJunction is null
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (StartJunction.JunctionType == Library.JunctionType.Execute
|
||||
|| StartJunction.JunctionType == Library.JunctionType.ArgData)
|
||||
{
|
||||
VirtualLine.VirtualLine.UpdateStartPoints(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
VirtualLine.VirtualLine.UpdateEndPoints(point);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static bool IsCreatingConnection => myGlobalData is not null;
|
||||
}
|
||||
|
||||
public static bool CanCreate => myGlobalData?.ChangingJunction.Equals(myGlobalData?.StartJunction) == false;
|
||||
public static class GlobalJunctionData
|
||||
{
|
||||
private static ConnectingData? myGlobalData;
|
||||
private static object _lockObj = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 创建节点之间控制点的连接行为
|
||||
/// </summary>
|
||||
public static ConnectingData? MyGlobalConnectingData
|
||||
{
|
||||
get => myGlobalData;
|
||||
set
|
||||
{
|
||||
lock (_lockObj)
|
||||
{
|
||||
myGlobalData ??= value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除连接视觉效果
|
||||
/// </summary>
|
||||
public static void OK()
|
||||
{
|
||||
myGlobalData?.VirtualLine.Remove();
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Serein.Workbench.Node.View
|
||||
public ArgJunctionControl()
|
||||
{
|
||||
base.JunctionType = JunctionType.ArgData;
|
||||
Render();
|
||||
this.InvalidateVisual();
|
||||
}
|
||||
|
||||
#region 控件属性,对应的参数
|
||||
@@ -25,28 +25,50 @@ namespace Serein.Workbench.Node.View
|
||||
get { return (int)GetValue(ArgIndexProperty); }
|
||||
set { SetValue(ArgIndexProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
public override void Render()
|
||||
private Point _myCenterPoint;
|
||||
public override Point MyCenterPoint { get => _myCenterPoint; }
|
||||
public override void Render(DrawingContext drawingContext)
|
||||
{
|
||||
if(double.IsNaN(base.Width))
|
||||
{
|
||||
base.Width = base._MyWidth;
|
||||
}
|
||||
if (double.IsNaN(base.Height))
|
||||
{
|
||||
base.Height = base._MyHeight;
|
||||
}
|
||||
double width = ActualWidth;
|
||||
double height = ActualHeight;
|
||||
|
||||
// 输入连接器的背景
|
||||
var connectorBackground = IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent;
|
||||
var connectorRect = new Rect(4, 4, width - 8, height - 8);
|
||||
drawingContext.DrawRectangle(connectorBackground, null, connectorRect);
|
||||
|
||||
// 定义圆形的大小和位置
|
||||
double connectorSize = 10; // 连接器的大小
|
||||
double circleCenterX = 8; // 圆心 X 坐标
|
||||
double circleCenterY = height / 2; // 圆心 Y 坐标
|
||||
var circlePoint = new Point(circleCenterX, circleCenterY);
|
||||
|
||||
// 绘制连接器的圆形部分
|
||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY);
|
||||
drawingContext.DrawGeometry(IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent, new Pen(Brushes.Black, 1), ellipse);
|
||||
|
||||
|
||||
var ellipse = new Ellipse
|
||||
|
||||
|
||||
// 定义三角形的间距
|
||||
double triangleOffsetX = 4; // 三角形与圆形的间距
|
||||
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
|
||||
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
|
||||
|
||||
// 绘制三角形
|
||||
var pathGeometry = new StreamGeometry();
|
||||
using (var context = pathGeometry.Open())
|
||||
{
|
||||
Width = base.Width,
|
||||
Height = base.Height,
|
||||
Fill = Brushes.Orange,
|
||||
ToolTip = "入参"
|
||||
};
|
||||
Content = ellipse;
|
||||
context.BeginFigure(new Point(triangleCenterX, triangleCenterY - 4.5), true, true);
|
||||
context.LineTo(new Point(triangleCenterX + 5, triangleCenterY), true, false);
|
||||
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
||||
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
||||
}
|
||||
drawingContext.DrawGeometry(IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent, new Pen(Brushes.Black, 1), pathGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Windows.Media;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using Serein.Library;
|
||||
|
||||
@@ -6,32 +8,75 @@ namespace Serein.Workbench.Node.View
|
||||
{
|
||||
public class ExecuteJunctionControl : JunctionControlBase
|
||||
{
|
||||
//public override JunctionType JunctionType { get; } = JunctionType.Execute;
|
||||
|
||||
|
||||
|
||||
public ExecuteJunctionControl()
|
||||
{
|
||||
base.JunctionType = JunctionType.Execute;
|
||||
Render();
|
||||
this.InvalidateVisual();
|
||||
|
||||
}
|
||||
|
||||
public override void Render()
|
||||
private Point _myCenterPoint;
|
||||
public override Point MyCenterPoint { get => _myCenterPoint; }
|
||||
public override void Render(DrawingContext drawingContext)
|
||||
{
|
||||
if (double.IsNaN(base.Width))
|
||||
{
|
||||
base.Width = base._MyWidth;
|
||||
}
|
||||
if (double.IsNaN(base.Height))
|
||||
{
|
||||
base.Height = base._MyHeight;
|
||||
}
|
||||
double width = ActualWidth;
|
||||
double height = ActualHeight;
|
||||
|
||||
var rect = new Rectangle
|
||||
// 绘制边框
|
||||
//var borderBrush = new SolidColorBrush(Colors.Black);
|
||||
//var borderThickness = 1.0;
|
||||
//var borderRect = new Rect(0, 0, width, height);
|
||||
//drawingContext.DrawRectangle(null, new Pen(borderBrush, borderThickness), borderRect);
|
||||
|
||||
// 输入连接器的背景
|
||||
var connectorBackground = IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent;
|
||||
var connectorRect = new Rect(4, 4, width - 8, height - 8);
|
||||
drawingContext.DrawRectangle(connectorBackground, null, connectorRect);
|
||||
|
||||
// 定义圆形的大小和位置
|
||||
double connectorSize = 10; // 连接器的大小
|
||||
double circleCenterX = 8; // 圆心 X 坐标
|
||||
double circleCenterY = height / 2; // 圆心 Y 坐标
|
||||
|
||||
var circlePoint = new Point(circleCenterX, circleCenterY);
|
||||
// 绘制连接器的圆形部分
|
||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY);
|
||||
|
||||
|
||||
drawingContext.DrawGeometry(IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent, new Pen(Brushes.Black, 1), ellipse);
|
||||
|
||||
|
||||
|
||||
|
||||
// 定义三角形的间距
|
||||
double triangleOffsetX = 4; // 三角形与圆形的间距
|
||||
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
|
||||
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
|
||||
|
||||
// 绘制三角形
|
||||
var pathGeometry = new StreamGeometry();
|
||||
using (var context = pathGeometry.Open())
|
||||
{
|
||||
Width = base.Width,
|
||||
Height = base.Height,
|
||||
Fill = Brushes.Green,
|
||||
ToolTip = "方法执行"
|
||||
};
|
||||
Content = rect;
|
||||
context.BeginFigure(new Point(triangleCenterX, triangleCenterY - 4.5), true, true);
|
||||
context.LineTo(new Point(triangleCenterX + 5, triangleCenterY), true, false);
|
||||
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
||||
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
||||
}
|
||||
drawingContext.DrawGeometry(IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent, new Pen(Brushes.Black, 1), pathGeometry);
|
||||
|
||||
// 绘制标签
|
||||
//var formattedText = new FormattedText(
|
||||
// "执行",
|
||||
// System.Globalization.CultureInfo.CurrentCulture,
|
||||
// FlowDirection.LeftToRight,
|
||||
// new Typeface("Segoe UI"),
|
||||
// 12,
|
||||
// Brushes.Black,
|
||||
// VisualTreeHelper.GetDpi(this).PixelsPerDip);
|
||||
//drawingContext.DrawText(formattedText, new Point(18,1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Windows.Media;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using Serein.Library;
|
||||
|
||||
@@ -11,28 +12,50 @@ namespace Serein.Workbench.Node.View
|
||||
public NextStepJunctionControl()
|
||||
{
|
||||
base.JunctionType = JunctionType.NextStep;
|
||||
Render();
|
||||
this.InvalidateVisual();
|
||||
}
|
||||
|
||||
public override void Render()
|
||||
private Point _myCenterPoint;
|
||||
public override Point MyCenterPoint { get => _myCenterPoint; }
|
||||
public override void Render(DrawingContext drawingContext)
|
||||
{
|
||||
if (double.IsNaN(base.Width))
|
||||
{
|
||||
base.Width = base._MyWidth;
|
||||
}
|
||||
if (double.IsNaN(base.Height))
|
||||
{
|
||||
base.Height = base._MyHeight;
|
||||
}
|
||||
double width = ActualWidth;
|
||||
double height = ActualHeight;
|
||||
|
||||
var rect = new Rectangle
|
||||
// 输入连接器的背景
|
||||
var connectorBackground = IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent;
|
||||
var connectorRect = new Rect(4, 4, width - 8, height - 8);
|
||||
drawingContext.DrawRectangle(connectorBackground, null, connectorRect);
|
||||
|
||||
// 定义圆形的大小和位置
|
||||
double connectorSize = 10; // 连接器的大小
|
||||
double circleCenterX = 8; // 圆心 X 坐标
|
||||
double circleCenterY = height / 2; // 圆心 Y 坐标
|
||||
|
||||
var circlePoint = new Point(circleCenterX, circleCenterY);
|
||||
// 绘制连接器的圆形部分
|
||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||
drawingContext.DrawGeometry(IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent, new Pen(Brushes.Black, 1), ellipse);
|
||||
_myCenterPoint = new Point(circleCenterX + connectorSize / 2, circleCenterY);
|
||||
|
||||
// 绘制连接器的圆形部分
|
||||
//var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||
|
||||
|
||||
// 定义三角形的间距
|
||||
double triangleOffsetX = 4; // 三角形与圆形的间距
|
||||
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
|
||||
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
|
||||
|
||||
// 绘制三角形
|
||||
var pathGeometry = new StreamGeometry();
|
||||
using (var context = pathGeometry.Open())
|
||||
{
|
||||
Width = base.Width,
|
||||
Height = base.Height,
|
||||
Fill = Brushes.Blue,
|
||||
ToolTip = "下一个方法值"
|
||||
};
|
||||
Content = rect;
|
||||
context.BeginFigure(new Point(triangleCenterX, triangleCenterY - 4.5), true, true);
|
||||
context.LineTo(new Point(triangleCenterX + 5, triangleCenterY), true, false);
|
||||
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
||||
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
||||
}
|
||||
drawingContext.DrawGeometry(IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent, new Pen(Brushes.Black, 1), pathGeometry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Windows.Media;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using Serein.Library;
|
||||
|
||||
@@ -12,28 +13,47 @@ namespace Serein.Workbench.Node.View
|
||||
public ResultJunctionControl()
|
||||
{
|
||||
base.JunctionType = JunctionType.ReturnData;
|
||||
Render();
|
||||
this.InvalidateVisual();
|
||||
}
|
||||
private Point _myCenterPoint;
|
||||
public override Point MyCenterPoint { get => _myCenterPoint; }
|
||||
|
||||
public override void Render()
|
||||
public override void Render(DrawingContext drawingContext)
|
||||
{
|
||||
if (double.IsNaN(base.Width))
|
||||
{
|
||||
base.Width = base._MyWidth;
|
||||
}
|
||||
if (double.IsNaN(base.Height))
|
||||
{
|
||||
base.Height = base._MyHeight;
|
||||
}
|
||||
double width = ActualWidth;
|
||||
double height = ActualHeight;
|
||||
|
||||
var rect = new Rectangle
|
||||
// 输入连接器的背景
|
||||
var connectorBackground = IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent;
|
||||
var connectorRect = new Rect(4, 4, width - 8, height - 8);
|
||||
drawingContext.DrawRectangle(connectorBackground, null, connectorRect);
|
||||
|
||||
// 定义圆形的大小和位置
|
||||
double connectorSize = 10; // 连接器的大小
|
||||
double circleCenterX = 8; // 圆心 X 坐标
|
||||
double circleCenterY = height / 2; // 圆心 Y 坐标
|
||||
var circlePoint = new Point(circleCenterX, circleCenterY);
|
||||
|
||||
// 绘制连接器的圆形部分
|
||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY);
|
||||
drawingContext.DrawGeometry(IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent, new Pen(Brushes.Black, 1), ellipse);
|
||||
|
||||
// 定义三角形的间距
|
||||
double triangleOffsetX = 4; // 三角形与圆形的间距
|
||||
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
|
||||
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
|
||||
|
||||
// 绘制三角形
|
||||
var pathGeometry = new StreamGeometry();
|
||||
using (var context = pathGeometry.Open())
|
||||
{
|
||||
Width = base.Width,
|
||||
Height = base.Height,
|
||||
Fill = Brushes.Red,
|
||||
ToolTip = "返回值"
|
||||
};
|
||||
Content = rect;
|
||||
context.BeginFigure(new Point(triangleCenterX, triangleCenterY - 4.5), true, true);
|
||||
context.LineTo(new Point(triangleCenterX + 5, triangleCenterY), true, false);
|
||||
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
||||
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
||||
}
|
||||
drawingContext.DrawGeometry(IsMouseOver ? Brushes.DarkCyan : Brushes.Transparent, new Pen(Brushes.Black, 1), pathGeometry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user