修改了无法添加基础节点的bug,增加WebSocket JSON ID字段,远程环境交互使用消息ID作为响应key。

This commit is contained in:
fengjiayi
2024-10-22 00:13:13 +08:00
parent 838158f446
commit 0a7e24d318
48 changed files with 1209 additions and 500 deletions

View File

@@ -10,7 +10,9 @@ namespace Serein.Workbench
/// </summary>
public partial class App : Application
{
#if DEBUG
#endif
public static SereinProjectData? FlowProjectData { get; set; }
public static string FileDataPath { get; set; } = "";
@@ -66,7 +68,7 @@ namespace Serein.Workbench
}
#if DEBUG
else if(1 == 1)
else if(1 == 11)
{
//string filePath = @"F:\临时\project\new project.dnf";

View File

@@ -461,6 +461,11 @@ namespace Serein.Workbench
return;
}
if(nodeModelBase is null)
{
Console.WriteLine("OnNodeCreateEvent事件接收到意外的返回值");
return;
}
// MethodDetails methodDetailss = eventArgs.MethodDetailss;
PositionOfUI position = eventArgs.Position;
@@ -577,15 +582,15 @@ namespace Serein.Workbench
{
string nodeGuid = eventArgs.NodeGuid;
if (!TryGetControl(nodeGuid, out var nodeControl)) return;
if (eventArgs.Class == InterruptClass.None)
{
nodeControl.ViewModel.IsInterrupt = false;
}
else
{
nodeControl.ViewModel.IsInterrupt = true;
}
//if (eventArgs.Class == InterruptClass.None)
//{
// nodeControl.ViewModel.IsInterrupt = false;
//}
//else
//{
// nodeControl.ViewModel.IsInterrupt = true;
//}
foreach (var menuItem in nodeControl.ContextMenu.Items)
{
@@ -1203,35 +1208,48 @@ namespace Serein.Workbench
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void FlowChartCanvas_Drop(object sender, DragEventArgs e)
private void FlowChartCanvas_Drop(object sender, DragEventArgs e)
{
var canvasDropPosition = e.GetPosition(FlowChartCanvas); // 更新画布落点
PositionOfUI position = new PositionOfUI(canvasDropPosition.X, canvasDropPosition.Y);
if (e.Data.GetDataPresent(MouseNodeType.CreateDllNodeInCanvas))
try
{
if (e.Data.GetData(MouseNodeType.CreateDllNodeInCanvas) is MoveNodeData nodeData)
var canvasDropPosition = e.GetPosition(FlowChartCanvas); // 更新画布落点
PositionOfUI position = new PositionOfUI(canvasDropPosition.X, canvasDropPosition.Y);
if (e.Data.GetDataPresent(MouseNodeType.CreateDllNodeInCanvas))
{
await EnvDecorator.CreateNodeAsync(nodeData.NodeControlType, position, nodeData.MethodDetailsInfo); // 创建DLL文件的节点对象
}
}
else if (e.Data.GetDataPresent(MouseNodeType.CreateBaseNodeInCanvas))
{
if (e.Data.GetData(MouseNodeType.CreateBaseNodeInCanvas) is Type droppedType)
{
NodeControlType nodeControlType = droppedType switch
if (e.Data.GetData(MouseNodeType.CreateDllNodeInCanvas) is MoveNodeData nodeData)
{
Type when typeof(ConditionRegionControl).IsAssignableFrom(droppedType) => NodeControlType.ConditionRegion, // 条件区域
Type when typeof(ConditionNodeControl).IsAssignableFrom(droppedType) => NodeControlType.ExpCondition,
Type when typeof(ExpOpNodeControl).IsAssignableFrom(droppedType) => NodeControlType.ExpOp,
_ => NodeControlType.None,
};
if(nodeControlType != NodeControlType.None)
{
await EnvDecorator.CreateNodeAsync(nodeControlType, position); // 创建基础节点对象
Task.Run(async () =>
{
await EnvDecorator.CreateNodeAsync(nodeData.NodeControlType, position, nodeData.MethodDetailsInfo); // 创建DLL文件的节点对象
});
}
}
else if (e.Data.GetDataPresent(MouseNodeType.CreateBaseNodeInCanvas))
{
if (e.Data.GetData(MouseNodeType.CreateBaseNodeInCanvas) is Type droppedType)
{
NodeControlType nodeControlType = droppedType switch
{
Type when typeof(ConditionRegionControl).IsAssignableFrom(droppedType) => NodeControlType.ConditionRegion, // 条件区域
Type when typeof(ConditionNodeControl).IsAssignableFrom(droppedType) => NodeControlType.ExpCondition,
Type when typeof(ExpOpNodeControl).IsAssignableFrom(droppedType) => NodeControlType.ExpOp,
_ => NodeControlType.None,
};
if (nodeControlType != NodeControlType.None)
{
Task.Run(async () =>
{
await EnvDecorator.CreateNodeAsync(nodeControlType, position); // 创建基础节点对象
});
}
}
}
e.Handled = true;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
e.Handled = true;
}
/// <summary>
@@ -1897,7 +1915,7 @@ namespace Serein.Workbench
//Console.WriteLine($"一共选取了{selectNodeControls.Count}个控件");
foreach (var node in selectNodeControls)
{
node.ViewModel.IsSelect =true;
//node.ViewModel.IsSelect =true;
// node.ViewModel.CancelSelect();
node.BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFC700"));
node.BorderThickness = new Thickness(4);
@@ -1908,7 +1926,7 @@ namespace Serein.Workbench
IsSelectControl = false;
foreach (var nodeControl in selectNodeControls)
{
nodeControl.ViewModel.IsSelect = false;
//nodeControl.ViewModel.IsSelect = false;
nodeControl.BorderBrush = Brushes.Black;
nodeControl.BorderThickness = new Thickness(0);
if (nodeControl.ViewModel.NodeModel.IsStart)

View File

@@ -40,6 +40,7 @@ namespace Serein.Workbench
else
{
FlowEnvironment = new FlowEnvironmentDecorator(uIContextOperation);
//_ = FlowEnvironment.StartRemoteServerAsync();
this.window = window;
}
}

View File

@@ -9,83 +9,97 @@ namespace Serein.Workbench.Node.ViewModel
public NodeControlViewModelBase(NodeModelBase nodeModel)
{
NodeModel = nodeModel;
MethodDetails = NodeModel.MethodDetails;
// 订阅来自 NodeModel 的通知事件
}
private NodeModelBase _nodeModelBase;
/// <summary>
/// 对应的节点实体类
/// </summary>
internal NodeModelBase NodeModel { get; }
private bool isSelect;
/// <summary>
/// 表示节点控件是否被选中
/// </summary>
internal bool IsSelect
public NodeModelBase NodeModel
{
get => isSelect;
set
get => _nodeModelBase; set
{
isSelect = value;
OnPropertyChanged();
if (value != null)
{
_nodeModelBase = value;
OnPropertyChanged();
}
}
}
//private bool isSelect;
///// <summary>
///// 表示节点控件是否被选中
///// </summary>
//internal bool IsSelect
//{
// get => isSelect;
// set
// {
// isSelect = value;
// OnPropertyChanged();
// }
//}
//private bool isInterrupt;
/////// <summary>
/////// 控制中断状态的视觉效果
/////// </summary>
//public bool IsInterrupt
//{
// get => NodeModel.DebugSetting.IsInterrupt;
// set
// {
// NodeModel.DebugSetting.IsInterrupt = value;
// OnPropertyChanged();
// }
//}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
//Console.WriteLine(propertyName);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// 使节点获得中断能力(以及是否启用节点)
/// </summary>
public NodeDebugSetting DebugSetting
{
get => NodeModel.DebugSetting;
set
{
if (value != null)
{
NodeModel.DebugSetting = value;
OnPropertyChanged();
}
}
}
//public NodeDebugSetting DebugSetting
//{
// get => Node.DebugSetting;
// set
// {
// if (value != null)
// {
// Node.DebugSetting = value;
// OnPropertyChanged();
// }
// }
//}
/// <summary>
/// 使节点能够表达方法信息
/// </summary>
public MethodDetails MethodDetails
{
get => NodeModel.MethodDetails;
set
{
if(value != null)
{
NodeModel.MethodDetails = value;
OnPropertyChanged();
}
}
}
//public MethodDetails MethodDetails
//{
// get => Node.MethodDetails;
// set
// {
// if(value != null)
// {
// Node.MethodDetails = value;
// OnPropertyChanged();
// }
// }
//}
private bool isInterrupt;
/// <summary>
/// 控制中断状态的视觉效果
/// </summary>
public bool IsInterrupt
{
get => isInterrupt;
set
{
isInterrupt = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -21,17 +21,20 @@
<Grid>
<Grid.ToolTip>
<ToolTip Background="LightYellow" Foreground="#071042" Content="{Binding MethodDetails.MethodTips, UpdateSourceTrigger=PropertyChanged}" />
<ToolTip Background="LightYellow" Foreground="#071042" Content="{Binding NodeModel.MethodDetails.MethodTips}" />
</Grid.ToolTip>
<Border>
<!--<TextBlock Text="{Binding NodelModel.DebugSetting.IsInterrupt}}"></TextBlock>-->
<Border x:Name="InterruptBorder">
<Border.Style>
<Style TargetType="Border">
<!-- 默认无边框 -->
<!--默认无边框-->
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsInterrupt}" Value="True">
<DataTrigger Binding="{Binding Path=NodeModel.DebugSetting.IsInterrupt}" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="Background" Value="#80000000" />
@@ -48,15 +51,16 @@
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Background="#8DE9FD">
<CheckBox IsChecked="{Binding DebugSetting.IsEnable, Mode=TwoWay}" VerticalContentAlignment="Center"/>
<CheckBox IsChecked="{Binding MethodDetails.IsProtectionParameter, Mode=TwoWay}" VerticalContentAlignment="Center"/>
<TextBlock Text="{Binding MethodDetails.MethodTips}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}" VerticalContentAlignment="Center"/>
<CheckBox IsChecked="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay}" VerticalContentAlignment="Center"/>
<TextBlock Text="{Binding NodeModel.MethodDetails.MethodTips, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<themes:MethodDetailsControl Grid.Row="1" MethodDetails="{Binding MethodDetails}"/>
<themes:MethodDetailsControl Grid.Row="1" MethodDetails="{Binding NodeModel.MethodDetails}"/>
<!-- ParameterProtectionMask 参数保护 -->
<!--取反 Visibility="{Binding DebugSetting.IsEnable, Converter={StaticResource InvertedBoolConverter}, ConverterParameter=Inverted}"-->
<Border Grid.Row="1" x:Name="ParameterProtectionMask" Background="LightBlue" Opacity="0.5" BorderBrush="#0A4651" BorderThickness="0"
Visibility="{Binding MethodDetails.IsProtectionParameter, Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}" />
Visibility="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay,
Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}" />
<Grid Grid.Row="2" Background="#D5F0FC" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
@@ -66,7 +70,7 @@
<TextBlock Text="result" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Grid.Column="1" BorderThickness="1">
<TextBlock Text="{Binding MethodDetails.ReturnType}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Text="{Binding NodeModel.MethodDetails.ReturnType, Mode=TwoWay}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Border>
</Grid>

View File

@@ -17,7 +17,7 @@
<Grid>
<Grid.ToolTip>
<ToolTip Background="LightYellow" Foreground="Black" Content="{Binding MethodDetails.MethodTips, UpdateSourceTrigger=PropertyChanged}" />
<ToolTip Background="LightYellow" Foreground="Black" Content="{Binding NodeModel.MethodDetails.MethodTips, UpdateSourceTrigger=PropertyChanged}" />
</Grid.ToolTip>
<Grid.RowDefinitions>
@@ -33,14 +33,14 @@
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" IsChecked="{Binding IsCustomData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> <!--Converter={StaticResource BoolToVis}-->
<TextBox Grid.Column="1" MinWidth="50" Text="{Binding CustomData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
<CheckBox Grid.Column="0" IsChecked="{Binding NodeModel.IsCustomData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> <!--Converter={StaticResource BoolToVis}-->
<TextBox Grid.Column="1" MinWidth="50" Text="{Binding NodeModel.CustomData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" VerticalAlignment="Center">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsCustomData}" Value="True">
<DataTrigger Binding="{Binding NodeModel.IsCustomData}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
@@ -53,7 +53,7 @@
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsCustomData}" Value="False">
<DataTrigger Binding="{Binding NodeModel.IsCustomData}" Value="False">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
@@ -61,7 +61,7 @@
</TextBlock.Style>
</TextBlock>
</Grid>
<TextBox Grid.Row="2" Background="#f1F66F" MinWidth="100" Text="{Binding Expression, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
<TextBox Grid.Row="2" Background="#f1F66F" MinWidth="100" Text="{Binding NodeModel.Expression, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
<!--<themes:MethodDetailsControl Grid.Row="1" MethodDetails="{Binding MethodDetails}" />

View File

@@ -16,7 +16,7 @@
<StackPanel Grid.Row="0" Orientation="Vertical" Background="LightSteelBlue">
<TextBlock Grid.Row="2" Text="表达式"></TextBlock>
<TextBox Text="{Binding Expression, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch"></TextBox>
<TextBox Text="{Binding NodeModel.Expression, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch"></TextBox>
</StackPanel>
</Grid>
</local:NodeControlBase>

View File

@@ -22,7 +22,7 @@
<Grid>
<Grid.ToolTip>
<ToolTip Background="LightYellow" Foreground="#071042" Content="{Binding MethodDetails.MethodName, UpdateSourceTrigger=PropertyChanged}" />
<ToolTip Background="LightYellow" Foreground="#071042" Content="{Binding NodeModel.MethodDetails.MethodName, UpdateSourceTrigger=PropertyChanged}" />
</Grid.ToolTip>
<Grid.RowDefinitions>
@@ -32,15 +32,16 @@
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Background="#FCB334">
<CheckBox IsChecked="{Binding DebugSetting.IsEnable, Mode=TwoWay}" VerticalContentAlignment="Center"/>
<CheckBox IsChecked="{Binding MethodDetails.IsProtectionParameter, Mode=TwoWay}" VerticalContentAlignment="Center"/>
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}" VerticalContentAlignment="Center"/>
<CheckBox IsChecked="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay}" VerticalContentAlignment="Center"/>
<TextBlock Text="{Binding MethodDetails.MethodTips, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Text="{Binding NodeModel.MethodDetails.MethodTips, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<themes:MethodDetailsControl Grid.Row="1" MethodDetails="{Binding MethodDetails}" />
<themes:MethodDetailsControl Grid.Row="1" MethodDetails="{Binding NodeModel.MethodDetails}" />
<Border Grid.Row="1" x:Name="ParameterProtectionMask" Background="LightBlue" Opacity="0.5" BorderBrush="#0A4651" BorderThickness="0"
Visibility="{Binding MethodDetails.IsProtectionParameter, Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}" />
Visibility="{Binding NodeModel.MethodDetails.IsProtectionParameter, Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}" />
<!--<Border Grid.Row="0" Background="#FCB334" >
</Border>-->
@@ -54,7 +55,7 @@
<TextBlock Text="result" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border Grid.Column="1" BorderThickness="1">
<TextBlock Text="{Binding MethodDetails.ReturnType}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Text="{Binding NodeModel.MethodDetails.ReturnType}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Border>
</Grid>
<!--<themes:ConditionControl Grid.Row="2" ></themes:ConditionControl>-->

View File

@@ -1,4 +1,5 @@
using Serein.Library.Api;
using Serein.Library;
using Serein.Library.Api;
using Serein.Workbench.Node.ViewModel;
using System.Windows.Controls;
using System.Windows.Media;
@@ -13,9 +14,8 @@ namespace Serein.Workbench.Node.View
{
public NodeControlViewModelBase ViewModel { get; set; }
protected NodeControlBase()
{
this.Background = Brushes.Transparent;
}
@@ -23,6 +23,7 @@ namespace Serein.Workbench.Node.View
{
ViewModel = viewModelBase;
this.Background = Brushes.Transparent;
this.DataContext = viewModelBase;
}
}

View File

@@ -5,11 +5,20 @@ namespace Serein.Workbench.Node.ViewModel
{
public class ActionNodeControlViewModel : NodeControlViewModelBase
{
private readonly SingleActionNode node;
//public SingleActionNode NodelModel
//{
// get => (SingleActionNode)base.NodeModel; set
// {
// if (base.NodeModel == null)
// {
// base.NodeModel = value;
// }
// }
//}
public ActionNodeControlViewModel(SingleActionNode node):base(node)
{
this.node = node;
// this.NodelModel = node;
}
}
}

View File

@@ -8,32 +8,32 @@ namespace Serein.Workbench.Node.ViewModel
/// </summary>
public class ConditionNodeControlViewModel : NodeControlViewModelBase
{
private readonly SingleConditionNode singleConditionNode;
public new SingleConditionNode NodeModel { get; }
/// <summary>
/// 是否为自定义参数
/// </summary>
public bool IsCustomData
{
get => singleConditionNode.IsCustomData;
set { singleConditionNode.IsCustomData= value; OnPropertyChanged(); }
}
/// <summary>
/// 自定义参数值
/// </summary>
public object? CustomData
{
get => singleConditionNode.CustomData;
set { singleConditionNode.CustomData = value ; OnPropertyChanged(); }
}
/// <summary>
/// 表达式
/// </summary>
public string Expression
{
get => singleConditionNode.Expression;
set { singleConditionNode.Expression = value; OnPropertyChanged(); }
}
///// <summary>
///// 是否为自定义参数
///// </summary>
//public bool IsCustomData
//{
// get => Node.IsCustomData;
// set { Node.IsCustomData= value; OnPropertyChanged(); }
//}
///// <summary>
// /// 自定义参数值
// /// </summary>
//public object? CustomData
//{
// get => Node.CustomData;
// set { Node.CustomData = value ; OnPropertyChanged(); }
//}
///// <summary>
///// 表达式
///// </summary>
//public string Expression
//{
// get => Node.Expression;
// set { Node.Expression = value; OnPropertyChanged(); }
//}
/// <summary>
/// 条件节点
@@ -41,7 +41,7 @@ namespace Serein.Workbench.Node.ViewModel
/// <param name="node"></param>
public ConditionNodeControlViewModel(SingleConditionNode node) : base(node)
{
this.singleConditionNode = node;
this.NodeModel = node;
//IsCustomData = false;
//CustomData = "";
//Expression = "PASS";

View File

@@ -5,22 +5,22 @@ namespace Serein.Workbench.Node.ViewModel
{
public class ExpOpNodeViewModel: NodeControlViewModelBase
{
public readonly SingleExpOpNode node;
public new SingleExpOpNode NodeModel { get; }
public string Expression
{
get => node.Expression;
set
{
node.Expression = value;
OnPropertyChanged();
}
}
//public string Expression
//{
// get => node.Expression;
// set
// {
// node.Expression = value;
// OnPropertyChanged();
// }
//}
public ExpOpNodeViewModel(SingleExpOpNode node) : base(node)
public ExpOpNodeViewModel(SingleExpOpNode nodeModel) : base(nodeModel)
{
this.node = node;
this.NodeModel = nodeModel;
}
}
}

View File

@@ -5,10 +5,10 @@ namespace Serein.Workbench.Node.ViewModel
{
public class FlipflopNodeControlViewModel : NodeControlViewModelBase
{
private readonly SingleFlipflopNode node;
public new SingleFlipflopNode NodelModel { get;}
public FlipflopNodeControlViewModel(SingleFlipflopNode node) : base(node)
{
this.node = node;
this.NodelModel = node;
}
}
}