破坏性更新,移除了Core/Framework(对应的上下文类移动到了Library)

This commit is contained in:
fengjiayi
2025-01-22 21:09:52 +08:00
parent 652707f980
commit eb1505596a
68 changed files with 1034 additions and 2600 deletions

View File

@@ -4,7 +4,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using Serein.Library;
using Serein.Workbench.Avalonia.Api;
using Serein.Workbench.Avalonia.Custom.Node.Views;
using Serein.Workbench.Avalonia.Custom.Views;
using Serein.Workbench.Avalonia.Model;
using Serein.Workbench.Avalonia.ViewModels;
using System;
using System.Collections.Generic;
@@ -30,11 +30,7 @@ namespace Serein.Workbench.Avalonia.Custom.Node.ViewModels
public NodeModelBase NodeModel { get; set; }
/// <summary>
/// 记录与该节点控件有关的所有连接
/// </summary>
private readonly List<NodeConnectionLineView> connectionControls = new List<NodeConnectionLineView>();
//public NodeControlViewModelBase ViewModel { get; set; }
@@ -42,48 +38,6 @@ namespace Serein.Workbench.Avalonia.Custom.Node.ViewModels
public void SetNodeModel(NodeModelBase nodeModel) => this.NodeModel = nodeModel;
/// <summary>
/// 添加与该节点有关的连接后,记录下来
/// </summary>
/// <param name="connection"></param>
public void AddCnnection(NodeConnectionLineView connection)
{
connectionControls.Add(connection);
}
/// <summary>
/// 删除了连接之后,还需要从节点中的记录移除
/// </summary>
/// <param name="connection"></param>
public void RemoveConnection(NodeConnectionLineView connection)
{
connectionControls.Remove(connection);
//connection.Remote();
}
/// <summary>
/// 删除所有连接
/// </summary>
public void RemoveAllConection()
{
foreach (var connection in this.connectionControls)
{
//connection.Remote();
}
}
/// <summary>
/// 更新与该节点有关的数据
/// </summary>
public void UpdateLocationConnections()
{
foreach (var connection in this.connectionControls)
{
//connection.RefreshLine(); // 主动更新连线位置
}
}
/// <summary>
/// 设置绑定:
/// Canvas.X and Y 画布位置

View File

@@ -21,7 +21,7 @@
<!--调用控制点,方法名称,下一个方法调用控制点-->
<Grid x:Name="HeaderGrid" Grid.Row="0" ColumnDefinitions="auto,*,auto" VerticalAlignment="Center">
<cv:NodeJunctionView Grid.Column="0" JunctionType="Execute" MyNode="{Binding NodeMoel}" Width="30" Height="15" Margin="4,0,2,0" />
<cv:NodeJunctionView x:Name="ExecuteJunctionControl" Grid.Column="0" JunctionType="Execute" MyNode="{Binding NodeMoel}" Width="30" Height="15" Margin="4,0,2,0" />
<StackPanel Grid.Column="1" Grid.RowSpan="2" >
<TextBlock Text="{Binding NodeMoel.DisplayName}" FontSize="17" HorizontalAlignment="Center">
<ToolTip.Tip>
@@ -31,7 +31,7 @@
</ToolTip.Tip>
</TextBlock>
</StackPanel>
<cv:NodeJunctionView Grid.Column="2" JunctionType="NextStep" MyNode="{Binding NodeMoel}" Width="30" Height="15" Margin="2,0,8,0"/>
<cv:NodeJunctionView x:Name="NextStepJunctionControl" Grid.Column="2" JunctionType="NextStep" MyNode="{Binding NodeMoel}" Width="30" Height="15" Margin="2,0,8,0"/>
</Grid>
<!--入参信息-->

View File

@@ -5,10 +5,11 @@ using Serein.Library;
using Serein.NodeFlow.Model;
using Serein.Workbench.Avalonia.Api;
using Serein.Workbench.Avalonia.Custom.Node.ViewModels;
using Serein.Workbench.Avalonia.Custom.Views;
namespace Serein.Workbench.Avalonia.Custom.Node.Views;
public partial class ActionNodeView : NodeControlBase
public partial class ActionNodeView : NodeControlBase, INodeJunction
{
private ActionNodeViewModel _vm;
@@ -20,4 +21,11 @@ public partial class ActionNodeView : NodeControlBase
//DataContext = _vm;
}
public NodeJunctionView ExecuteJunction => this.ExecuteJunctionControl;
public NodeJunctionView NextStepJunction => this.NextStepJunctionControl;
public NodeJunctionView[] ArgDataJunction => throw new System.NotImplementedException();
public NodeJunctionView ReturnDataJunction => throw new System.NotImplementedException();
}

View File

@@ -14,13 +14,62 @@ using System.Threading.Tasks;
namespace Serein.Workbench.Avalonia.Custom.Node.Views
{
public class NodeControlBase : UserControl
public abstract class NodeControlBase : UserControl
{
/// <summary>
/// 记录与该节点控件有关的所有连接
/// </summary>
private readonly List<NodeConnectionLineControl> connectionControls = new List<NodeConnectionLineControl>();
protected NodeControlBase()
{
this.Background = Brushes.Transparent;
}
/// <summary>
/// 添加与该节点有关的连接后,记录下来
/// </summary>
/// <param name="connection"></param>
public void AddConnection(NodeConnectionLineControl connection)
{
connectionControls.Add(connection);
}
/// <summary>
/// 删除了连接之后,还需要从节点中的记录移除
/// </summary>
/// <param name="connection"></param>
public void RemoveConnection(NodeConnectionLineControl connection)
{
connectionControls.Remove(connection);
connection.Remove();
}
/// <summary>
/// 删除所有连接
/// </summary>
public void RemoveAllConection()
{
foreach (var connection in this.connectionControls)
{
connection.Remove();
}
}
/// <summary>
/// 更新与该节点有关的数据
/// </summary>
public void UpdateLocationConnections()
{
foreach (var connection in this.connectionControls)
{
connection.RefreshLineDsiplay(); // 主动更新连线位置
}
}
/// <summary>
/// 放置在某个节点容器中
/// </summary>

View File

@@ -62,7 +62,7 @@ namespace Serein.Workbench.Avalonia.Custom.Views
//visualPen.Freeze(); // Freeze以提高性能
linkSize = 4; // 整线条粗细
int zIndex = 999999;
int zIndex = -999999;
this.ZIndex = zIndex;
//Panel.SetZIndex(this, zIndex); // 置底
@@ -111,6 +111,15 @@ namespace Serein.Workbench.Avalonia.Custom.Views
this.leftPoint = left;
InvalidateVisual(); // 触发重绘
}
/// <summary>
/// 刷新颜色
/// </summary>
/// <param name="brush"></param>
public void UpdateColor(Brush brush )
{
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
InvalidateVisual(); // 触发重绘
}
/// <summary>
/// 控件重绘事件

View File

@@ -1,279 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Media;
using Avalonia.VisualTree;
using Serein.Library;
using Serein.Script.Node;
using Serein.Workbench.Avalonia.Extension;
using Serein.Workbench.Avalonia.Services;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Color = Avalonia.Media.Color;
using Point = Avalonia.Point;
namespace Serein.Workbench.Avalonia.Custom.Views
{
public class NodeConnectionLineView
{
/// <summary>
/// 线条类别(方法调用)
/// </summary>
public ConnectionInvokeType ConnectionInvokeType { get; set; } = ConnectionInvokeType.IsSucceed;
/// <summary>
/// 线条类别(参数传递)
/// </summary>
public ConnectionArgSourceType ConnectionArgSourceType { get; set; } = ConnectionArgSourceType.GetOtherNodeData;
/// <summary>
/// 画布
/// </summary>
private Canvas Canvas;
/// <summary>
/// 连接线的起点
/// </summary>
private NodeJunctionView? LeftNodeJunctionView;
/// <summary>
/// 连接线的终点
/// </summary>
private NodeJunctionView? RightNodeJunctionView;
/// <summary>
/// 连接时显示的线
/// </summary>
public ConnectionLineShape? ConnectionLineShape { get; private set; }
public NodeConnectionLineView(Canvas canvas,
NodeJunctionView? leftNodeJunctionView,
NodeJunctionView? rightNodeJunctionView)
{
this.Canvas = canvas;
this.LeftNodeJunctionView = leftNodeJunctionView;
this.RightNodeJunctionView = rightNodeJunctionView;
}
/// <summary>
/// 连接到终点
/// </summary>
/// <param name="endNodeJunctionView"></param>
public void ToEnd(NodeJunctionView endNodeJunctionView)
{
if((endNodeJunctionView.JunctionType == JunctionType.NextStep
|| endNodeJunctionView.JunctionType == JunctionType.ReturnData)
&& RightNodeJunctionView is not null
/*&& LeftNodeJunctionView is null*/
/*&& !LeftNodeJunctionView.Equals(endNodeJunctionView)*/)
{
LeftNodeJunctionView = endNodeJunctionView;
RefreshLineDsiplay();
return;
}
else if ((endNodeJunctionView.JunctionType == JunctionType.Execute
|| endNodeJunctionView.JunctionType == JunctionType.ArgData)
&& LeftNodeJunctionView is not null
/*&& RightNodeJunctionView is null*/
/*&& !RightNodeJunctionView.Equals(endNodeJunctionView)*/)
{
RightNodeJunctionView = endNodeJunctionView;
RefreshLineDsiplay();
return;
}
//
//var leftPoint = GetPoint(LeftNodeJunctionView);
//var rightPoint = GetPoint(RightNodeJunctionView);
//var brush = GetBackgrounp();
//ConnectionLineShape.UpdatePoint(leftPoint, rightPoint);
//CreateLineShape(startPoint, endPoint, brush);
}
/// <summary>
/// 刷新线的显示
/// </summary>
public void RefreshLineDsiplay()
{
if(LeftNodeJunctionView is null || RightNodeJunctionView is null)
{
return;
}
var leftPoint = GetPoint(LeftNodeJunctionView);
var rightPoint = GetPoint(RightNodeJunctionView);
if (ConnectionLineShape is null)
{
Debug.WriteLine("创建");
CreateLineShape(leftPoint, rightPoint, GetBackgrounp());
}
else
{
Debug.WriteLine("刷新");
var brush = GetBackgrounp();
ConnectionLineShape.UpdatePoint( leftPoint, rightPoint, brush);
}
}
/// <summary>
/// 刷新临时线的显示
/// </summary>
public void RefreshRightPointOfTempLineDsiplay(Point rightPoint)
{
if(ConnectionLineShape is not null)
{
var brush = GetBackgrounp();
ConnectionLineShape.UpdateRightPoint(rightPoint, brush);
return;
}
if (LeftNodeJunctionView is not null)
{
var leftPoint = GetPoint(LeftNodeJunctionView);
var brush = GetBackgrounp();
CreateLineShape(leftPoint, rightPoint, brush);
}
}
/// <summary>
/// 刷新临时线的显示
/// </summary>
public void RefreshLeftPointOfTempLineDsiplay(Point leftPoint)
{
if(ConnectionLineShape is not null)
{
var brush = GetBackgrounp();
ConnectionLineShape.UpdateLeftPoints(leftPoint, brush);
return;
}
if (RightNodeJunctionView is not null)
{
var rightPoint = GetPoint(RightNodeJunctionView);
var brush = GetBackgrounp();
CreateLineShape(leftPoint, rightPoint, brush);
}
}
private static Point defaultPoint = new Point(0, 0);
int count;
private Point GetPoint(NodeJunctionView nodeJunctionView)
{
var junctionSize = nodeJunctionView.GetTransformedBounds()!.Value.Bounds.Size;
Point junctionPoint;
if (nodeJunctionView.JunctionType == JunctionType.ArgData || nodeJunctionView.JunctionType == JunctionType.Execute)
{
junctionPoint = new Point(junctionSize.Width / 2 - 11, junctionSize.Height / 2); // 选择左侧
}
else
{
junctionPoint = new Point(junctionSize.Width / 2 + 11, junctionSize.Height / 2); // 选择右侧
}
if (nodeJunctionView.TranslatePoint(junctionPoint, Canvas) is Point point)
{
//myData.StartPoint = point;
return point;
}
else
{
return defaultPoint;
}
//var point = nodeJunctionView.TranslatePoint(defaultPoint , Canvas);
//if(point is null)
//{
// return defaultPoint;
//}
//else
//{
// return point.Value;
// }
}
private void CreateLineShape(Point leftPoint, Point rightPoint, Brush brush)
{
ConnectionLineShape = new ConnectionLineShape(leftPoint, rightPoint, brush);
Canvas.Children.Add(ConnectionLineShape);
}
private JunctionOfConnectionType GetConnectionType()
{
return LeftNodeJunctionView.JunctionType.ToConnectyionType();
}
/// <summary>
/// 获取背景颜色
/// </summary>
/// <returns></returns>
public Brush GetBackgrounp()
{
if(LeftNodeJunctionView is null || RightNodeJunctionView is null)
{
return new SolidColorBrush(Color.Parse("#FF0000")); // 没有终点
}
// 判断连接控制点是否匹配
if (!IsCanConnected())
{
return new SolidColorBrush(Color.Parse("#FF0000"));
}
if (GetConnectionType() == JunctionOfConnectionType.Invoke)
{
return ConnectionInvokeType.ToLineColor(); // 调用
}
else
{
return ConnectionArgSourceType.ToLineColor(); // 参数
}
}
public bool IsCanConnected()
{
if (LeftNodeJunctionView is null
|| RightNodeJunctionView is null)
{
return false;
}
if (LeftNodeJunctionView?.MyNode is null
|| LeftNodeJunctionView.MyNode.Equals(RightNodeJunctionView.MyNode))
return false;
if (LeftNodeJunctionView.JunctionType.IsCanConnection(RightNodeJunctionView.JunctionType))
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 移除线
/// </summary>
public void Remove()
{
if(ConnectionLineShape is null)
{
return;
}
Canvas.Children.Remove(ConnectionLineShape);
}
}
}

View File

@@ -9,6 +9,7 @@ using Newtonsoft.Json.Linq;
using Serein.Library;
using Serein.Library.Utils;
using Serein.Workbench.Avalonia.Api;
using Serein.Workbench.Avalonia.Custom.Node.Views;
using Serein.Workbench.Avalonia.Custom.ViewModels;
using Serein.Workbench.Avalonia.Extension;
using Serein.Workbench.Avalonia.Services;
@@ -51,7 +52,7 @@ public partial class NodeContainerView : UserControl
/// <summary>
/// 当前选取的控件
/// </summary>
private readonly List<Control> selectNodeControls = [];
private readonly List<NodeControlBase> selectNodeControls = [];
/// <summary>
/// 记录开始拖动节点控件时的鼠标位置
@@ -98,7 +99,7 @@ public partial class NodeContainerView : UserControl
{
IsCanvasDragging = false;
IsControlDragging = false;
nodeOperationService.ConnectingData.Reset();
nodeOperationService.ConnectingManage.Reset();
}
};
#endregion
@@ -192,7 +193,7 @@ public partial class NodeContainerView : UserControl
private void NodeContainerView_PointerMoved(object? sender, PointerEventArgs e)
{
// 是否正在连接
var myData = nodeOperationService.ConnectingData;
var myData = nodeOperationService.ConnectingManage;
if (myData.IsCreateing)
{
var isPass = e.JudgePointer(sender, PointerType.Mouse, p => p.IsLeftButtonPressed);
@@ -318,7 +319,7 @@ public partial class NodeContainerView : UserControl
}
/// <summary>
/// 控件的鼠标键按下事件,启动拖动操作。
/// 控件的鼠标键按下事件,启动拖动操作。
/// </summary>
private void Block_MouseLeftButtonDown(object? sender, PointerPressedEventArgs e)
{
@@ -328,10 +329,11 @@ public partial class NodeContainerView : UserControl
return;
}
if (sender is Control nodeControl)
if (sender is NodeControlBase nodeControl)
{
IsControlDragging = true;
startControlDragPoint = GetPositionOfCanvas(e); // 记录鼠标按下时的位置
e.Handled = true; // 防止事件传播影响其他控件
}
@@ -343,7 +345,7 @@ public partial class NodeContainerView : UserControl
private void Block_MouseMove(object? sender, PointerEventArgs e)
{
if (sender is not Control nodeControl)
if (sender is not NodeControlBase nodeControl)
{
return;
}
@@ -365,6 +367,7 @@ public partial class NodeContainerView : UserControl
double newLeft = Canvas.GetLeft(nodeControl) + deltaX; // 新的左边距
double newTop = Canvas.GetTop(nodeControl) + deltaY; // 新的上边距
DragControl(nodeControl, newLeft, newTop);
nodeControl.UpdateLocationConnections();
}
// 批量移动
else
@@ -401,10 +404,10 @@ public partial class NodeContainerView : UserControl
}
// 更新节点之间线的连接位置
//foreach (var nodeControl in selectNodeControls)
//{
// //nodeControl.UpdateLocationConnections();
//}
foreach (var item in selectNodeControls)
{
item.UpdateLocationConnections();
}
}
startControlDragPoint = currentPosition; // 更新起始点位置
}

View File

@@ -7,6 +7,7 @@ using Serein.Library.Api;
using Serein.Workbench.Avalonia.Api;
using Serein.Workbench.Avalonia.Extension;
using System;
using System.Diagnostics;
using Color = Avalonia.Media.Color;
using Point = Avalonia.Point;
@@ -76,7 +77,7 @@ public class NodeJunctionView : TemplatedControl
private void NodeJunctionView_PointerMoved(object? sender, PointerEventArgs e)
{
if (!nodeOperationService.ConnectingData.IsCreateing)
if (!nodeOperationService.ConnectingManage.IsCreateing)
return;
if (nodeOperationService.MainCanvas is not InputElement inputElement)
return;
@@ -87,7 +88,7 @@ public class NodeJunctionView : TemplatedControl
}
else
{
var oldNj = nodeOperationService.ConnectingData.CurrentJunction;
var oldNj = nodeOperationService.ConnectingManage.CurrentJunction;
if (oldNj is not null)
{
oldNj.IsPreviewing = false;
@@ -98,7 +99,7 @@ public class NodeJunctionView : TemplatedControl
private void RefreshDisplay(NodeJunctionView junctionView)
{
var oldNj = nodeOperationService.ConnectingData.CurrentJunction;
var oldNj = nodeOperationService.ConnectingManage.CurrentJunction;
if (oldNj is not null )
{
if (junctionView.Equals(oldNj))
@@ -108,11 +109,11 @@ public class NodeJunctionView : TemplatedControl
oldNj.IsPreviewing = false;
oldNj.InvalidateVisual();
}
nodeOperationService.ConnectingData.CurrentJunction = junctionView;
if (!this.Equals(junctionView))
nodeOperationService.ConnectingManage.CurrentJunction = junctionView;
if (!this.Equals(junctionView) && nodeOperationService.ConnectingManage.IsCanConnected())
{
nodeOperationService.ConnectingData.TempLine?.ToEnd(junctionView);
Debug.WriteLine("ok");
nodeOperationService.ConnectingManage.TempLine?.ToEnd(junctionView);
}
junctionView.IsPreviewing = true;
junctionView.InvalidateVisual();
@@ -132,12 +133,12 @@ public class NodeJunctionView : TemplatedControl
private void NodeJunctionView_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
CheckJunvtion();
nodeOperationService.ConnectingData.Reset();
nodeOperationService.ConnectingManage.Reset();
}
private void CheckJunvtion()
{
var myData = nodeOperationService.ConnectingData;
var myData = nodeOperationService.ConnectingManage;
if(myData.StartJunction is null || myData.CurrentJunction is null)
{
return;
@@ -246,7 +247,7 @@ public class NodeJunctionView : TemplatedControl
/// <returns></returns>
protected IBrush GetBackgrounp()
{
var myData = nodeOperationService.ConnectingData;
var myData = nodeOperationService.ConnectingManage;
if (IsPreviewing == false || !myData.IsCreateing )
{
return new SolidColorBrush(Color.Parse("#76ABEE"));