Delete Workbench directory

移除不要的文件夹
This commit is contained in:
一泓秋水
2025-01-02 13:58:55 +08:00
committed by GitHub
parent c47320d4de
commit 2c160d660a
26 changed files with 0 additions and 2953 deletions

View File

@@ -1,234 +0,0 @@
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 ConnectionLineShape : Shape
{
private readonly double strokeThickness;
private readonly LineType lineType;
/// <summary>
/// 确定起始坐标和目标坐标、外光样式的曲线
/// </summary>
/// <param name="lineType">线条类型</param>
/// <param name="start">起始坐标</param>
/// <param name="end">结束坐标</param>
/// <param name="brush">颜色</param>
/// <param name="isDotted">是否为虚线</param>
public ConnectionLineShape(LineType lineType,
Point start,
Point end,
Brush brush,
bool isDotted = false,
bool isTop = false)
{
this.lineType = lineType;
this.brush = brush;
startPoint = start;
endPoint = end;
this.strokeThickness = 4;
InitElementPoint(isDotted, isTop);
InvalidateVisual(); // 触发重绘
}
public void InitElementPoint(bool isDotted , bool isTop = false)
{
hitVisiblePen = new Pen(Brushes.Transparent, 1.0); // 初始化碰撞检测线
hitVisiblePen.Freeze(); // Freeze以提高性能
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
opacity = 1.0d;
if (isDotted)
{
opacity = 0.42d;
visualPen.DashStyle = DashStyles.Dash; // 选择虚线样式
}
visualPen.Freeze(); // Freeze以提高性能
linkSize = 4; // 整线条粗细
int zIndex = -999999;
if (isTop)
{
zIndex *= -1;
}
Panel.SetZIndex(this, zIndex); // 置底
}
/// <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);
break;
case LineType.Semicircle:
DrawSemicircleCurve(drawingContext, startPoint, endPoint);
break;
default:
break;
}
}
#region
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; // 线条颜色
private double opacity; // 透明度
double linkSize; // 根据缩放比例调整线条粗细
protected override Geometry DefiningGeometry => streamGeometry;
public void UpdateLineColor(Brush brush)
{
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
InvalidateVisual(); // 触发重绘
}
private Point c0, c1; // 用于计算贝塞尔曲线控制点逻辑
private Vector axis = new Vector(1, 0);
private Vector startToEnd;
private void DrawBezierCurve(DrawingContext drawingContext,
Point start,
Point end)
{
// 控制点的计算逻辑
double power = 140; // 控制贝塞尔曲线的“拉伸”强度
drawingContext.PushOpacity(opacity);
// 计算轴向向量与起点到终点的向量
//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);
}
private void DrawSemicircleCurve(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);
}
#endregion
}
}

View File

@@ -1,378 +0,0 @@
using Serein.Library;
using Serein.Library.Utils;
using System;
using System.Net;
using System.Reflection;
using System.Windows;
using Serein.Workbench.Extension;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.Windows.Documents;
using System.Threading;
namespace Serein.Workbench.Node.View
{
internal static class MyUIFunc
{
public static Pen CreateAndFreezePen()
{
// 创建Pen
Pen pen = new Pen(Brushes.Black, 1);
// 冻结Pen
if (pen.CanFreeze)
{
pen.Freeze();
}
return pen;
}
}
public class ParamsArgControl: Shape
{
public ParamsArgControl()
{
this.MouseDown += ParamsArg_OnMouseDown; // 增加或删除
this.MouseMove += ParamsArgControl_MouseMove;
this.MouseLeave += ParamsArgControl_MouseLeave;
AddOrRemoveParamsTask = AddAsync;
}
protected readonly StreamGeometry StreamGeometry = new StreamGeometry();
protected override Geometry DefiningGeometry => StreamGeometry;
#region
public static readonly DependencyProperty NodeProperty =
DependencyProperty.Register(nameof(MyNode), typeof(NodeModelBase), typeof(ParamsArgControl), new PropertyMetadata(default(NodeModelBase)));
//public NodeModelBase NodeModel;
/// <summary>
/// 所在的节点
/// </summary>
public NodeModelBase MyNode
{
get { return (NodeModelBase)GetValue(NodeProperty); }
set { SetValue(NodeProperty, value); }
}
#endregion
#region
public static readonly DependencyProperty ArgIndexProperty =
DependencyProperty.Register(nameof(ArgIndex), typeof(int), typeof(ParamsArgControl), new PropertyMetadata(default(int)));
/// <summary>
/// 参数的索引
/// </summary>
public int ArgIndex
{
get { return (int)GetValue(ArgIndexProperty); }
set { SetValue(ArgIndexProperty, value.ToString()); }
}
#endregion
/// <summary>
/// 控件重绘事件
/// </summary>
/// <param name="drawingContext"></param>
protected override void OnRender(DrawingContext drawingContext)
{
Brush brush = isMouseOver ? Brushes.Red : Brushes.Green;
double height = ActualHeight;
// 定义圆形的大小和位置
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(brush, MyUIFunc.CreateAndFreezePen(), ellipse);
}
private bool isMouseOver; // 鼠标悬停状态
private Func<Task> AddOrRemoveParamsTask; // 增加或删除参数
public async void ParamsArg_OnMouseDown(object sender, MouseButtonEventArgs e)
{
await AddOrRemoveParamsTask.Invoke();
}
private void ParamsArgControl_MouseMove(object sender, MouseEventArgs e)
{
isMouseOver = true;
if (cancellationTokenSource.IsCancellationRequested) {
cancellationTokenSource = new CancellationTokenSource();
Task.Run(async () =>
{
await Task.Delay(380);
}, cancellationTokenSource.Token).ContinueWith((t) =>
{
// 如果焦点仍在控件上时,则改变点击事件
if (isMouseOver)
{
AddOrRemoveParamsTask = RemoveAsync;
this.Dispatcher.Invoke(InvalidateVisual);// 触发一次重绘
}
});
}
}
private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
private void ParamsArgControl_MouseLeave(object sender, MouseEventArgs e)
{
isMouseOver = false;
AddOrRemoveParamsTask = AddAsync; // 鼠标焦点离开时恢复点击事件
cancellationTokenSource?.Cancel();
this.Dispatcher.Invoke(InvalidateVisual);// 触发一次重绘
}
private async Task AddAsync()
{
await this.MyNode.Env.ChangeParameter(MyNode.Guid, true, ArgIndex);
}
private async Task RemoveAsync()
{
await this.MyNode.Env.ChangeParameter(MyNode.Guid, false, ArgIndex);
}
}
public abstract class JunctionControlBase : Shape
{
protected JunctionControlBase()
{
this.Width = 25;
this.Height = 20;
this.MouseDown += JunctionControlBase_MouseDown;
this.MouseMove += JunctionControlBase_MouseMove;
this.MouseLeave += JunctionControlBase_MouseLeave; ;
}
#region
public static readonly DependencyProperty NodeProperty =
DependencyProperty.Register(nameof(MyNode), typeof(NodeModelBase), typeof(JunctionControlBase), new PropertyMetadata(default(NodeModelBase)));
//public NodeModelBase NodeModel;
/// <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; }
/// <summary>
/// 禁止连接
/// </summary>
private bool IsConnectionDisable;
/// <summary>
/// 处理鼠标悬停状态
/// </summary>
private bool _isMouseOver;
public bool IsMouseOver
{
get => _isMouseOver;
set
{
if(_isMouseOver != value)
{
GlobalJunctionData.MyGlobalConnectingData.CurrentJunction = this;
_isMouseOver = value;
InvalidateVisual();
}
}
}
/// <summary>
/// 控件重绘事件
/// </summary>
/// <param name="drawingContext"></param>
protected override void OnRender(DrawingContext drawingContext)
{
Render(drawingContext);
}
/// <summary>
/// 获取背景颜色
/// </summary>
/// <returns></returns>
protected Brush GetBackgrounp()
{
var myData = GlobalJunctionData.MyGlobalConnectingData;
if(!myData.IsCreateing)
{
return Brushes.Transparent;
}
if (IsMouseOver)
{
if (myData.IsCanConnected)
{
if (myData.Type == JunctionOfConnectionType.Invoke)
{
return myData.ConnectionInvokeType.ToLineColor();
}
else
{
return myData.ConnectionArgSourceType.ToLineColor();
}
}
else
{
return Brushes.Red;
}
}
else
{
return Brushes.Transparent;
}
}
private object lockObj = new object();
/// <summary>
/// 控件获得鼠标焦点事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void JunctionControlBase_MouseMove(object sender, MouseEventArgs e)
{
//if (!GlobalJunctionData.MyGlobalConnectingData.IsCreateing) return;
//if (IsMouseOver) return;
IsMouseOver = true;
//this.InvalidateVisual();
}
/// <summary>
/// 控件失去鼠标焦点事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void JunctionControlBase_MouseLeave(object sender, MouseEventArgs e)
{
IsMouseOver = false;
e.Handled = true;
}
/// <summary>
/// 在碰撞点上按下鼠标控件开始进行移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void JunctionControlBase_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var canvas = MainWindow.GetParentOfType<Canvas>(this);
if (canvas != null)
{
var myData = GlobalJunctionData.MyGlobalConnectingData;
myData.Reset();
myData.IsCreateing = true; // 表示开始连接
myData.StartJunction = this;
myData.CurrentJunction = this;
myData.StartPoint = this.TranslatePoint(new Point(this.Width / 2, this.Height / 2), canvas);
var junctionOfConnectionType = this.JunctionType.ToConnectyionType();
ConnectionLineShape bezierLine; // 类别
Brush brushColor; // 临时线的颜色
if (junctionOfConnectionType == JunctionOfConnectionType.Invoke)
{
brushColor = ConnectionInvokeType.IsSucceed.ToLineColor();
}
else if(junctionOfConnectionType == JunctionOfConnectionType.Arg)
{
brushColor = ConnectionArgSourceType.GetOtherNodeData.ToLineColor();
}
else
{
return;
}
bezierLine = new ConnectionLineShape(LineType.Bezier,
myData.StartPoint,
myData.StartPoint,
brushColor,
isTop: true); // 绘制临时的线
Mouse.OverrideCursor = Cursors.Cross; // 设置鼠标为正在创建连线
myData.MyLine = new MyLine(canvas, bezierLine);
}
}
e.Handled = true;
}
private Point GetStartPoint()
{
return new Point(this.ActualWidth / 2, this.ActualHeight / 2); // 起始节点选择右侧边缘中心
}
}
}

View File

@@ -1,161 +0,0 @@
using Serein.Library;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
namespace Serein.Workbench.Node.View
{
#region Model
public class MyLine
{
public MyLine(Canvas canvas, ConnectionLineShape line)
{
Canvas = canvas;
Line = line;
canvas?.Children.Add(line);
}
public Canvas Canvas { get; set; }
public ConnectionLineShape Line { get; set; }
public void Remove()
{
Canvas?.Children.Remove(Line);
}
}
public class ConnectingData
{
/// <summary>
/// 是否正在创建连线
/// </summary>
public bool IsCreateing { get; set; }
/// <summary>
/// 起始控制点
/// </summary>
public JunctionControlBase StartJunction { get; set; }
/// <summary>
/// 当前的控制点
/// </summary>
public JunctionControlBase CurrentJunction { get; set; }
/// <summary>
/// 开始坐标
/// </summary>
public Point StartPoint { get; set; }
/// <summary>
/// 线条样式
/// </summary>
public MyLine MyLine { get; set; }
/// <summary>
/// 线条类别(方法调用)
/// </summary>
public ConnectionInvokeType ConnectionInvokeType { get; set; } = ConnectionInvokeType.IsSucceed;
/// <summary>
/// 线条类别(参数传递)
/// </summary>
public ConnectionArgSourceType ConnectionArgSourceType { get; set; } = ConnectionArgSourceType.GetOtherNodeData;
/// <summary>
/// 判断当前连接类型
/// </summary>
public JunctionOfConnectionType Type => StartJunction.JunctionType.ToConnectyionType();
/// <summary>
/// 是否允许连接
/// </summary>
public bool IsCanConnected { get
{
if(StartJunction is null
|| CurrentJunction is null
)
{
return false;
}
if (!StartJunction.MyNode.Equals(CurrentJunction.MyNode)
&& StartJunction.JunctionType.IsCanConnection(CurrentJunction.JunctionType))
{
return true;
}
else
{
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)
{
MyLine.Line.UpdateStartPoints(point);
}
else
{
MyLine.Line.UpdateEndPoints(point);
}
}
/// <summary>
/// 重置
/// </summary>
public void Reset()
{
IsCreateing = false;
StartJunction = null;
CurrentJunction = null;
MyLine?.Remove();
ConnectionInvokeType = ConnectionInvokeType.IsSucceed;
ConnectionArgSourceType = ConnectionArgSourceType.GetOtherNodeData;
}
}
public static class GlobalJunctionData
{
//private static ConnectingData? myGlobalData;
//private static object _lockObj = new object();
/// <summary>
/// 创建节点之间控制点的连接行为
/// </summary>
public static ConnectingData MyGlobalConnectingData { get; } = new ConnectingData();
/// <summary>
/// 删除连接视觉效果
/// </summary>
public static void OK()
{
MyGlobalConnectingData.Reset();
}
}
#endregion
}

View File

@@ -1,237 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows;
using Serein.Workbench.Node.View;
using System.Windows.Controls;
using Serein.Library;
using System.Windows.Data;
namespace Serein.Workbench.Node.View
{
public abstract class NodeJunctionViewBase : ContentControl, IDisposable
{
public NodeJunctionViewBase()
{
var transfromGroup = new TransformGroup();
transfromGroup.Children.Add(_Translate);
RenderTransform = transfromGroup;
}
/// <summary>
/// 每个连接器都有一个唯一标识符Guid用于标识连接器。
/// </summary>
public Guid Guid
{
get => (Guid)GetValue(GuidProperty);
set => SetValue(GuidProperty, value);
}
public static readonly DependencyProperty GuidProperty = DependencyProperty.Register(
nameof(Guid),
typeof(Guid),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new PropertyMetadata(Guid.Empty));
/// <summary>
/// 连接器当前的连接数,表示有多少条 NodeLink 连接到此连接器。该属性为只读。
/// </summary>
public int ConnectedCount
{
get => (int)GetValue(ConnectedCountProperty);
private set => SetValue(ConnectedCountPropertyKey, value);
}
public static readonly DependencyPropertyKey ConnectedCountPropertyKey = DependencyProperty.RegisterReadOnly(
nameof(ConnectedCount),
typeof(int),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new PropertyMetadata(0));
public static readonly DependencyProperty ConnectedCountProperty = ConnectedCountPropertyKey.DependencyProperty;
/// <summary>
/// 布尔值,指示此连接器是否有任何连接。
/// </summary>
public bool IsConnected
{
get => (bool)GetValue(IsConnectedProperty);
private set => SetValue(IsConnectedPropertyKey, value);
}
public static readonly DependencyPropertyKey IsConnectedPropertyKey = DependencyProperty.RegisterReadOnly(
nameof(IsConnected),
typeof(bool),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new PropertyMetadata(false));
public static readonly DependencyProperty IsConnectedProperty = IsConnectedPropertyKey.DependencyProperty;
/// <summary>
/// 这些属性控制连接器的外观(颜色、边框厚度、填充颜色)。
/// </summary>
public Brush Stroke
{
get => (Brush)GetValue(StrokeProperty);
set => SetValue(StrokeProperty, value);
}
public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(
nameof(Stroke),
typeof(Brush),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new FrameworkPropertyMetadata(Brushes.Blue));
/// <summary>
/// 这些属性控制连接器的外观(颜色、边框厚度、填充颜色)。
/// </summary>
public double StrokeThickness
{
get => (double)GetValue(StrokeThicknessProperty);
set => SetValue(StrokeThicknessProperty, value);
}
public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register(
nameof(StrokeThickness),
typeof(double),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new FrameworkPropertyMetadata(1.0));
/// <summary>
/// 这些属性控制连接器的外观(颜色、边框厚度、填充颜色)。
/// </summary>
public Brush Fill
{
get => (Brush)GetValue(FillProperty);
set => SetValue(FillProperty, value);
}
public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
nameof(Fill),
typeof(Brush),
typeof(NodeJunctionViewBase),// NodeConnectorContent
new FrameworkPropertyMetadata(Brushes.Gray));
/// <summary>
/// 指示该连接器是否可以与其他连接器进行连接。
/// </summary>
public bool CanConnect
{
get => (bool)GetValue(CanConnectProperty);
set => SetValue(CanConnectProperty, value);
}
public static readonly DependencyProperty CanConnectProperty = DependencyProperty.Register(
nameof(CanConnect),
typeof(bool),
typeof(NodeJunctionViewBase),// NodeConnectorContent
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender));
private Point _Position = new Point();
/// <summary>
/// 该连接器的当前坐标(位置)。
/// </summary>
public Point Position
{
get => _Position;
set => UpdatePosition(value);
}
/// <summary>
/// (重要数据)表示连接器所属的节点。
/// </summary>
public NodeModelBase NodeModel { get; private set; } = null;
/// <summary>
/// 该连接器所连接的所有 NodeLink 的集合。
/// </summary>
public IEnumerable<ConnectionControl> NodeLinks => _NodeLinks;
List<ConnectionControl> _NodeLinks = new List<ConnectionControl>();
protected abstract FrameworkElement ConnectorControl { get; }
TranslateTransform _Translate = new TranslateTransform();
void UpdatePosition(Point pos)
{
_Position = pos;
_Translate.X = _Position.X;
_Translate.Y = _Position.Y;
InvalidateVisual();
}
/// <summary>
/// 将 NodeLink 添加到连接器,并更新 ConnectedCount 和 IsConnected。
/// </summary>
/// <param name="nodeLink"></param>
public void Connect(ConnectionControl nodeLink)
{
_NodeLinks.Add(nodeLink);
ConnectedCount = _NodeLinks.Count;
IsConnected = ConnectedCount > 0;
}
/// <summary>
/// 断开与某个 NodeLink 的连接,更新连接状态。
/// </summary>
/// <param name="nodeLink"></param>
public void Disconnect(ConnectionControl nodeLink)
{
_NodeLinks.Remove(nodeLink);
ConnectedCount = _NodeLinks.Count;
IsConnected = ConnectedCount > 0;
}
/// <summary>
/// 获取连接器相对于指定 Canvas 的位置。
/// </summary>
/// <param name="canvas"></param>
/// <param name="xScaleOffset"></param>
/// <param name="yScaleOffset"></param>
/// <returns></returns>
public Point GetContentPosition(Canvas canvas, double xScaleOffset = 0.5, double yScaleOffset = 0.5)
{
// it will be shifted Control position if not called UpdateLayout().
ConnectorControl.UpdateLayout();
var transformer = ConnectorControl.TransformToVisual(canvas);
var x = ConnectorControl.ActualWidth * xScaleOffset;
var y = ConnectorControl.ActualHeight * yScaleOffset;
return transformer.Transform(new Point(x, y));
}
/// <summary>
/// 更新与此连接器相连的所有 NodeLink 的位置。这个方法是抽象的,要求子类实现。
/// </summary>
/// <param name="canvas"></param>
public abstract void UpdateLinkPosition(Canvas canvas);
/// <summary>
/// 用于检查此连接器是否可以与另一个连接器相连接,要求子类实现。
/// </summary>
/// <param name="connector"></param>
/// <returns></returns>
public abstract bool CanConnectTo(NodeJunctionViewBase connector);
/// <summary>
/// 释放连接器相关的资源,包括样式、绑定和已连接的 NodeLink
/// </summary>
public void Dispose()
{
// You need to clear Style.
// Because implemented on style for binding.
Style = null;
// Clear binding for subscribing source changed event from old control.
// throw exception about visual tree ancestor different if you not clear binding.
BindingOperations.ClearAllBindings(this);
var nodeLinks = _NodeLinks.ToArray();
// it must instance to nodeLinks because change node link collection in NodeLink Dispose.
foreach (var nodeLink in nodeLinks)
{
// nodeLink.Dispose();
}
}
}
}

View File

@@ -1,74 +0,0 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ArgJunctionControl : JunctionControlBase
{
public ArgJunctionControl()
{
base.JunctionType = JunctionType.ArgData;
this.InvalidateVisual();
}
#region
public static readonly DependencyProperty ArgIndexProperty =
DependencyProperty.Register("ArgIndex", typeof(int), typeof(ArgJunctionControl), new PropertyMetadata(default(int)));
/// <summary>
/// 所在的节点
/// </summary>
public int ArgIndex
{
get { return (int)GetValue(ArgIndexProperty); }
set { SetValue(ArgIndexProperty, value); }
}
#endregion
private Point _myCenterPoint;
public override Point MyCenterPoint { get => _myCenterPoint; }
public override void Render(DrawingContext drawingContext)
{
double width = ActualWidth;
double height = ActualHeight;
var background = GetBackgrounp();
// 输入连接器的背景
var connectorRect = new Rect(0, 0, width, height);
drawingContext.DrawRectangle(Brushes.Transparent, null, connectorRect);
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY); // 中心坐标
// 绘制连接器的圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
// 定义三角形的间距
double triangleOffsetX = 4; // 三角形与圆形的间距
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
// 绘制三角形
var pathGeometry = new StreamGeometry();
using (var context = pathGeometry.Open())
{
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(background, MyUIFunc.CreateAndFreezePen(), pathGeometry);
}
}
}

View File

@@ -1,84 +0,0 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ExecuteJunctionControl : JunctionControlBase
{
public ExecuteJunctionControl()
{
base.JunctionType = JunctionType.Execute;
this.InvalidateVisual();
}
private Point _myCenterPoint;
public override Point MyCenterPoint { get => _myCenterPoint; }
public override void Render(DrawingContext drawingContext)
{
double width = ActualWidth;
double height = ActualHeight;
var background = GetBackgrounp();
// 绘制边框
//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 connectorRect = new Rect(0, 0, width, height);
drawingContext.DrawRectangle(Brushes.Transparent,null, connectorRect);
//drawingContext.DrawRectangle(Brushes.Transparent, new Pen(background,2), connectorRect);
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY); // 中心坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
// 绘制连接器的圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
// 定义三角形的间距
double triangleOffsetX = 4; // 三角形与圆形的间距
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
// 绘制三角形
var pathGeometry = new StreamGeometry();
using (var context = pathGeometry.Open())
{
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(background, MyUIFunc.CreateAndFreezePen(), 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));
}
}
}

View File

@@ -1,60 +0,0 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class NextStepJunctionControl : JunctionControlBase
{
//public override JunctionType JunctionType { get; } = JunctionType.NextStep;
public NextStepJunctionControl()
{
base.JunctionType = JunctionType.NextStep;
this.InvalidateVisual();
}
private Point _myCenterPoint;
public override Point MyCenterPoint { get => _myCenterPoint; }
public override void Render(DrawingContext drawingContext)
{
double width = ActualWidth;
double height = ActualHeight;
var background = GetBackgrounp();
// 输入连接器的背景
var connectorRect = new Rect(0, 0, width, height);
drawingContext.DrawRectangle(Brushes.Transparent, null, connectorRect);
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY); // 中心坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
// 绘制连接器的圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
// 绘制连接器的圆形部分
//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())
{
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(background, MyUIFunc.CreateAndFreezePen(), pathGeometry);
}
}
}

View File

@@ -1,61 +0,0 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ResultJunctionControl : JunctionControlBase
{
//public override JunctionType JunctionType { get; } = JunctionType.ReturnData;
public ResultJunctionControl()
{
base.JunctionType = JunctionType.ReturnData;
this.InvalidateVisual();
}
private Point _myCenterPoint;
public override Point MyCenterPoint { get => _myCenterPoint; }
public override void Render(DrawingContext drawingContext)
{
double width = ActualWidth;
double height = ActualHeight;
// 输入连接器的背景
var connectorRect = new Rect(0, 0, width, height);
drawingContext.DrawRectangle(Brushes.Transparent, null, connectorRect);
var background = GetBackgrounp();
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
_myCenterPoint = new Point(circleCenterX - connectorSize / 2 , circleCenterY); // 中心坐标
// 绘制连接器的圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
// 定义三角形的间距
double triangleOffsetX = 4; // 三角形与圆形的间距
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
// 绘制三角形
var pathGeometry = new StreamGeometry();
using (var context = pathGeometry.Open())
{
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(background, MyUIFunc.CreateAndFreezePen(), pathGeometry);
}
}
}