mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-14 21:46:35 +08:00
修改了无法保存项目文件的bug
This commit is contained in:
@@ -21,6 +21,7 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Threading;
|
||||
using DataObject = System.Windows.DataObject;
|
||||
|
||||
namespace Serein.WorkBench
|
||||
@@ -50,12 +51,6 @@ namespace Serein.WorkBench
|
||||
/// </summary>
|
||||
private readonly LogWindow logWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 节点的命名空间
|
||||
/// </summary>
|
||||
public const string NodeSpaceName = $"{nameof(Serein)}.{nameof(Serein.NodeFlow)}.{nameof(Serein.NodeFlow.Model)}";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 流程运行环境
|
||||
/// </summary>
|
||||
@@ -82,7 +77,7 @@ namespace Serein.WorkBench
|
||||
/// <summary>
|
||||
/// 拖动创建节点控件时的鼠标位置
|
||||
/// </summary>
|
||||
private Point canvasDropPosition;
|
||||
// private Point canvasDropPosition;
|
||||
|
||||
/// <summary>
|
||||
/// 记录拖动开始时的鼠标位置
|
||||
@@ -138,6 +133,7 @@ namespace Serein.WorkBench
|
||||
{
|
||||
ViewModel = new MainWindowViewModel(this);
|
||||
FlowEnvironment = ViewModel.FlowEnvironment;
|
||||
InitFlowEvent();
|
||||
|
||||
InitializeComponent();
|
||||
logWindow = new LogWindow();
|
||||
@@ -145,14 +141,23 @@ namespace Serein.WorkBench
|
||||
// 重定向 Console 输出
|
||||
var logTextWriter = new LogTextWriter(WriteLog);
|
||||
Console.SetOut(logTextWriter);
|
||||
InitFlowEvent();
|
||||
InitUI();
|
||||
|
||||
var project = App.FData;
|
||||
if (project == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeCanvas(project.Basic.Canvas.Width, project.Basic.Canvas.Lenght);// 设置画布大小
|
||||
FlowEnvironment.LoadProject(project, App.FileDataPath); // 加载项目
|
||||
}
|
||||
|
||||
private void InitFlowEvent()
|
||||
{
|
||||
FlowEnvironment.OnDllLoad += FlowEnvironment_DllLoadEvent;
|
||||
FlowEnvironment.OnLoadNode += FlowEnvironment_NodeLoadEvent;
|
||||
// FlowEnvironment.OnLoadNode += FlowEnvironment_NodeLoadEvent;
|
||||
FlowEnvironment.OnProjectLoaded += FlowEnvironment_OnProjectLoaded;
|
||||
FlowEnvironment.OnStartNodeChange += FlowEnvironment_StartNodeChangeEvent;
|
||||
FlowEnvironment.OnNodeConnectChange += FlowEnvironment_NodeConnectChangeEvemt;
|
||||
FlowEnvironment.OnNodeCreate += FlowEnvironment_NodeCreateEvent;
|
||||
@@ -161,6 +166,7 @@ namespace Serein.WorkBench
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void InitUI()
|
||||
{
|
||||
canvasTransformGroup = new TransformGroup();
|
||||
@@ -171,22 +177,41 @@ namespace Serein.WorkBench
|
||||
canvasTransformGroup.Children.Add(translateTransform);
|
||||
|
||||
FlowChartCanvas.RenderTransform = canvasTransformGroup;
|
||||
|
||||
FlowChartCanvas.RenderTransformOrigin = new Point(0.5, 0.5);
|
||||
}
|
||||
|
||||
#region Main窗体加载方法
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
}
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
logWindow.Close();
|
||||
System.Windows.Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
private void Window_ContentRendered(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var connection in Connections)
|
||||
{
|
||||
connection.Refresh();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
public void WriteLog(string message)
|
||||
{
|
||||
logWindow.AppendText(message);
|
||||
}
|
||||
|
||||
#region 运行环境事件
|
||||
private void FlowEnvironment_OnProjectLoaded(ProjectLoadedEventArgs eventArgs)
|
||||
{
|
||||
//foreach(var connection in Connections)
|
||||
//{
|
||||
// connection.Refresh();
|
||||
//}
|
||||
Console.WriteLine((FlowChartStackPanel.ActualWidth, FlowChartStackPanel.ActualHeight));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 运行完成
|
||||
/// </summary>
|
||||
@@ -202,27 +227,30 @@ namespace Serein.WorkBench
|
||||
/// </summary>
|
||||
private void FlowEnvironment_DllLoadEvent(LoadDLLEventArgs eventArgs)
|
||||
{
|
||||
Assembly assembly = eventArgs.Assembly;
|
||||
List<MethodDetails> methodDetailss = eventArgs.MethodDetailss;
|
||||
this.Dispatcher.Invoke(() => {
|
||||
Assembly assembly = eventArgs.Assembly;
|
||||
List<MethodDetails> methodDetailss = eventArgs.MethodDetailss;
|
||||
|
||||
var dllControl = new DllControl
|
||||
{
|
||||
Header = "DLL name : " + assembly.GetName().Name // 设置控件标题为程序集名称
|
||||
};
|
||||
|
||||
foreach (var methodDetails in methodDetailss)
|
||||
{
|
||||
switch (methodDetails.MethodDynamicType)
|
||||
var dllControl = new DllControl
|
||||
{
|
||||
case Library.Enums.NodeType.Action:
|
||||
dllControl.AddAction(methodDetails.Clone()); // 添加动作类型到控件
|
||||
break;
|
||||
case Library.Enums.NodeType.Flipflop:
|
||||
dllControl.AddFlipflop(methodDetails.Clone()); // 添加触发器方法到控件
|
||||
break;
|
||||
Header = "DLL name : " + assembly.GetName().Name // 设置控件标题为程序集名称
|
||||
};
|
||||
|
||||
foreach (var methodDetails in methodDetailss)
|
||||
{
|
||||
switch (methodDetails.MethodDynamicType)
|
||||
{
|
||||
case Library.Enums.NodeType.Action:
|
||||
dllControl.AddAction(methodDetails.Clone()); // 添加动作类型到控件
|
||||
break;
|
||||
case Library.Enums.NodeType.Flipflop:
|
||||
dllControl.AddFlipflop(methodDetails.Clone()); // 添加触发器方法到控件
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DllStackPanel.Children.Add(dllControl); // 将控件添加到界面上显示
|
||||
DllStackPanel.Children.Add(dllControl); // 将控件添加到界面上显示
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -230,34 +258,35 @@ namespace Serein.WorkBench
|
||||
/// </summary>
|
||||
/// <param name="nodeInfo"></param>
|
||||
/// <param name="methodDetailss"></param>
|
||||
private void FlowEnvironment_NodeLoadEvent(LoadNodeEventArgs eventArgs)
|
||||
{
|
||||
if (!eventArgs.IsSucceed)
|
||||
{
|
||||
MessageBox.Show(eventArgs.ErrorTips);
|
||||
return;
|
||||
}
|
||||
NodeInfo nodeInfo = eventArgs.NodeInfo;
|
||||
MethodDetails methodDetailss = eventArgs.MethodDetailss;
|
||||
//private void FlowEnvironment_NodeLoadEvent(LoadNodeEventArgs eventArgs)
|
||||
//{
|
||||
// if (!eventArgs.IsSucceed)
|
||||
// {
|
||||
// MessageBox.Show(eventArgs.ErrorTips);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 创建对应的实例(包含NodeModel,NodeControl,NodeControlViewModel)
|
||||
NodeControlBase? nodeControl = CreateNodeControlOfNodeInfo(nodeInfo, methodDetailss);
|
||||
if (nodeControl == null)
|
||||
{
|
||||
WriteLog($"无法为节点类型创建节点控件: {nodeInfo.MethodName}\r\n");
|
||||
return;
|
||||
// ConfigureNodeControl(nodeInfo, nodeControl, nodeControls, regionControls);
|
||||
}
|
||||
|
||||
// 判断是否属于区域控件,如果是,则加载区域子项
|
||||
if (nodeControl is ActionRegionControl || nodeControl is ConditionRegionControl)
|
||||
{
|
||||
AddNodeControlInRegeionControl(nodeControl, nodeInfo.ChildNodes);
|
||||
}
|
||||
// NodeInfo nodeInfo = eventArgs.NodeInfo;
|
||||
// MethodDetails methodDetailss = eventArgs.MethodDetailss;
|
||||
|
||||
NodeControls.TryAdd(nodeInfo.Guid, nodeControl); // 存放对应的控件
|
||||
PlaceNodeOnCanvas(nodeControl, nodeInfo.Position.X, nodeInfo.Position.Y); // 配置节点,并放置在画布上
|
||||
}
|
||||
// // 创建对应的实例(包含NodeModel,NodeControl,NodeControlViewModel)
|
||||
// NodeControlBase? nodeControl = CreateNodeControlOfNodeInfo(nodeInfo, methodDetailss);
|
||||
// if (nodeControl == null)
|
||||
// {
|
||||
// WriteLog($"无法为节点类型创建节点控件: {nodeInfo.MethodName}\r\n");
|
||||
// return;
|
||||
// // ConfigureNodeControl(nodeInfo, nodeControl, nodeControls, regionControls);
|
||||
// }
|
||||
|
||||
// // 判断是否属于区域控件,如果是,则加载区域子项
|
||||
// // if (nodeControl is ActionRegionControl || nodeControl is ConditionRegionControl)
|
||||
// // {
|
||||
// // AddNodeControlInRegeionControl(nodeControl, nodeInfo.ChildNodes);
|
||||
// // }
|
||||
|
||||
// NodeControls.TryAdd(nodeInfo.Guid, nodeControl); // 存放对应的控件
|
||||
// PlaceNodeOnCanvas(nodeControl, nodeInfo.Position.X, nodeInfo.Position.Y); // 配置节点,并放置在画布上
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 节点连接关系变更
|
||||
@@ -267,40 +296,48 @@ namespace Serein.WorkBench
|
||||
/// <param name="connectionType"></param>
|
||||
private void FlowEnvironment_NodeConnectChangeEvemt(NodeConnectChangeEventArgs eventArgs)
|
||||
{
|
||||
string fromNodeGuid = eventArgs.FromNodeGuid;
|
||||
string toNodeGuid = eventArgs.ToNodeGuid;
|
||||
if (!NodeControls.TryGetValue(fromNodeGuid, out var fromNode) || !NodeControls.TryGetValue(toNodeGuid, out var toNode))
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
ConnectionType connectionType = eventArgs.ConnectionType;
|
||||
if(eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Create)
|
||||
{
|
||||
// 添加连接
|
||||
var connection = new Connection
|
||||
string fromNodeGuid = eventArgs.FromNodeGuid;
|
||||
string toNodeGuid = eventArgs.ToNodeGuid;
|
||||
if (!NodeControls.TryGetValue(fromNodeGuid, out var fromNode) || !NodeControls.TryGetValue(toNodeGuid, out var toNode))
|
||||
{
|
||||
Start = fromNode,
|
||||
End = toNode,
|
||||
Type = connectionType
|
||||
};
|
||||
|
||||
BsControl.Draw(FlowChartCanvas, connection); // 添加贝塞尔曲线显示
|
||||
ConfigureLineContextMenu(connection); // 设置连接右键事件
|
||||
Connections.Add(connection);
|
||||
EndConnection();
|
||||
}
|
||||
else if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Remote)
|
||||
{
|
||||
// 需要移除连接
|
||||
var removeConnections = Connections.Where(c => c.Start.ViewModel.Node.Guid.Equals(fromNodeGuid)
|
||||
&& c.End.ViewModel.Node.Guid.Equals(toNodeGuid))
|
||||
.ToList();
|
||||
foreach(var connection in removeConnections)
|
||||
{
|
||||
connection.RemoveFromCanvas(FlowChartCanvas);
|
||||
Connections.Remove(connection);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ConnectionType connectionType = eventArgs.ConnectionType;
|
||||
if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Create)
|
||||
{
|
||||
lock (Connections)
|
||||
{
|
||||
// 添加连接
|
||||
var connection = new Connection
|
||||
{
|
||||
Start = fromNode,
|
||||
End = toNode,
|
||||
Type = connectionType
|
||||
};
|
||||
|
||||
BsControl.Draw(FlowChartCanvas, connection); // 添加贝塞尔曲线显示
|
||||
ConfigureLineContextMenu(connection); // 设置连接右键事件
|
||||
Connections.Add(connection);
|
||||
EndConnection();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Remote)
|
||||
{
|
||||
// 需要移除连接
|
||||
var removeConnections = Connections.Where(c => c.Start.ViewModel.Node.Guid.Equals(fromNodeGuid)
|
||||
&& c.End.ViewModel.Node.Guid.Equals(toNodeGuid))
|
||||
.ToList();
|
||||
foreach (var connection in removeConnections)
|
||||
{
|
||||
connection.RemoveFromCanvas(FlowChartCanvas);
|
||||
Connections.Remove(connection);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -309,14 +346,16 @@ namespace Serein.WorkBench
|
||||
/// <param name="eventArgs"></param>
|
||||
private void FlowEnvironment_NodeRemoteEvent(NodeRemoteEventArgs eventArgs)
|
||||
{
|
||||
var nodeGuid = eventArgs.NodeGuid;
|
||||
if (!NodeControls.TryGetValue(nodeGuid, out var nodeControl))
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
FlowChartCanvas.Children.Remove(nodeControl);
|
||||
NodeControls.Remove(nodeControl.ViewModel.Node.Guid);
|
||||
|
||||
var nodeGuid = eventArgs.NodeGuid;
|
||||
if (!NodeControls.TryGetValue(nodeGuid, out var nodeControl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
FlowChartCanvas.Children.Remove(nodeControl);
|
||||
NodeControls.Remove(nodeControl.ViewModel.Node.Guid);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -326,35 +365,52 @@ namespace Serein.WorkBench
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void FlowEnvironment_NodeCreateEvent(NodeCreateEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.NodeModel is not NodeModelBase nodeModelBase)
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (eventArgs.NodeModel is not NodeModelBase nodeModelBase)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建对应控件
|
||||
NodeControlBase? nodeControl = nodeModelBase.ControlType switch
|
||||
{
|
||||
NodeControlType.Action => CreateNodeControl<ActionNodeControl, ActionNodeControlViewModel>(nodeModelBase), //typeof(ActionNodeControl),
|
||||
NodeControlType.Flipflop => CreateNodeControl<FlipflopNodeControl, FlipflopNodeControlViewModel>(nodeModelBase),
|
||||
NodeControlType.ExpCondition => CreateNodeControl<ConditionNodeControl, ConditionNodeControlViewModel>(nodeModelBase),
|
||||
NodeControlType.ExpOp => CreateNodeControl<ExpOpNodeControl, ExpOpNodeViewModel>(nodeModelBase),
|
||||
NodeControlType.ConditionRegion => CreateNodeControl<ConditionRegionControl, ConditionRegionNodeControlViewModel>(nodeModelBase),
|
||||
_ => null,
|
||||
};
|
||||
if(nodeControl == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// MethodDetails methodDetailss = eventArgs.MethodDetailss;
|
||||
Position position = eventArgs.Position;
|
||||
|
||||
|
||||
NodeControls.TryAdd(nodeModelBase.Guid, nodeControl);
|
||||
|
||||
if (!TryPlaceNodeInRegion(nodeControl))
|
||||
{
|
||||
PlaceNodeOnCanvas(nodeControl, canvasDropPosition.X, canvasDropPosition.Y);
|
||||
}
|
||||
// 创建对应控件
|
||||
NodeControlBase? nodeControl = nodeModelBase.ControlType switch
|
||||
{
|
||||
NodeControlType.Action => CreateNodeControl<ActionNodeControl, ActionNodeControlViewModel>(nodeModelBase), //typeof(ActionNodeControl),
|
||||
NodeControlType.Flipflop => CreateNodeControl<FlipflopNodeControl, FlipflopNodeControlViewModel>(nodeModelBase),
|
||||
NodeControlType.ExpCondition => CreateNodeControl<ConditionNodeControl, ConditionNodeControlViewModel>(nodeModelBase),
|
||||
NodeControlType.ExpOp => CreateNodeControl<ExpOpNodeControl, ExpOpNodeViewModel>(nodeModelBase),
|
||||
NodeControlType.ConditionRegion => CreateNodeControl<ConditionRegionControl, ConditionRegionNodeControlViewModel>(nodeModelBase),
|
||||
_ => null,
|
||||
};
|
||||
if (nodeControl == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
NodeControls.TryAdd(nodeModelBase.Guid, nodeControl);
|
||||
|
||||
if (eventArgs.IsAddInRegion && NodeControls.TryGetValue(eventArgs.RegeionGuid, out NodeControlBase? regionControl))
|
||||
{
|
||||
if (regionControl is not null)
|
||||
{
|
||||
TryPlaceNodeInRegion(regionControl, nodeControl);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TryPlaceNodeInRegion(nodeControl, position))
|
||||
{
|
||||
PlaceNodeOnCanvas(nodeControl, position.X, position.Y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -365,29 +421,32 @@ namespace Serein.WorkBench
|
||||
/// <param name="newNodeGuid"></param>
|
||||
private void FlowEnvironment_StartNodeChangeEvent(StartNodeChangeEventArgs eventArgs)
|
||||
{
|
||||
string oldNodeGuid = eventArgs.OldNodeGuid;
|
||||
string newNodeGuid = eventArgs.NewNodeGuid;
|
||||
if (!NodeControls.TryGetValue(newNodeGuid, out var newStartNodeControl))
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (newStartNodeControl == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(oldNodeGuid))
|
||||
{
|
||||
NodeControls.TryGetValue(oldNodeGuid, out var oldStartNodeControl);
|
||||
if (oldStartNodeControl != null)
|
||||
string oldNodeGuid = eventArgs.OldNodeGuid;
|
||||
string newNodeGuid = eventArgs.NewNodeGuid;
|
||||
if (!NodeControls.TryGetValue(newNodeGuid, out var newStartNodeControl))
|
||||
{
|
||||
oldStartNodeControl.BorderBrush = Brushes.Black;
|
||||
oldStartNodeControl.BorderThickness = new Thickness(0);
|
||||
return;
|
||||
}
|
||||
if (newStartNodeControl == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(oldNodeGuid))
|
||||
{
|
||||
NodeControls.TryGetValue(oldNodeGuid, out var oldStartNodeControl);
|
||||
if (oldStartNodeControl != null)
|
||||
{
|
||||
oldStartNodeControl.BorderBrush = Brushes.Black;
|
||||
oldStartNodeControl.BorderThickness = new Thickness(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
newStartNodeControl.BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#04FC10"));
|
||||
newStartNodeControl.BorderThickness = new Thickness(2);
|
||||
newStartNodeControl.BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#04FC10"));
|
||||
newStartNodeControl.BorderThickness = new Thickness(2);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -396,31 +455,7 @@ namespace Serein.WorkBench
|
||||
|
||||
|
||||
#region 加载 DynamicNodeFlow 文件
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var project = App.FData;
|
||||
if (project == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeCanvas(project.Basic.canvas.width, project.Basic.canvas.lenght);// 设置画布大小
|
||||
FlowEnvironment.LoadProject(project, App.FileDataPath); // 加载项目
|
||||
|
||||
|
||||
//LoadDll(project); // 加载DLL
|
||||
//LoadNodeControls(project); // 加载节点
|
||||
|
||||
//var startNode = nodeControls.Values.FirstOrDefault(control => control.ViewModel.Node.Guid.Equals(project.StartNode));
|
||||
//var startNodeGuid = nodeControls.Keys.FirstOrDefault(guid => guid.Equals(project.StartNode));
|
||||
//if (!string.IsNullOrEmpty(startNodeGuid))
|
||||
//{
|
||||
// FlowEnvironment.SetStartNode(startNodeGuid);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 运行环节加载了项目文件,需要创建节点控件
|
||||
/// </summary>
|
||||
@@ -433,17 +468,17 @@ namespace Serein.WorkBench
|
||||
// 创建控件实例
|
||||
NodeControlBase nodeControl = nodeInfo.Type switch
|
||||
{
|
||||
$"{NodeSpaceName}.{nameof(SingleActionNode)}" =>
|
||||
$"{NodeStaticConfig.NodeSpaceName}.{nameof(SingleActionNode)}" =>
|
||||
CreateNodeControl<SingleActionNode, ActionNodeControl, ActionNodeControlViewModel>(methodDetailss),// 动作节点控件
|
||||
$"{NodeSpaceName}.{nameof(SingleFlipflopNode)}" =>
|
||||
$"{NodeStaticConfig.NodeSpaceName}.{nameof(SingleFlipflopNode)}" =>
|
||||
CreateNodeControl<SingleFlipflopNode, FlipflopNodeControl, FlipflopNodeControlViewModel>(methodDetailss), // 触发器节点控件
|
||||
|
||||
$"{NodeSpaceName}.{nameof(SingleConditionNode)}" =>
|
||||
$"{NodeStaticConfig.NodeSpaceName}.{nameof(SingleConditionNode)}" =>
|
||||
CreateNodeControl<SingleConditionNode, ConditionNodeControl, ConditionNodeControlViewModel>(), // 条件表达式控件
|
||||
$"{NodeSpaceName}.{nameof(SingleExpOpNode)}" =>
|
||||
$"{NodeStaticConfig.NodeSpaceName}.{nameof(SingleExpOpNode)}" =>
|
||||
CreateNodeControl<SingleExpOpNode, ExpOpNodeControl, ExpOpNodeViewModel>(), // 操作表达式控件
|
||||
|
||||
$"{NodeSpaceName}.{nameof(CompositeConditionNode)}" =>
|
||||
$"{NodeStaticConfig.NodeSpaceName}.{nameof(CompositeConditionNode)}" =>
|
||||
CreateNodeControl<CompositeConditionNode, ConditionRegionControl, ConditionRegionNodeControlViewModel>(), // 条件区域控件
|
||||
_ => throw new NotImplementedException($"非预期的节点类型{nodeInfo.Type}"),
|
||||
};
|
||||
@@ -755,13 +790,14 @@ namespace Serein.WorkBench
|
||||
/// <param name="e"></param>
|
||||
private void FlowChartCanvas_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
canvasDropPosition = e.GetPosition(FlowChartCanvas); // 更新画布落点
|
||||
var canvasDropPosition = e.GetPosition(FlowChartCanvas); // 更新画布落点
|
||||
Position position = new Position(canvasDropPosition.X, canvasDropPosition.Y);
|
||||
if (e.Data.GetDataPresent(MouseNodeType.CreateDllNodeInCanvas))
|
||||
{
|
||||
if (e.Data.GetData(MouseNodeType.CreateDllNodeInCanvas) is MoveNodeData nodeData)
|
||||
{
|
||||
// 创建DLL文件的节点对象
|
||||
FlowEnvironment.CreateNode(nodeData.NodeControlType, nodeData.MethodDetails);
|
||||
FlowEnvironment.CreateNode(nodeData.NodeControlType, position, nodeData.MethodDetails);
|
||||
}
|
||||
}
|
||||
else if (e.Data.GetDataPresent(MouseNodeType.CreateBaseNodeInCanvas))
|
||||
@@ -778,7 +814,7 @@ namespace Serein.WorkBench
|
||||
if(nodeControlType != NodeControlType.None)
|
||||
{
|
||||
// 创建基础节点对象
|
||||
FlowEnvironment.CreateNode(nodeControlType);
|
||||
FlowEnvironment.CreateNode(nodeControlType, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,9 +828,10 @@ namespace Serein.WorkBench
|
||||
/// <param name="dropPosition"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryPlaceNodeInRegion(NodeControlBase nodeControl)
|
||||
private bool TryPlaceNodeInRegion(NodeControlBase nodeControl, Position position)
|
||||
{
|
||||
HitTestResult hitTestResult = VisualTreeHelper.HitTest(FlowChartCanvas, canvasDropPosition);
|
||||
var point = new Point(position.X, position.Y);
|
||||
HitTestResult hitTestResult = VisualTreeHelper.HitTest(FlowChartCanvas, point);
|
||||
if (hitTestResult != null && hitTestResult.VisualHit is UIElement hitElement)
|
||||
{
|
||||
// 准备放置条件表达式控件
|
||||
@@ -803,10 +840,12 @@ namespace Serein.WorkBench
|
||||
ConditionRegionControl conditionRegion = GetParentOfType<ConditionRegionControl>(hitElement);
|
||||
if (conditionRegion != null)
|
||||
{
|
||||
// 如果存在条件区域容器
|
||||
conditionRegion.AddCondition(nodeControl);
|
||||
TryPlaceNodeInRegion(conditionRegion, nodeControl);
|
||||
//// 如果存在条件区域容器
|
||||
//conditionRegion.AddCondition(nodeControl);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -831,8 +870,26 @@ namespace Serein.WorkBench
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将节点放在目标区域中
|
||||
/// </summary>
|
||||
/// <param name="regionControl">区域容器</param>
|
||||
/// <param name="nodeControl">节点控件</param>
|
||||
private void TryPlaceNodeInRegion(NodeControlBase regionControl, NodeControlBase nodeControl)
|
||||
{
|
||||
// 准备放置条件表达式控件
|
||||
if (nodeControl.ViewModel.Node.ControlType == NodeControlType.ExpCondition)
|
||||
{
|
||||
ConditionRegionControl conditionRegion = regionControl as ConditionRegionControl;
|
||||
if (conditionRegion != null)
|
||||
{
|
||||
// 如果存在条件区域容器
|
||||
conditionRegion.AddCondition(nodeControl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 拖动效果,根据拖放数据是否为指定类型设置拖放效果
|
||||
/// </summary>
|
||||
@@ -1038,6 +1095,7 @@ namespace Serein.WorkBench
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 画布中框选节点控件动作
|
||||
|
||||
/// <summary>
|
||||
@@ -1120,7 +1178,7 @@ namespace Serein.WorkBench
|
||||
/// </summary>
|
||||
private void FlowChartCanvas_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (IsSelectControl && e.LeftButton == MouseButtonState.Pressed)
|
||||
if (IsSelectControl && e.LeftButton == MouseButtonState.Pressed) // 正在选取节点
|
||||
{
|
||||
// 获取当前鼠标位置
|
||||
Point currentPoint = e.GetPosition(FlowChartCanvas);
|
||||
@@ -1137,7 +1195,8 @@ namespace Serein.WorkBench
|
||||
SelectionRectangle.Height = height;
|
||||
}
|
||||
|
||||
if (IsConnecting)
|
||||
|
||||
if (IsConnecting) // 正在连接节点
|
||||
{
|
||||
Point position = e.GetPosition(FlowChartCanvas);
|
||||
if (currentLine == null || startConnectNodeControl == null)
|
||||
@@ -1149,7 +1208,7 @@ namespace Serein.WorkBench
|
||||
currentLine.X2 = position.X;
|
||||
currentLine.Y2 = position.Y;
|
||||
}
|
||||
if (IsCanvasDragging)
|
||||
if (IsCanvasDragging) // 正在移动画布
|
||||
{
|
||||
Point currentMousePosition = e.GetPosition(this);
|
||||
double deltaX = currentMousePosition.X - startPoint.X;
|
||||
@@ -1160,9 +1219,6 @@ namespace Serein.WorkBench
|
||||
|
||||
startPoint = currentMousePosition;
|
||||
|
||||
// AdjustCanvasSizeAndContent(deltaX, deltaY);
|
||||
|
||||
|
||||
foreach (var line in Connections)
|
||||
{
|
||||
line.Refresh();
|
||||
@@ -1173,6 +1229,7 @@ namespace Serein.WorkBench
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 拖动画布实现缩放平移效果
|
||||
private void FlowChartCanvas_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
@@ -1197,16 +1254,25 @@ namespace Serein.WorkBench
|
||||
// 单纯缩放画布,不改变画布大小
|
||||
private void FlowChartCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
//var w = (int)(FlowChartCanvas.Width * scaleTransform.ScaleX);
|
||||
//var h = (int)(FlowChartCanvas.Height * scaleTransform.ScaleY);
|
||||
|
||||
//var TMP1 = w / FlowChartStackPanel.ActualWidth < 0.9;
|
||||
//var TMP2 = h / FlowChartStackPanel.ActualHeight < 0.9;
|
||||
|
||||
//Console.WriteLine("w"+(w, FlowChartStackPanel.ActualWidth, TMP1));
|
||||
//Console.WriteLine("h"+(h, FlowChartStackPanel.ActualHeight, TMP2));
|
||||
|
||||
|
||||
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
||||
{
|
||||
if (e.Delta < 0 && scaleTransform.ScaleX < 0.2) return;
|
||||
if (e.Delta > 0 && scaleTransform.ScaleX > 2.0) return;
|
||||
if (e.Delta > 0 && scaleTransform.ScaleY > 1.5) return;
|
||||
double scale = e.Delta > 0 ? 0.1 : -0.1;
|
||||
|
||||
|
||||
scaleTransform.ScaleX += scale;
|
||||
scaleTransform.ScaleY += scale;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1215,6 +1281,8 @@ namespace Serein.WorkBench
|
||||
{
|
||||
FlowChartCanvas.Width = width;
|
||||
FlowChartCanvas.Height = height;
|
||||
//FlowChartStackPanel.Width = width;
|
||||
//FlowChartStackPanel.Height = height;
|
||||
}
|
||||
|
||||
|
||||
@@ -1258,19 +1326,49 @@ namespace Serein.WorkBench
|
||||
|
||||
private void Thumb_DragDelta_BottomRight(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
// 从右下角调整大小
|
||||
double newWidth = Math.Max(FlowChartCanvas.ActualWidth + e.HorizontalChange * scaleTransform.ScaleX, 0);
|
||||
double newHeight = Math.Max(FlowChartCanvas.ActualHeight + e.VerticalChange * scaleTransform.ScaleY, 0);
|
||||
// 获取缩放后的水平和垂直变化
|
||||
double horizontalChange = e.HorizontalChange * scaleTransform.ScaleX;
|
||||
double verticalChange = e.VerticalChange * scaleTransform.ScaleY;
|
||||
|
||||
// 计算新的宽度和高度,确保不会小于400
|
||||
double newWidth = Math.Max(FlowChartCanvas.ActualWidth + horizontalChange, 400);
|
||||
double newHeight = Math.Max(FlowChartCanvas.ActualHeight + verticalChange, 400);
|
||||
|
||||
|
||||
newWidth = newWidth < 400 ? 400 : newWidth;
|
||||
newHeight = newHeight < 400 ? 400 : newHeight;
|
||||
|
||||
// 更新 Canvas 大小
|
||||
FlowChartCanvas.Width = newWidth;
|
||||
FlowChartCanvas.Height = newHeight;
|
||||
|
||||
// 如果宽度和高度超过400,调整TranslateTransform以保持左上角不动
|
||||
if (newWidth > 400 && newHeight > 400)
|
||||
{
|
||||
// 计算平移的变化,保持左上角不动
|
||||
double deltaX = -horizontalChange / 2; // 水平方向的平移
|
||||
double deltaY = -verticalChange / 2; // 垂直方向的平移
|
||||
|
||||
// 调整TranslateTransform以补偿尺寸变化
|
||||
translateTransform.X += deltaX;
|
||||
translateTransform.Y += deltaY;
|
||||
}
|
||||
|
||||
//// 从右下角调整大小
|
||||
//double newWidth = Math.Max(FlowChartCanvas.ActualWidth + e.HorizontalChange * scaleTransform.ScaleX, 0);
|
||||
//double newHeight = Math.Max(FlowChartCanvas.ActualHeight + e.VerticalChange * scaleTransform.ScaleY, 0);
|
||||
|
||||
//newWidth = newWidth < 400 ? 400 : newWidth;
|
||||
//newHeight = newHeight < 400 ? 400 : newHeight;
|
||||
|
||||
//if (newWidth > 400 && newHeight > 400)
|
||||
//{
|
||||
// FlowChartCanvas.Width = newWidth;
|
||||
// FlowChartCanvas.Height = newHeight;
|
||||
|
||||
// double x = e.HorizontalChange > 0 ? -0.5 : 0.5;
|
||||
// double y = e.VerticalChange > 0 ? -0.5 : 0.5;
|
||||
|
||||
// double deltaX = x * scaleTransform.ScaleX;
|
||||
// double deltaY = y * scaleTransform.ScaleY;
|
||||
// Test(deltaX, deltaY);
|
||||
//}
|
||||
}
|
||||
|
||||
//private void Thumb_DragDelta_Left(object sender, DragDeltaEventArgs e)
|
||||
@@ -1285,30 +1383,113 @@ namespace Serein.WorkBench
|
||||
private void Thumb_DragDelta_Right(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
//从右侧调整大小
|
||||
double newWidth = Math.Max(FlowChartCanvas.ActualWidth + e.HorizontalChange * scaleTransform.ScaleX, 0);
|
||||
newWidth = newWidth < 400 ? 400 : newWidth;
|
||||
//double newWidth = Math.Max(FlowChartCanvas.ActualWidth + e.HorizontalChange * scaleTransform.ScaleX, 0);
|
||||
//newWidth = newWidth < 400 ? 400 : newWidth;
|
||||
//if (newWidth > 400)
|
||||
//{
|
||||
// FlowChartCanvas.Width = newWidth;
|
||||
|
||||
// double x = e.HorizontalChange > 0 ? -0.5 : 0.5;
|
||||
// double y = 0;
|
||||
|
||||
// double deltaX = x * scaleTransform.ScaleX;
|
||||
// double deltaY = y * 0;
|
||||
// Test(deltaX, deltaY);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
// 获取缩放后的水平和垂直变化
|
||||
double horizontalChange = e.HorizontalChange * scaleTransform.ScaleX;
|
||||
//double verticalChange = e.VerticalChange * scaleTransform.ScaleY;
|
||||
|
||||
// 计算新的宽度和高度,确保不会小于400
|
||||
double newWidth = Math.Max(FlowChartCanvas.ActualWidth + horizontalChange, 400);
|
||||
//double newHeight = Math.Max(FlowChartCanvas.ActualHeight + verticalChange, 400);
|
||||
|
||||
// 更新 Canvas 大小
|
||||
FlowChartCanvas.Width = newWidth;
|
||||
//FlowChartCanvas.Height = newHeight;
|
||||
|
||||
// 如果宽度和高度超过400,调整TranslateTransform以保持左上角不动
|
||||
if (newWidth > 400 /*&& newHeight > 400*/)
|
||||
{
|
||||
// 计算平移的变化,保持左上角不动
|
||||
double deltaX = -horizontalChange / 2; // 水平方向的平移
|
||||
//double deltaY = -verticalChange / 2; // 垂直方向的平移
|
||||
|
||||
// 调整TranslateTransform以补偿尺寸变化
|
||||
translateTransform.X += deltaX;
|
||||
//translateTransform.Y += deltaY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//private void Thumb_DragDelta_Top(object sender, DragDeltaEventArgs e)
|
||||
//{
|
||||
// // 从顶部调整大小
|
||||
// double newHeight = Math.Max(FlowChartCanvas.ActualHeight - e.VerticalChange, 0);
|
||||
|
||||
|
||||
// FlowChartCanvas.Height = newHeight;
|
||||
// Canvas.SetTop(FlowChartCanvas, Canvas.GetTop(FlowChartCanvas) + e.VerticalChange);
|
||||
//}
|
||||
|
||||
private void Thumb_DragDelta_Bottom(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
// 从底部调整大小
|
||||
double newHeight = Math.Max(FlowChartCanvas.ActualHeight + e.VerticalChange * scaleTransform.ScaleY, 0);
|
||||
newHeight = newHeight < 400 ? 400 : newHeight;
|
||||
//// 从底部调整大小
|
||||
//double oldHeight = FlowChartCanvas.Height;
|
||||
|
||||
//double newHeight = Math.Max(FlowChartCanvas.ActualHeight + e.VerticalChange * scaleTransform.ScaleY, 0);
|
||||
////newHeight = newHeight < 400 ? 400 : newHeight;
|
||||
//if(newHeight > 400)
|
||||
//{
|
||||
// FlowChartCanvas.Height = newHeight;
|
||||
|
||||
// double x = 0;
|
||||
// double y = e.VerticalChange > 0 ? -0.5 : 0.5 ;
|
||||
|
||||
// double deltaX = x * 0;
|
||||
// double deltaY = y * (scaleTransform.ScaleY);
|
||||
|
||||
// Test(deltaX, deltaY);
|
||||
//}
|
||||
|
||||
|
||||
// 获取缩放后的水平和垂直变化
|
||||
//double horizontalChange = e.HorizontalChange * scaleTransform.ScaleX;
|
||||
double verticalChange = e.VerticalChange * scaleTransform.ScaleY;
|
||||
|
||||
// 计算新的宽度和高度,确保不会小于400
|
||||
//double newWidth = Math.Max(FlowChartCanvas.ActualWidth + horizontalChange, 400);
|
||||
double newHeight = Math.Max(FlowChartCanvas.ActualHeight + verticalChange, 400);
|
||||
|
||||
// 更新 Canvas 大小
|
||||
//FlowChartCanvas.Width = newWidth;
|
||||
FlowChartCanvas.Height = newHeight;
|
||||
|
||||
// 如果宽度和高度超过400,调整TranslateTransform以保持左上角不动
|
||||
if (/*newWidth > 400 &&*/ newHeight > 400)
|
||||
{
|
||||
// 计算平移的变化,保持左上角不动
|
||||
//double deltaX = -horizontalChange / 2; // 水平方向的平移
|
||||
double deltaY = -verticalChange / 2; // 垂直方向的平移
|
||||
|
||||
// 调整TranslateTransform以补偿尺寸变化
|
||||
//translateTransform.X += deltaX;
|
||||
translateTransform.Y += deltaY;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void Test(double deltaX, double deltaY)
|
||||
{
|
||||
translateTransform.X += deltaX;
|
||||
translateTransform.Y += deltaY;
|
||||
//Console.WriteLine((translateTransform.X, translateTransform.Y));
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
@@ -1358,7 +1539,8 @@ namespace Serein.WorkBench
|
||||
/// <param name="e"></param>
|
||||
private void ButtonDebugFlipflopNode_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FlowEnvironment.Exit(); // 在运行平台上点击了退出
|
||||
Console.WriteLine((FlowChartStackPanel.ActualWidth, FlowChartStackPanel.ActualHeight));
|
||||
FlowEnvironment?.Exit(); // 在运行平台上点击了退出
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1373,26 +1555,24 @@ namespace Serein.WorkBench
|
||||
var projectData = FlowEnvironment.SaveProject();
|
||||
projectData.Basic = new Basic
|
||||
{
|
||||
canvas = new FlowCanvas
|
||||
Canvas = new FlowCanvas
|
||||
{
|
||||
lenght = (float)FlowChartCanvas.Width,
|
||||
width = (float)FlowChartCanvas.Height,
|
||||
Lenght = (float)FlowChartCanvas.Width,
|
||||
Width = (float)FlowChartCanvas.Height,
|
||||
},
|
||||
versions = "1",
|
||||
Versions = "1",
|
||||
};
|
||||
|
||||
foreach(var node in projectData.Nodes)
|
||||
{
|
||||
var control = new ActionNodeControl(null);// GetControl(node.Guid);
|
||||
Point positionRelativeToParent = control.TranslatePoint(new Point(0, 0), FlowChartCanvas);
|
||||
|
||||
node.Position = new Position
|
||||
|
||||
if(NodeControls.TryGetValue(node.Guid,out var nodeControl))
|
||||
{
|
||||
X = (float)positionRelativeToParent.X,
|
||||
Y = (float)positionRelativeToParent.Y,
|
||||
};
|
||||
Point positionRelativeToParent = nodeControl.TranslatePoint(new Point(0, 0), FlowChartCanvas);
|
||||
node.Position = new Position(positionRelativeToParent.X, positionRelativeToParent.Y);
|
||||
}
|
||||
}
|
||||
var projectJsonData = JArray.FromObject(projectData);
|
||||
var projectJsonData = JObject.FromObject(projectData);
|
||||
var savePath = SaveContentToFile(projectJsonData.ToString());
|
||||
savePath = System.IO.Path.GetDirectoryName(savePath);
|
||||
|
||||
@@ -1696,8 +1876,6 @@ namespace Serein.WorkBench
|
||||
return Uri.UnescapeDataString(relativeUri.ToString().Replace('/', System.IO.Path.DirectorySeparatorChar));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#region 创建两个控件之间的连接关系,在UI层面上显示为 带箭头指向的贝塞尔曲线
|
||||
@@ -1725,7 +1903,9 @@ namespace Serein.WorkBench
|
||||
canvas.Children.Add(connection.ArrowPath);
|
||||
}
|
||||
|
||||
|
||||
BezierLineDrawer.UpdateBezierLine(canvas, connection.Start, connection.End, connection.BezierPath, connection.ArrowPath);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
@@ -1826,7 +2006,8 @@ namespace Serein.WorkBench
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
BsControl.Draw(Canvas, this);
|
||||
// BsControl.Draw(Canvas, this);
|
||||
BezierLineDrawer.UpdateBezierLine(Canvas, Start, End, BezierPath, ArrowPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1925,6 +2106,7 @@ namespace Serein.WorkBench
|
||||
arrowGeometry.Figures.Add(arrowFigure);
|
||||
|
||||
arrowPath.Data = arrowGeometry;
|
||||
|
||||
}
|
||||
// 计算终点落点位置
|
||||
private static Point CalculateEndpointOutsideElement(FrameworkElement element, Canvas canvas, Point startPoint, out Localhost localhost)
|
||||
|
||||
Reference in New Issue
Block a user