mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-29 19:13:23 +08:00
重构中day1,写了很多,不知道怎么说清楚
This commit is contained in:
@@ -115,7 +115,7 @@ namespace Serein.Workbench.Avalonia.Services
|
|||||||
this.feefService = feefService;
|
this.feefService = feefService;
|
||||||
feefService.OnNodeCreate += FeefService_OnNodeCreate; // 订阅运行环境创建节点事件
|
feefService.OnNodeCreate += FeefService_OnNodeCreate; // 订阅运行环境创建节点事件
|
||||||
feefService.OnNodeConnectChange += FeefService_OnNodeConnectChange; // 订阅运行环境连接了节点事件
|
feefService.OnNodeConnectChange += FeefService_OnNodeConnectChange; // 订阅运行环境连接了节点事件
|
||||||
NodeMVVMManagement.RegisterUI(NodeControlType.Action, typeof(ActionNodeView), typeof(ActionNodeViewModel)); // 注册动作节点
|
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.Action, typeof(ActionNodeView), typeof(ActionNodeViewModel)); // 注册动作节点
|
||||||
// 手动加载项目
|
// 手动加载项目
|
||||||
_ = Task.Run(async delegate
|
_ = Task.Run(async delegate
|
||||||
{
|
{
|
||||||
@@ -184,7 +184,7 @@ namespace Serein.Workbench.Avalonia.Services
|
|||||||
SereinEnv.WriteLine(InfoType.WARN, $"OnNodeCreate 事件意外触发,节点Guid重复 - {nodeModel.Guid}");
|
SereinEnv.WriteLine(InfoType.WARN, $"OnNodeCreate 事件意外触发,节点Guid重复 - {nodeModel.Guid}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!NodeMVVMManagement.TryGetType(nodeModel.ControlType, out var nodeMVVM))
|
if (!flowEnvironment.NodeMVVMManagement.TryGetType(nodeModel.ControlType, out var nodeMVVM))
|
||||||
{
|
{
|
||||||
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,节点类型尚未注册。");
|
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,节点类型尚未注册。");
|
||||||
return;
|
return;
|
||||||
|
|||||||
17
Workbench/Api/IFlowEEForwardingService.cs
Normal file
17
Workbench/Api/IFlowEEForwardingService.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using Serein.Library.Api;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Api
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 流程事件管理,转发流程运行环境中触发的事件到工作台各个订阅者
|
||||||
|
/// </summary>
|
||||||
|
internal interface IFlowEEForwardingService : IFlowEnvironmentEvent
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
32
Workbench/Api/INodeContainerControl.cs
Normal file
32
Workbench/Api/INodeContainerControl.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Serein.Workbench.Node.View;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Api
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 约束具有容器功能的节点控件应该有什么方法
|
||||||
|
/// </summary>
|
||||||
|
public interface INodeContainerControl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 放置一个节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeControl"></param>
|
||||||
|
bool PlaceNode(NodeControlBase nodeControl);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取出一个节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeControl"></param>
|
||||||
|
bool TakeOutNode(NodeControlBase nodeControl);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取出所有节点(用于删除容器)
|
||||||
|
/// </summary>
|
||||||
|
void TakeOutAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Workbench/Api/INodeControl.cs
Normal file
23
Workbench/Api/INodeControl.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Serein.Library;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Avalonia.Api
|
||||||
|
{
|
||||||
|
//internal interface INodeControl
|
||||||
|
//{
|
||||||
|
// /// <summary>
|
||||||
|
// /// 对应的节点实体
|
||||||
|
// /// </summary>
|
||||||
|
// NodeModelBase NodeModelBase { get; }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// 初始化使用的方法,设置节点实体
|
||||||
|
// /// </summary>
|
||||||
|
// /// <param name="nodeModel"></param>
|
||||||
|
// void SetNodeModel(NodeModelBase nodeModel);
|
||||||
|
//}
|
||||||
|
}
|
||||||
51
Workbench/Api/INodeJunction.cs
Normal file
51
Workbench/Api/INodeJunction.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using Serein.Library;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Avalonia.Api
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 约束一个节点应该有哪些控制点
|
||||||
|
/// </summary>
|
||||||
|
/*public interface INodeJunction
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 方法执行入口控制点
|
||||||
|
/// </summary>
|
||||||
|
NodeJunctionView ExecuteJunction { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// 执行完成后下一个要执行的方法控制点
|
||||||
|
/// </summary>
|
||||||
|
NodeJunctionView NextStepJunction { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数节点控制点
|
||||||
|
/// </summary>
|
||||||
|
NodeJunctionView[] ArgDataJunction { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// 返回值控制点
|
||||||
|
/// </summary>
|
||||||
|
NodeJunctionView ReturnDataJunction { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取目标参数控制点,用于防止wpf释放资源导致找不到目标节点,返回-1,-1的坐标
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
NodeJunctionView GetJunctionOfArgData(int index)
|
||||||
|
{
|
||||||
|
var arr = ArgDataJunction;
|
||||||
|
if (index >= arr.Length)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return arr[index];
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="clr-namespace:Serein.Workbench"
|
xmlns:local="clr-namespace:Serein.Workbench"
|
||||||
StartupUri="MainWindow.xaml"
|
xmlns:view="clr-namespace:Serein.Workbench.Views"
|
||||||
|
StartupUri="Views/FlowWorkbenchView.xaml"
|
||||||
Startup="Application_Startup">
|
Startup="Application_Startup">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
|
|||||||
@@ -1,18 +1,109 @@
|
|||||||
using Newtonsoft.Json;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Serein.Library;
|
using Serein.Library;
|
||||||
|
using Serein.Library.Api;
|
||||||
using Serein.Library.Utils;
|
using Serein.Library.Utils;
|
||||||
|
using Serein.NodeFlow.Env;
|
||||||
|
using Serein.Workbench.Api;
|
||||||
|
using Serein.Workbench.Services;
|
||||||
|
using Serein.Workbench.ViewModels;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace Serein.Workbench
|
namespace Serein.Workbench
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public static class ServiceCollectionExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 注册ViewModel
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collection"></param>
|
||||||
|
public static void AddViewModelServices(this IServiceCollection collection)
|
||||||
|
{
|
||||||
|
collection.AddSingleton<Locator>(); // 主窗体
|
||||||
|
|
||||||
|
collection.AddSingleton<MainViewModel>();
|
||||||
|
collection.AddSingleton<MainMenuBarViewModel>();
|
||||||
|
collection.AddSingleton<FlowWorkbenchViewModel>();
|
||||||
|
collection.AddSingleton<BaseNodesViewModel>();
|
||||||
|
collection.AddSingleton<FlowLibrarysViewModel>();
|
||||||
|
collection.AddSingleton<FlowEditViewModel>();
|
||||||
|
|
||||||
|
collection.AddTransient<FlowCanvasViewModel>(); // 依赖信息
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddWorkbenchServices(this IServiceCollection collection)
|
||||||
|
{
|
||||||
|
collection.AddSingleton<IFlowEEForwardingService, FlowEEForwardingService>(); // 流程事件管理
|
||||||
|
collection.AddSingleton<IWorkbenchEventService, WorkbenchEventService>(); // 流程事件管理
|
||||||
|
collection.AddSingleton<INodeOperationService, NodeOperationService>(); // 节点操作管理
|
||||||
|
// collection.AddSingleton<IKeyEventService, KeyEventService>(); // 按键事件管理
|
||||||
|
//collection.AddSingleton<FlowNodeControlService>(); // 流程节点控件管理
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册流程接口相关实例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collection"></param>
|
||||||
|
public static void AddFlowServices(this IServiceCollection collection)
|
||||||
|
{
|
||||||
|
#region 创建实例
|
||||||
|
Func<SynchronizationContext> getSyncContext = null;
|
||||||
|
Dispatcher.CurrentDispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
var uiContext = SynchronizationContext.Current; // 在UI线程上获取UI线程上下文信息
|
||||||
|
if (uiContext is not null)
|
||||||
|
{
|
||||||
|
getSyncContext = () => uiContext;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
UIContextOperation? uIContextOperation = null;
|
||||||
|
uIContextOperation = new UIContextOperation(getSyncContext); // 封装一个调用UI线程的工具类
|
||||||
|
var flowEnvironmentDecorator = new FlowEnvironmentDecorator();
|
||||||
|
flowEnvironmentDecorator.SetUIContextOperation(uIContextOperation);
|
||||||
|
collection.AddSingleton<UIContextOperation>(uIContextOperation); // 注册UI线程操作上下文
|
||||||
|
collection.AddSingleton<IFlowEnvironment>(flowEnvironmentDecorator); // 注册运行环境
|
||||||
|
collection.AddSingleton<IFlowEnvironmentEvent>(flowEnvironmentDecorator); // 注册运行环境事件
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for App.xaml
|
/// Interaction logic for App.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
|
private static IServiceProvider? ServiceProvider;
|
||||||
|
public static T GetService<T>() where T : class
|
||||||
|
{
|
||||||
|
return ServiceProvider?.GetService<T>() ?? throw new NullReferenceException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public App()
|
||||||
|
{
|
||||||
|
var collection = new ServiceCollection();
|
||||||
|
collection.AddWorkbenchServices();
|
||||||
|
collection.AddFlowServices();
|
||||||
|
collection.AddViewModelServices();
|
||||||
|
var services = collection.BuildServiceProvider(); // 绑定并返回获取实例的服务接口
|
||||||
|
App.ServiceProvider = services;
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await Task.Delay(500);
|
||||||
|
await this.LoadLocalProjectAsync();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task LoadLocalProjectAsync()
|
private async Task LoadLocalProjectAsync()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -30,10 +121,14 @@ namespace Serein.Workbench
|
|||||||
App.FlowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
App.FlowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
||||||
App.FileDataPath = System.IO.Path.GetDirectoryName(filePath)!; // filePath;//
|
App.FileDataPath = System.IO.Path.GetDirectoryName(filePath)!; // filePath;//
|
||||||
var dir = Path.GetDirectoryName(filePath);
|
var dir = Path.GetDirectoryName(filePath);
|
||||||
|
|
||||||
|
App.GetService<IFlowEnvironment>().LoadProject(new FlowEnvInfo { Project = App.FlowProjectData },App.FileDataPath);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static SereinProjectData? FlowProjectData { get; set; }
|
public static SereinProjectData? FlowProjectData { get; set; }
|
||||||
public static string FileDataPath { get; set; } = "";
|
public static string FileDataPath { get; set; } = "";
|
||||||
|
|
||||||
@@ -66,7 +161,7 @@ namespace Serein.Workbench
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
await this.LoadLocalProjectAsync();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
33
Workbench/Converters/CountToVisibilityConverter.cs
Normal file
33
Workbench/Converters/CountToVisibilityConverter.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Converters
|
||||||
|
{
|
||||||
|
public class CountToVisibilityConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public bool Inverse { get; set; } = false; // 可选:反转逻辑
|
||||||
|
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (value is IEnumerable collection)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
foreach (var item in collection) count++;
|
||||||
|
bool visible = count > 0;
|
||||||
|
if (Inverse) visible = !visible;
|
||||||
|
return visible ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
return Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
29
Workbench/Customs/FlowMethodInfoListBox.xaml
Normal file
29
Workbench/Customs/FlowMethodInfoListBox.xaml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<UserControl x:Class="Serein.Workbench.Customs.FlowMethodInfoListBox"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:converter="clr-namespace:Serein.Workbench.Converters"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Customs"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<converter:CountToVisibilityConverter x:Key="CountToVisibilityConverter"/>
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<ListBox ItemsSource="{Binding Nodes}"
|
||||||
|
Visibility="{Binding Nodes, Converter={StaticResource CountToVisibilityConverter}}"
|
||||||
|
Background="{Binding BackgroundColor}">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Margin="2">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding NodeType}"></TextBlock>
|
||||||
|
<TextBlock Text="{Binding AnotherName}" Margin="4,0,0,0"></TextBlock>
|
||||||
|
<TextBlock Text="{Binding MethodName}" Margin="6,0,0,0"></TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</UserControl>
|
||||||
100
Workbench/Customs/FlowMethodInfoListBox.xaml.cs
Normal file
100
Workbench/Customs/FlowMethodInfoListBox.xaml.cs
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
using Serein.Library;
|
||||||
|
using Serein.Workbench.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Customs
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public class Test: DependencyObject
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FlowMethodInfoListBox.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class FlowMethodInfoListBox : UserControl
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public FlowMethodInfoListBox()
|
||||||
|
{
|
||||||
|
this.DataContext = this;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IEnumerable<FlowLibraryMethodDetailsInfo> Nodes
|
||||||
|
{
|
||||||
|
get { return (IEnumerable<FlowLibraryMethodDetailsInfo>)GetValue(NodesProperty); }
|
||||||
|
set { SetValue(NodesProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
//public ItemCollection Items
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// return (ItemCollection)GetValue(ItemsProperty);
|
||||||
|
// }
|
||||||
|
// set
|
||||||
|
// {
|
||||||
|
// SetValue(ItemsProperty, value);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly DependencyProperty NodesProperty = DependencyProperty.Register("NodesProperty", typeof(IEnumerable<FlowLibraryMethodDetailsInfo>), typeof(FlowMethodInfoListBox));
|
||||||
|
|
||||||
|
//public int TurnValue
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// return (int)GetValue(TurnValueProperty);
|
||||||
|
// }
|
||||||
|
// set
|
||||||
|
// {
|
||||||
|
// SetValue(TurnValueProperty, value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
// public static readonly DependencyProperty NodesProperty = DependencyProperty.Register(nameof(Nodes), typeof(IEnumerable<FlowLibraryMethodDetailsInfo>), typeof(FlowMethodInfoListBox), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
public Brush BackgroundColor
|
||||||
|
{
|
||||||
|
get { return (Brush)GetValue(BackgroundColorProperty); }
|
||||||
|
set { SetValue(BackgroundColorProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty BackgroundColorProperty =
|
||||||
|
DependencyProperty.Register(nameof(BackgroundColor), typeof(Brush), typeof(FlowMethodInfoListBox), new PropertyMetadata(Brushes.White));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
44
Workbench/Models/FlowLibraryInfo.cs
Normal file
44
Workbench/Models/FlowLibraryInfo.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Serein.Library;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Models
|
||||||
|
{
|
||||||
|
public partial class FlowLibraryMethodDetailsInfo(MethodDetailsInfo info): ObservableObject
|
||||||
|
{
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _anotherName = info.MethodAnotherName;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _assmblyName = info.AssemblyName;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _methodName = info.MethodName;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _nodeType = info.NodeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal partial class FlowLibraryInfo : ObservableObject
|
||||||
|
{
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _filePath;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _libraryName;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private ObservableCollection<FlowLibraryMethodDetailsInfo> _methodInfo;
|
||||||
|
|
||||||
|
|
||||||
|
public List<FlowLibraryMethodDetailsInfo> ActionNodes { get => MethodInfo.Where(x => x.NodeType == NodeType.Action.ToString()).ToList(); set { } }
|
||||||
|
public List<FlowLibraryMethodDetailsInfo> FlipflopNodes { get => MethodInfo.Where(x => x.NodeType == NodeType.Flipflop.ToString()).ToList(); set { } }
|
||||||
|
public List<FlowLibraryMethodDetailsInfo> UINodes { get => MethodInfo.Where(x => x.NodeType == NodeType.UI.ToString()).ToList(); set { } }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,6 +60,8 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AvalonEdit" Version="6.3.0.90" />
|
<PackageReference Include="AvalonEdit" Version="6.3.0.90" />
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
|
||||||
|
|
||||||
@@ -83,9 +85,4 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Views\" />
|
|
||||||
<Folder Include="VIewModels\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
344
Workbench/Services/FlowEEForwardingService.cs
Normal file
344
Workbench/Services/FlowEEForwardingService.cs
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Serein.Library.Api;
|
||||||
|
using Serein.NodeFlow;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Serein.Library;
|
||||||
|
using Serein.Library.Utils;
|
||||||
|
using Serein.Workbench.Avalonia.Api;
|
||||||
|
using Serein.Workbench.Api;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Services
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal class FlowEEForwardingService : IFlowEEForwardingService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 流程运行环境
|
||||||
|
/// </summary>
|
||||||
|
private readonly IFlowEnvironment flowEnvironment;
|
||||||
|
private readonly IFlowEnvironmentEvent flowEnvironmentEvent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转发流程运行环境各个事件的实现类
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flowEnvironment"></param>
|
||||||
|
/// <param name="flowNodeControlService"></param>
|
||||||
|
public FlowEEForwardingService(IFlowEnvironment flowEnvironment,
|
||||||
|
IFlowEnvironmentEvent flowEnvironmentEvent)
|
||||||
|
{
|
||||||
|
this.flowEnvironment = flowEnvironment;
|
||||||
|
this.flowEnvironmentEvent = flowEnvironmentEvent;
|
||||||
|
InitFlowEnvironmentEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 工作台事件转发
|
||||||
|
/// <summary>
|
||||||
|
/// 加载了依赖文件事件
|
||||||
|
/// </summary>
|
||||||
|
public event LoadDllHandler? OnDllLoad;
|
||||||
|
/// <summary>
|
||||||
|
/// 项目加载完成事件
|
||||||
|
/// </summary>
|
||||||
|
public event ProjectLoadedHandler? OnProjectLoaded;
|
||||||
|
/// <summary>
|
||||||
|
/// 项目保存中事件
|
||||||
|
/// </summary>
|
||||||
|
public event ProjectSavingHandler? OnProjectSaving;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点连接改变事件
|
||||||
|
/// </summary>
|
||||||
|
public event NodeConnectChangeHandler? OnNodeConnectChange;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点创建事件
|
||||||
|
/// </summary>
|
||||||
|
public event NodeCreateHandler? OnNodeCreate;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点移除事件
|
||||||
|
/// </summary>
|
||||||
|
public event NodeRemoveHandler? OnNodeRemove;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点放置容器事件
|
||||||
|
/// </summary>
|
||||||
|
public event NodePlaceHandler? OnNodePlace;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点取出事件
|
||||||
|
/// </summary>
|
||||||
|
public event NodeTakeOutHandler? OnNodeTakeOut;
|
||||||
|
/// <summary>
|
||||||
|
/// 流程起始节点改变事件
|
||||||
|
/// </summary>
|
||||||
|
public event StartNodeChangeHandler? OnStartNodeChange;
|
||||||
|
/// <summary>
|
||||||
|
/// 流程运行完毕事件
|
||||||
|
/// </summary>
|
||||||
|
public event FlowRunCompleteHandler? OnFlowRunComplete;
|
||||||
|
/// <summary>
|
||||||
|
/// 被监视的对象数据改变事件
|
||||||
|
/// </summary>
|
||||||
|
public event MonitorObjectChangeHandler? OnMonitorObjectChange;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点中断状态改变事件
|
||||||
|
/// </summary>
|
||||||
|
public event NodeInterruptStateChangeHandler? OnNodeInterruptStateChange;
|
||||||
|
/// <summary>
|
||||||
|
/// 表达式中断触发事件
|
||||||
|
/// </summary>
|
||||||
|
public event ExpInterruptTriggerHandler? OnInterruptTrigger;
|
||||||
|
/// <summary>
|
||||||
|
/// 容器对象改变事件
|
||||||
|
/// </summary>
|
||||||
|
public event IOCMembersChangedHandler? OnIOCMembersChanged;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点定位事件
|
||||||
|
/// </summary>
|
||||||
|
public event NodeLocatedHandler? OnNodeLocated;
|
||||||
|
/// <summary>
|
||||||
|
/// 节点移动事件
|
||||||
|
/// </summary>
|
||||||
|
public event NodeMovedHandler? OnNodeMoved;
|
||||||
|
/// <summary>
|
||||||
|
/// 运行环境输出事件
|
||||||
|
/// </summary>
|
||||||
|
public event EnvOutHandler? OnEnvOut;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 流程运行环境事件
|
||||||
|
|
||||||
|
private void InitFlowEnvironmentEvent()
|
||||||
|
{
|
||||||
|
flowEnvironmentEvent.OnDllLoad += FlowEnvironment_DllLoadEvent;
|
||||||
|
flowEnvironmentEvent.OnProjectSaving += EnvDecorator_OnProjectSaving;
|
||||||
|
flowEnvironmentEvent.OnProjectLoaded += FlowEnvironment_OnProjectLoaded;
|
||||||
|
flowEnvironmentEvent.OnStartNodeChange += FlowEnvironment_StartNodeChangeEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeConnectChange += FlowEnvironment_NodeConnectChangeEvemt;
|
||||||
|
flowEnvironmentEvent.OnNodeCreate += FlowEnvironment_NodeCreateEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeRemove += FlowEnvironment_NodeRemoveEvent;
|
||||||
|
flowEnvironmentEvent.OnNodePlace += EnvDecorator_OnNodePlaceEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeTakeOut += EnvDecorator_OnNodeTakeOutEvent;
|
||||||
|
flowEnvironmentEvent.OnFlowRunComplete += FlowEnvironment_OnFlowRunCompleteEvent;
|
||||||
|
|
||||||
|
flowEnvironmentEvent.OnMonitorObjectChange += FlowEnvironment_OnMonitorObjectChangeEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeInterruptStateChange += FlowEnvironment_OnNodeInterruptStateChangeEvent;
|
||||||
|
flowEnvironmentEvent.OnInterruptTrigger += FlowEnvironment_OnInterruptTriggerEvent;
|
||||||
|
|
||||||
|
flowEnvironmentEvent.OnIOCMembersChanged += FlowEnvironment_OnIOCMembersChangedEvent;
|
||||||
|
|
||||||
|
flowEnvironmentEvent.OnNodeLocated += FlowEnvironment_OnNodeLocateEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeMoved += FlowEnvironment_OnNodeMovedEvent;
|
||||||
|
|
||||||
|
flowEnvironmentEvent.OnEnvOut += FlowEnvironment_OnEnvOutEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetFlowEnvironmentEvent()
|
||||||
|
{
|
||||||
|
flowEnvironmentEvent.OnDllLoad -= FlowEnvironment_DllLoadEvent;
|
||||||
|
flowEnvironmentEvent.OnProjectSaving -= EnvDecorator_OnProjectSaving;
|
||||||
|
flowEnvironmentEvent.OnProjectLoaded -= FlowEnvironment_OnProjectLoaded;
|
||||||
|
flowEnvironmentEvent.OnStartNodeChange -= FlowEnvironment_StartNodeChangeEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeConnectChange -= FlowEnvironment_NodeConnectChangeEvemt;
|
||||||
|
flowEnvironmentEvent.OnNodeCreate -= FlowEnvironment_NodeCreateEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeRemove -= FlowEnvironment_NodeRemoveEvent;
|
||||||
|
flowEnvironmentEvent.OnNodePlace -= EnvDecorator_OnNodePlaceEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeTakeOut -= EnvDecorator_OnNodeTakeOutEvent;
|
||||||
|
flowEnvironmentEvent.OnFlowRunComplete -= FlowEnvironment_OnFlowRunCompleteEvent;
|
||||||
|
|
||||||
|
|
||||||
|
flowEnvironmentEvent.OnMonitorObjectChange -= FlowEnvironment_OnMonitorObjectChangeEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeInterruptStateChange -= FlowEnvironment_OnNodeInterruptStateChangeEvent;
|
||||||
|
flowEnvironmentEvent.OnInterruptTrigger -= FlowEnvironment_OnInterruptTriggerEvent;
|
||||||
|
|
||||||
|
flowEnvironmentEvent.OnIOCMembersChanged -= FlowEnvironment_OnIOCMembersChangedEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeLocated -= FlowEnvironment_OnNodeLocateEvent;
|
||||||
|
flowEnvironmentEvent.OnNodeMoved -= FlowEnvironment_OnNodeMovedEvent;
|
||||||
|
|
||||||
|
flowEnvironmentEvent.OnEnvOut -= FlowEnvironment_OnEnvOutEvent;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 运行环境事件
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 环境内容输出
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
private void FlowEnvironment_OnEnvOutEvent(InfoType type, string value)
|
||||||
|
{
|
||||||
|
//LogOutWindow.AppendText($"{DateTime.Now} [{type}] : {value}{Environment.NewLine}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 需要保存项目
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private void EnvDecorator_OnProjectSaving(ProjectSavingEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnProjectSaving?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载完成
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
private void FlowEnvironment_OnProjectLoaded(ProjectLoadedEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnProjectLoaded?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 运行完成
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private void FlowEnvironment_OnFlowRunCompleteEvent(FlowEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.INFO, "-------运行完成---------\r\n");
|
||||||
|
OnFlowRunComplete?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载了DLL文件,dll内容
|
||||||
|
/// </summary>
|
||||||
|
private void FlowEnvironment_DllLoadEvent(LoadDllEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnDllLoad?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点连接关系变更
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
private void FlowEnvironment_NodeConnectChangeEvemt(NodeConnectChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnNodeConnectChange?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点移除事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
private void FlowEnvironment_NodeRemoveEvent(NodeRemoveEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnNodeRemove?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加节点事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs">添加节点事件参数</param>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private void FlowEnvironment_NodeCreateEvent(NodeCreateEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnNodeCreate?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 放置一个节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private void EnvDecorator_OnNodePlaceEvent(NodePlaceEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnNodePlace?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取出一个节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
private void EnvDecorator_OnNodeTakeOutEvent(NodeTakeOutEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnNodeTakeOut?.Invoke(eventArgs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置了流程起始控件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="oldNodeGuid"></param>
|
||||||
|
/// <param name="newNodeGuid"></param>
|
||||||
|
private void FlowEnvironment_StartNodeChangeEvent(StartNodeChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
|
||||||
|
OnStartNodeChange?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 被监视的对象发生改变
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
private void FlowEnvironment_OnMonitorObjectChangeEvent(MonitorObjectEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnMonitorObjectChange?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点中断状态改变。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
private void FlowEnvironment_OnNodeInterruptStateChangeEvent(NodeInterruptStateChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnNodeInterruptStateChange?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点触发了中断
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private void FlowEnvironment_OnInterruptTriggerEvent(InterruptTriggerEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnInterruptTrigger?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IOC变更
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private void FlowEnvironment_OnIOCMembersChangedEvent(IOCMembersChangedEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnIOCMembersChanged?.Invoke(eventArgs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点需要定位
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private void FlowEnvironment_OnNodeLocateEvent(NodeLocatedEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnNodeLocated?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点移动
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
private void FlowEnvironment_OnNodeMovedEvent(NodeMovedEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
OnNodeMoved?.Invoke(eventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
80
Workbench/Services/KeyEventService.cs
Normal file
80
Workbench/Services/KeyEventService.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Services
|
||||||
|
{
|
||||||
|
delegate void KeyDownEventHandler(Key key);
|
||||||
|
delegate void KeyUpEventHandler(Key key);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 全局事件服务
|
||||||
|
/// </summary>
|
||||||
|
internal interface IKeyEventService
|
||||||
|
{
|
||||||
|
event KeyDownEventHandler KeyDown;
|
||||||
|
event KeyUpEventHandler KeyUp;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取某个按键状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool GetKeyState(Key key);
|
||||||
|
/// <summary>
|
||||||
|
/// 设置某个按键的状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="state"></param>
|
||||||
|
void SetKeyState(Key key, bool statestate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 管理按键状态
|
||||||
|
/// </summary>
|
||||||
|
internal class KeyEventService : IKeyEventService
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按键按下
|
||||||
|
/// </summary>
|
||||||
|
public event KeyDownEventHandler KeyDown;
|
||||||
|
/// <summary>
|
||||||
|
/// 按键松开
|
||||||
|
/// </summary>
|
||||||
|
public event KeyUpEventHandler KeyUp;
|
||||||
|
|
||||||
|
public KeyEventService()
|
||||||
|
{
|
||||||
|
var arr = Enum.GetValues<Key>();
|
||||||
|
KeysState = new bool[arr.Length];
|
||||||
|
|
||||||
|
// 绑定快捷键
|
||||||
|
//HotKeyManager.SetHotKey(saveMenuItem, new KeyGesture(Key.S, KeyModifiers.Control));
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly bool[] KeysState;
|
||||||
|
public bool GetKeyState(Key key)
|
||||||
|
{
|
||||||
|
return KeysState[(int)key];
|
||||||
|
}
|
||||||
|
public void SetKeyState(Key key, bool state)
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
KeyDown?.Invoke(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KeyUp?.Invoke(key);
|
||||||
|
}
|
||||||
|
//Debug.WriteLine($"按键事件:{key} - {state}");
|
||||||
|
KeysState[(int)key] = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
406
Workbench/Services/NodeOperationService.cs
Normal file
406
Workbench/Services/NodeOperationService.cs
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Serein.Library;
|
||||||
|
using Serein.Library.Api;
|
||||||
|
using Serein.Library.Utils;
|
||||||
|
using Serein.NodeFlow;
|
||||||
|
using Serein.NodeFlow.Env;
|
||||||
|
using Serein.Workbench.Api;
|
||||||
|
using Serein.Workbench.Avalonia.Api;
|
||||||
|
using Serein.Workbench.Node;
|
||||||
|
using Serein.Workbench.Node.View;
|
||||||
|
using Serein.Workbench.Node.ViewModel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Api
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提供节点操作的接口
|
||||||
|
/// </summary>
|
||||||
|
internal interface INodeOperationService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 连接数据
|
||||||
|
/// </summary>
|
||||||
|
// ConnectingManage ConnectingManage { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主画布
|
||||||
|
/// </summary>
|
||||||
|
Canvas MainCanvas { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点创建事件
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
event NodeViewCreateHandle OnNodeViewCreate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建节点控件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeType">控件类型</param>
|
||||||
|
/// <param name="position">创建坐标</param>
|
||||||
|
/// <param name="methodDetailsInfo">节点方法信息</param>
|
||||||
|
public void CreateNodeView(MethodDetailsInfo methodDetailsInfo, PositionOfUI position);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 尝试从连接控制点创建连接
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startJunction"></param>
|
||||||
|
//void TryCreateConnectionOnJunction(NodeJunctionView startJunction);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region 事件与事件参数
|
||||||
|
/// <summary>
|
||||||
|
/// 创建节点控件事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
|
||||||
|
internal delegate bool NodeViewCreateHandle(NodeViewCreateEventArgs eventArgs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建节点控件事件参数
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal class NodeViewCreateEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
internal NodeViewCreateEventArgs(NodeControlBase nodeControl, PositionOfUI position)
|
||||||
|
{
|
||||||
|
this.NodeControl = nodeControl;
|
||||||
|
this.Position = position;
|
||||||
|
}
|
||||||
|
public NodeControlBase NodeControl { get; private set; }
|
||||||
|
public PositionOfUI Position { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Services
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 节点操作相关服务
|
||||||
|
/// </summary>
|
||||||
|
internal class NodeOperationService : INodeOperationService
|
||||||
|
{
|
||||||
|
|
||||||
|
public NodeOperationService(IFlowEnvironment flowEnvironment,
|
||||||
|
IFlowEEForwardingService feefService)
|
||||||
|
{
|
||||||
|
this.flowEnvironment = flowEnvironment;
|
||||||
|
this.feefService = feefService;
|
||||||
|
feefService.OnNodeCreate += FeefService_OnNodeCreate; // 订阅运行环境创建节点事件
|
||||||
|
feefService.OnNodeConnectChange += FeefService_OnNodeConnectChange; // 订阅运行环境连接了节点事件
|
||||||
|
// 手动加载项目
|
||||||
|
_ = Task.Run(async delegate
|
||||||
|
{
|
||||||
|
await Task.Delay(1000);
|
||||||
|
var flowEnvironment = new FlowEnvironment();// App.GetService<IFlowEnvironment>();
|
||||||
|
var filePath = @"C:\Users\Az\source\repos\CLBanyunqiState\CLBanyunqiState\bin\debug\net8.0\project.dnf";
|
||||||
|
string content = System.IO.File.ReadAllText(filePath); // 读取整个文件内容
|
||||||
|
var projectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
||||||
|
var projectDfilePath = System.IO.Path.GetDirectoryName(filePath)!;
|
||||||
|
flowEnvironment.LoadProject(new FlowEnvInfo { Project = projectData }, projectDfilePath);
|
||||||
|
}, CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 接口属性
|
||||||
|
//public ConnectingManage ConnectingManage { get; private set; } = new ConnectingManage();
|
||||||
|
public Canvas MainCanvas { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 私有变量
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 存储所有与节点有关的控件
|
||||||
|
/// </summary>
|
||||||
|
private Dictionary<string, NodeControlBase> NodeControls { get; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 存储所有连接
|
||||||
|
/// </summary>
|
||||||
|
//private List<NodeConnectionLineControl> Connections { get; } = [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 流程运行环境
|
||||||
|
/// </summary>
|
||||||
|
private readonly IFlowEnvironment flowEnvironment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 流程运行环境事件转发
|
||||||
|
/// </summary>
|
||||||
|
private readonly IFlowEEForwardingService feefService;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 节点操作事件
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建了节点控件
|
||||||
|
/// </summary>
|
||||||
|
public event NodeViewCreateHandle OnNodeViewCreate;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 转发事件的处理
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从工作台事件转发器监听节点创建事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
private void FeefService_OnNodeCreate(NodeCreateEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
var nodeModel = eventArgs.NodeModel;
|
||||||
|
if (NodeControls.ContainsKey(nodeModel.Guid))
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.WARN, $"OnNodeCreate 事件意外触发,节点Guid重复 - {nodeModel.Guid}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!flowEnvironment.NodeMVVMManagement.TryGetType(nodeModel.ControlType, out var nodeMVVM))
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,节点类型尚未注册。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nodeMVVM.ControlType == null
|
||||||
|
|| nodeMVVM.ViewModelType == null)
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,UI类型尚未注册(请通过 NodeMVVMManagement.RegisterUI() 方法进行注册)。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isSuccessful = TryCreateNodeView(nodeMVVM.ControlType, // 控件UI类型
|
||||||
|
nodeMVVM.ViewModelType, // 控件VIewModel类型
|
||||||
|
nodeModel, // 控件数据实体
|
||||||
|
out var nodeControl); // 成功创建后传出的节点控件实体
|
||||||
|
if (!isSuccessful || nodeControl is null)
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,节点创建失败。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var e = new NodeViewCreateEventArgs(nodeControl, eventArgs.Position);
|
||||||
|
if (OnNodeViewCreate?.Invoke(e) == true)
|
||||||
|
{
|
||||||
|
// 成功创建
|
||||||
|
NodeControls.TryAdd(nodeModel.Guid, nodeControl); // 缓存起来,通知其它地方拿取这个控件
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 运行环境连接了节点事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private void FeefService_OnNodeConnectChange(NodeConnectChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
string fromNodeGuid = eventArgs.FromNodeGuid;
|
||||||
|
string toNodeGuid = eventArgs.ToNodeGuid;
|
||||||
|
if (!TryGetControl(fromNodeGuid, out var fromNodeControl)
|
||||||
|
|| !TryGetControl(toNodeGuid, out var toNodeControl))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (eventArgs.JunctionOfConnectionType == JunctionOfConnectionType.Invoke)
|
||||||
|
{
|
||||||
|
ConnectionInvokeType connectionType = eventArgs.ConnectionInvokeType;
|
||||||
|
#region 创建/删除节点之间的调用关系
|
||||||
|
#region 创建连接
|
||||||
|
if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Create) // 添加连接
|
||||||
|
{
|
||||||
|
if (fromNodeControl is not INodeJunction IFormJunction || toNodeControl is not INodeJunction IToJunction)
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.INFO, "非预期的连接");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var startJunction = IFormJunction.NextStepJunction;
|
||||||
|
var endJunction = IToJunction.ExecuteJunction;
|
||||||
|
|
||||||
|
// NodeConnectionLineControl nodeConnectionLineControl = new NodeConnectionLineControl(MainCanvas, startJunction, endJunction);
|
||||||
|
|
||||||
|
//startJunction.TransformToVisual(MainCanvas);
|
||||||
|
|
||||||
|
//// 添加连接
|
||||||
|
//var shape = new ConnectionLineShape(
|
||||||
|
// FlowChartCanvas,
|
||||||
|
// connectionType,
|
||||||
|
// startJunction,
|
||||||
|
// endJunction
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
|
//NodeConnectionLine nodeConnectionLine = new NodeConnectionLine(MainCanvas, shape);
|
||||||
|
|
||||||
|
//if (toNodeControl is FlipflopNodeControl flipflopControl
|
||||||
|
// && flipflopControl?.ViewModel?.NodeModel is NodeModelBase nodeModel) // 某个节点连接到了触发器,尝试从全局触发器视图中移除该触发器
|
||||||
|
//{
|
||||||
|
// NodeTreeViewer.RemoveGlobalFlipFlop(nodeModel); // 从全局触发器树树视图中移除
|
||||||
|
//}
|
||||||
|
|
||||||
|
//Connections.Add(nodeConnectionLineControl);
|
||||||
|
//fromNodeControl.AddConnection(nodeConnectionLineControl);
|
||||||
|
//toNodeControl.AddConnection(nodeConnectionLineControl);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region 移除连接
|
||||||
|
/* else if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Remove) // 移除连接
|
||||||
|
{
|
||||||
|
// 需要移除连接
|
||||||
|
var removeConnections = Connections.Where(c =>
|
||||||
|
c.Start.MyNode.Guid.Equals(fromNodeGuid)
|
||||||
|
&& c.End.MyNode.Guid.Equals(toNodeGuid)
|
||||||
|
&& (c.Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke
|
||||||
|
|| c.End.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var connection in removeConnections)
|
||||||
|
{
|
||||||
|
Connections.Remove(connection);
|
||||||
|
fromNodeControl.RemoveConnection(connection); // 移除连接
|
||||||
|
toNodeControl.RemoveConnection(connection); // 移除连接
|
||||||
|
if (NodeControls.TryGetValue(connection.End.MyNode.Guid, out var control))
|
||||||
|
{
|
||||||
|
JudgmentFlipFlopNode(control); // 连接关系变更时判断
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 私有方法
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建节点控件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="viewType">节点控件视图控件类型</param>
|
||||||
|
/// <param name="viewModelType">节点控件ViewModel类型</param>
|
||||||
|
/// <param name="nodeModel">节点Model实例</param>
|
||||||
|
/// <param name="nodeView">返回的节点对象</param>
|
||||||
|
/// <returns>是否创建成功</returns>
|
||||||
|
/// <exception cref="Exception">无法创建节点控件</exception>
|
||||||
|
private bool TryCreateNodeView(Type viewType, Type viewModelType, NodeModelBase nodeModel, out NodeControlBase? nodeView)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(nodeModel.Guid))
|
||||||
|
{
|
||||||
|
nodeModel.Guid = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
var t_ViewModel = Activator.CreateInstance(viewModelType, nodeModel);
|
||||||
|
if (t_ViewModel is not NodeControlViewModelBase viewModelBase)
|
||||||
|
{
|
||||||
|
nodeView = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var controlObj = Activator.CreateInstance(viewType);
|
||||||
|
if (controlObj is NodeControlBase nodeControl)
|
||||||
|
{
|
||||||
|
nodeControl.DataContext = viewModelBase;
|
||||||
|
nodeView = nodeControl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodeView = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在其它地方验证过了,所以注释
|
||||||
|
//if ((viewType is null)
|
||||||
|
// || viewModelType is null
|
||||||
|
// || nodeModel is null)
|
||||||
|
//{
|
||||||
|
// nodeView = null;
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
//if (typeof(INodeControl).IsSubclassOf(viewType)
|
||||||
|
// || typeof(NodeViewModelBase).IsSubclassOf(viewModelType))
|
||||||
|
//{
|
||||||
|
// nodeView = null;
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetControl(string nodeGuid, out NodeControlBase nodeControl)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(nodeGuid))
|
||||||
|
{
|
||||||
|
nodeControl = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!NodeControls.TryGetValue(nodeGuid, out nodeControl))
|
||||||
|
{
|
||||||
|
nodeControl = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (nodeControl is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 操作接口对外暴露的接口
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建节点控件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeType">控件类型</param>
|
||||||
|
/// <param name="position">创建坐标</param>
|
||||||
|
/// <param name="methodDetailsInfo">节点方法信息(基础节点传null)</param>
|
||||||
|
public void CreateNodeView(MethodDetailsInfo methodDetailsInfo, PositionOfUI position)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
if (EnumHelper.TryConvertEnum<NodeControlType>(methodDetailsInfo.NodeType, out var nodeType))
|
||||||
|
{
|
||||||
|
await flowEnvironment.CreateNodeAsync(nodeType, position, methodDetailsInfo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
13
Workbench/Services/ProjectService.cs
Normal file
13
Workbench/Services/ProjectService.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Services
|
||||||
|
{
|
||||||
|
internal class ProjectService
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
90
Workbench/Services/WorkbenchEventService.cs
Normal file
90
Workbench/Services/WorkbenchEventService.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
using Serein.Library;
|
||||||
|
using Serein.Library.Api;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Services
|
||||||
|
{
|
||||||
|
|
||||||
|
#region 工作台事件
|
||||||
|
|
||||||
|
public delegate void PreviewlMethodInfoHandler(PreviewlMethodInfoEventArgs eventArgs);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 工作台事件参数
|
||||||
|
public class PreviewlMethodInfoEventArgs(MethodDetailsInfo mdInfo) : EventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 方法信息
|
||||||
|
/// </summary>
|
||||||
|
public MethodDetailsInfo MethodDetailsInfo { get; } = mdInfo;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工作台事件管理
|
||||||
|
/// </summary>
|
||||||
|
internal interface IWorkbenchEventService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 预览了某个方法信息(待创建)
|
||||||
|
/// </summary>
|
||||||
|
event PreviewlMethodInfoHandler OnPreviewlMethodInfo;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 预览依赖方法信息
|
||||||
|
/// </summary>
|
||||||
|
void PreviewLibraryMethodInfo(MethodDetailsInfo mdInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工作台事件的实现类
|
||||||
|
/// </summary>
|
||||||
|
internal class WorkbenchEventService : IWorkbenchEventService
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IFlowEnvironment flowEnvironment;
|
||||||
|
/// <summary>
|
||||||
|
/// 管理工作台的事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flowEnvironment"></param>
|
||||||
|
public WorkbenchEventService(IFlowEnvironment flowEnvironment)
|
||||||
|
{
|
||||||
|
this.flowEnvironment = flowEnvironment;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeEvents()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 预览了某个方法信息(待创建)
|
||||||
|
/// </summary>
|
||||||
|
public event PreviewlMethodInfoHandler? OnPreviewlMethodInfo;
|
||||||
|
/// <summary>
|
||||||
|
/// 预览依赖方法信息
|
||||||
|
/// </summary>
|
||||||
|
public void PreviewLibraryMethodInfo(MethodDetailsInfo mdInfo)
|
||||||
|
{
|
||||||
|
OnPreviewlMethodInfo?.Invoke(new PreviewlMethodInfoEventArgs(mdInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 需要放置节点控件
|
||||||
|
/// </summary>
|
||||||
|
public void PlateNodeControl()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
13
Workbench/ViewModels/BaseNodesViewModel.cs
Normal file
13
Workbench/ViewModels/BaseNodesViewModel.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
internal class BaseNodesViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Workbench/ViewModels/FlowCanvasViewModel.cs
Normal file
19
Workbench/ViewModels/FlowCanvasViewModel.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
public partial class FlowCanvasViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _isConnectionInvokeNode;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _isConnectionArgSourceNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
Workbench/ViewModels/FlowEditViewModel.cs
Normal file
16
Workbench/ViewModels/FlowEditViewModel.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 流程编辑数据视图
|
||||||
|
/// </summary>
|
||||||
|
public partial class FlowEditViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
54
Workbench/ViewModels/FlowLibrarysViewModel.cs
Normal file
54
Workbench/ViewModels/FlowLibrarysViewModel.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Serein.Library;
|
||||||
|
using Serein.Workbench.Api;
|
||||||
|
using Serein.Workbench.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
internal partial class FlowLibrarysViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
private readonly IFlowEEForwardingService flowEEForwardingService;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private ObservableCollection<FlowLibraryInfo> flowLibraryInfos;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public FlowLibrarysViewModel(IFlowEEForwardingService flowEEForwardingService)
|
||||||
|
{
|
||||||
|
this.flowEEForwardingService = flowEEForwardingService;
|
||||||
|
FlowLibraryInfos = new ObservableCollection<FlowLibraryInfo>();
|
||||||
|
flowEEForwardingService.OnDllLoad += FlowEEForwardingService_OnDllLoad;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FlowEEForwardingService_OnDllLoad(Library.Api.LoadDllEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (!eventArgs.IsSucceed) return;
|
||||||
|
List<MethodDetailsInfo> mds = eventArgs.MethodDetailss;
|
||||||
|
NodeLibraryInfo libraryInfo = eventArgs.NodeLibraryInfo;
|
||||||
|
|
||||||
|
var methodInfo = new ObservableCollection<FlowLibraryMethodDetailsInfo>();
|
||||||
|
foreach (var md in mds)
|
||||||
|
{
|
||||||
|
methodInfo.Add(new FlowLibraryMethodDetailsInfo(md));
|
||||||
|
}
|
||||||
|
var flInfo = new FlowLibraryInfo
|
||||||
|
{
|
||||||
|
LibraryName = libraryInfo.AssemblyName,
|
||||||
|
FilePath = libraryInfo.FilePath,
|
||||||
|
MethodInfo = methodInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
FlowLibraryInfos.Add(flInfo);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Workbench/ViewModels/FlowWorkbenchViewModel.cs
Normal file
25
Workbench/ViewModels/FlowWorkbenchViewModel.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Serein.Workbench.Api;
|
||||||
|
using Serein.Workbench.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
internal partial class FlowWorkbenchViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
private readonly IFlowEEForwardingService flowEEForwardingService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public FlowWorkbenchViewModel(IFlowEEForwardingService flowEEForwardingService)
|
||||||
|
{
|
||||||
|
this.flowEEForwardingService = flowEEForwardingService;
|
||||||
|
//flowEEForwardingService.OnDllLoad += FlowEEForwardingService_OnDllLoad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Workbench/ViewModels/Locator.cs
Normal file
40
Workbench/ViewModels/Locator.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
internal class Locator
|
||||||
|
{
|
||||||
|
private static IServiceProvider ServiceProvide { get; set; }
|
||||||
|
public Locator(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
ServiceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
//private IServiceProvider GetService()
|
||||||
|
//{
|
||||||
|
// var service = new ServiceCollection();
|
||||||
|
// service.AddSingleton<MainViewModel>();
|
||||||
|
// service.AddSingleton<MainMenuBarViewModel>();
|
||||||
|
// service.AddSingleton<FlowWorkbenchViewModel>();
|
||||||
|
// service.AddSingleton<BaseNodesViewModel>();
|
||||||
|
// service.AddSingleton<FlowLibrarysViewModel>();
|
||||||
|
// service.AddTransient<FlowLibraryMethodDetailssViewModel>();
|
||||||
|
// return service.BuildServiceProvider();
|
||||||
|
//}
|
||||||
|
|
||||||
|
public MainViewModel MainViewModel => App.GetService<MainViewModel>() ?? throw new NotImplementedException();
|
||||||
|
public MainMenuBarViewModel MainMenuBarViewModel => App.GetService<MainMenuBarViewModel>() ?? throw new NotImplementedException();
|
||||||
|
public FlowWorkbenchViewModel FlowWorkbenchViewModel => App.GetService<FlowWorkbenchViewModel>() ?? throw new NotImplementedException();
|
||||||
|
public BaseNodesViewModel BaseNodesViewModel => App.GetService<BaseNodesViewModel>() ?? throw new NotImplementedException();
|
||||||
|
public FlowLibrarysViewModel FlowLibrarysViewModel => App.GetService<FlowLibrarysViewModel>() ?? throw new NotImplementedException();
|
||||||
|
public FlowEditViewModel FlowEditViewModel => App.GetService<FlowEditViewModel>() ?? throw new NotImplementedException();
|
||||||
|
public FlowCanvasViewModel FlowCanvasViewModel => App.GetService<FlowCanvasViewModel>() ?? throw new NotImplementedException();
|
||||||
|
|
||||||
|
public IServiceProvider ServiceProvider { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Workbench/ViewModels/MainMenuBarViewModel.cs
Normal file
12
Workbench/ViewModels/MainMenuBarViewModel.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
public class MainMenuBarViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
public MainMenuBarViewModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
Workbench/ViewModels/MainViewModel.cs
Normal file
17
Workbench/ViewModels/MainViewModel.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
public class MainViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
public MainViewModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Workbench/Views/BaseNodesView.xaml
Normal file
23
Workbench/Views/BaseNodesView.xaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<UserControl x:Class="Serein.Workbench.Views.BaseNodesView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
xmlns:nodeView="clr-namespace:Serein.Workbench.Node.View"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="150" d:DesignWidth="400">
|
||||||
|
<Grid>
|
||||||
|
<!--暂时隐藏基础面板 Visibility="Collapsed" -->
|
||||||
|
<ScrollViewer Grid.Row="0" HorizontalScrollBarVisibility="Auto">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<!--<nodeView:NetScriptNodeControl x:Name="NetScriptNodeControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>-->
|
||||||
|
<nodeView:ScriptNodeControl x:Name="ScriptNodeControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>
|
||||||
|
<nodeView:GlobalDataControl x:Name="GlobalDataControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>
|
||||||
|
<nodeView:ExpOpNodeControl x:Name="ExpOpNodeControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>
|
||||||
|
<nodeView:ConditionNodeControl x:Name="ConditionNodeControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>
|
||||||
|
<!--<nodeView:ConditionRegionControl x:Name="ConditionRegionControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>-->
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
57
Workbench/Views/BaseNodesView.xaml.cs
Normal file
57
Workbench/Views/BaseNodesView.xaml.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using Serein.Library;
|
||||||
|
using Serein.Workbench.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// BaseNodesView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class BaseNodesView : UserControl
|
||||||
|
{
|
||||||
|
public BaseNodesView()
|
||||||
|
{
|
||||||
|
this.DataContext = App.GetService<Locator>().BaseNodesViewModel;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 基础节点的拖拽放置创建
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void BaseNodeControl_PreviewMouseMove(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is UserControl control)
|
||||||
|
{
|
||||||
|
if (e.LeftButton == MouseButtonState.Pressed)
|
||||||
|
{
|
||||||
|
// 创建一个 DataObject 用于拖拽操作,并设置拖拽效果
|
||||||
|
var dragData = new DataObject(MouseNodeType.CreateBaseNodeInCanvas, control.GetType());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DragDrop.DoDragDrop(control, dragData, DragDropEffects.Move);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
121
Workbench/Views/FlowCanvasView.xaml
Normal file
121
Workbench/Views/FlowCanvasView.xaml
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<UserControl x:Class="Serein.Workbench.Views.FlowCanvasView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
xmlns:tool="clr-namespace:Serein.Workbench.Tool.Converters"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
|
|
||||||
|
<UserControl.Resources>
|
||||||
|
<tool:RightThumbPositionConverter x:Key="RightThumbPositionConverter" />
|
||||||
|
<tool:BottomThumbPositionConverter x:Key="BottomThumbPositionConverter" />
|
||||||
|
<tool:VerticalCenterThumbPositionConverter x:Key="VerticalCenterThumbPositionConverter" />
|
||||||
|
<tool:HorizontalCenterThumbPositionConverter x:Key="HorizontalCenterThumbPositionConverter" />
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<StackPanel x:Name="FlowChartStackPanel"
|
||||||
|
ClipToBounds="True">
|
||||||
|
<!-- 虚拟化 VirtualizingStackPanel.IsVirtualizing="True" -->
|
||||||
|
<Canvas
|
||||||
|
x:Name="FlowChartCanvas"
|
||||||
|
Background="#E1FBEA"
|
||||||
|
AllowDrop="True"
|
||||||
|
Width="1920"
|
||||||
|
Height="1080"
|
||||||
|
MouseLeftButtonDown ="FlowChartCanvas_MouseLeftButtonDown"
|
||||||
|
MouseLeftButtonUp="FlowChartCanvas_MouseLeftButtonUp"
|
||||||
|
MouseDown="FlowChartCanvas_MouseDown"
|
||||||
|
MouseUp="FlowChartCanvas_MouseUp"
|
||||||
|
MouseMove="FlowChartCanvas_MouseMove"
|
||||||
|
MouseWheel="FlowChartCanvas_MouseWheel"
|
||||||
|
Drop="FlowChartCanvas_Drop"
|
||||||
|
DragOver="FlowChartCanvas_DragOver"
|
||||||
|
>
|
||||||
|
|
||||||
|
<Rectangle x:Name="SelectionRectangle"
|
||||||
|
Stroke="Blue"
|
||||||
|
StrokeThickness="2"
|
||||||
|
Fill="LightBlue"
|
||||||
|
Opacity="0.2"
|
||||||
|
Panel.ZIndex="999999"
|
||||||
|
Visibility="Collapsed"/>
|
||||||
|
|
||||||
|
<!-- Top-Left Thumb -->
|
||||||
|
<!--<Thumb x:Name="TopLeftThumb"
|
||||||
|
Width="10" Height="10"
|
||||||
|
DragDelta="Thumb_DragDelta_TopLeft"
|
||||||
|
Cursor="SizeNWSE"
|
||||||
|
Canvas.Left="0" Canvas.Top="0"/>-->
|
||||||
|
|
||||||
|
<!-- Top-Right Thumb -->
|
||||||
|
<!--<Thumb x:Name="TopRightThumb"
|
||||||
|
Width="10" Height="10"
|
||||||
|
DragDelta="Thumb_DragDelta_TopRight"
|
||||||
|
Cursor="SizeNESW"
|
||||||
|
Canvas.Left="{Binding ActualWidth, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource RightThumbPositionConverter}}"
|
||||||
|
Canvas.Top="0"/>-->
|
||||||
|
|
||||||
|
<!-- Bottom-Left Thumb -->
|
||||||
|
<!--<Thumb x:Name="BottomLeftThumb"
|
||||||
|
Width="10" Height="10"
|
||||||
|
DragDelta="Thumb_DragDelta_BottomLeft"
|
||||||
|
Cursor="SizeNESW"
|
||||||
|
Canvas.Left="0"
|
||||||
|
Canvas.Top="{Binding ActualHeight, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource BottomThumbPositionConverter}}"/>-->
|
||||||
|
|
||||||
|
<!-- Left Thumb -->
|
||||||
|
<!--<Thumb x:Name="LeftThumb"
|
||||||
|
Width="10" Height="10"
|
||||||
|
DragDelta="Thumb_DragDelta_Left"
|
||||||
|
Cursor="SizeWE"
|
||||||
|
Canvas.Left="0"
|
||||||
|
Canvas.Top="{Binding ActualHeight, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource VerticalCenterThumbPositionConverter}}"/>-->
|
||||||
|
|
||||||
|
<!-- Right Thumb -->
|
||||||
|
|
||||||
|
<!-- Top Thumb -->
|
||||||
|
<!--<Thumb x:Name="TopThumb"
|
||||||
|
Width="10" Height="10"
|
||||||
|
DragDelta="Thumb_DragDelta_Top"
|
||||||
|
Cursor="SizeNS"
|
||||||
|
Canvas.Left="{Binding ActualWidth, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource HorizontalCenterThumbPositionConverter}}"
|
||||||
|
Canvas.Top="0"/>-->
|
||||||
|
|
||||||
|
<!-- Bottom Thumb -->
|
||||||
|
<!-- Bottom-Right Thumb -->
|
||||||
|
<Thumb x:Name="BottomRightThumb"
|
||||||
|
Width="15" Height="15"
|
||||||
|
DragDelta="Thumb_DragDelta_BottomRight"
|
||||||
|
Cursor="SizeNWSE"
|
||||||
|
Canvas.Left="{Binding ActualWidth, Converter={StaticResource RightThumbPositionConverter}, ElementName=FlowChartCanvas, Mode=OneWay}"
|
||||||
|
Canvas.Top="{Binding ActualHeight, Converter={StaticResource BottomThumbPositionConverter}, ElementName=FlowChartCanvas, Mode=OneWay}"/>
|
||||||
|
|
||||||
|
<!--Canvas.Left="{Binding ActualWidth, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource RightThumbPositionConverter}}"
|
||||||
|
Canvas.Top="{Binding ActualHeight, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource VerticalCenterThumbPositionConverter}}"-->
|
||||||
|
<Thumb x:Name="RightThumb" Width="5" Cursor="SizeWE" Canvas.Top="0" Canvas.Right="0" DragDelta="Thumb_DragDelta_Right">
|
||||||
|
<Thumb.Template>
|
||||||
|
<ControlTemplate>
|
||||||
|
<Border Background="#B1B9F8" Width="5" Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}" />
|
||||||
|
</ControlTemplate>
|
||||||
|
</Thumb.Template>
|
||||||
|
</Thumb>
|
||||||
|
|
||||||
|
<!--Canvas.Left="{Binding ActualWidth, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource HorizontalCenterThumbPositionConverter}}"
|
||||||
|
Canvas.Top="{Binding ActualHeight, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource BottomThumbPositionConverter}}"-->
|
||||||
|
<Thumb x:Name="BottomThumb" Height="5" Cursor="SizeNS" Canvas.Bottom="0" Canvas.Left="0" DragDelta="Thumb_DragDelta_Bottom">
|
||||||
|
<Thumb.Template>
|
||||||
|
<ControlTemplate>
|
||||||
|
<Border Background="#B1B9F8" Height="5" Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}" />
|
||||||
|
</ControlTemplate>
|
||||||
|
</Thumb.Template>
|
||||||
|
</Thumb>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</UserControl>
|
||||||
686
Workbench/Views/FlowCanvasView.xaml.cs
Normal file
686
Workbench/Views/FlowCanvasView.xaml.cs
Normal file
@@ -0,0 +1,686 @@
|
|||||||
|
using Serein.Library;
|
||||||
|
using Serein.Library.Api;
|
||||||
|
using Serein.Workbench.Node.View;
|
||||||
|
using Serein.Workbench.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Controls.Primitives;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Media.Media3D;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// FlowCanvasView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class FlowCanvasView : UserControl
|
||||||
|
{
|
||||||
|
private FlowCanvasViewModel ViewModel;
|
||||||
|
/// <summary>
|
||||||
|
/// 存储所有的连接。考虑集成在运行环境中。
|
||||||
|
/// </summary>
|
||||||
|
private List<ConnectionControl> Connections { get; } = [];
|
||||||
|
|
||||||
|
#region 与画布相关的字段
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标记是否正在尝试选取控件
|
||||||
|
/// </summary>
|
||||||
|
private bool IsSelectControl;
|
||||||
|
/// <summary>
|
||||||
|
/// 标记是否正在进行连接操作
|
||||||
|
/// </summary>
|
||||||
|
//private bool IsConnecting;
|
||||||
|
/// <summary>
|
||||||
|
/// 标记是否正在拖动控件
|
||||||
|
/// </summary>
|
||||||
|
private bool IsControlDragging;
|
||||||
|
/// <summary>
|
||||||
|
/// 标记是否正在拖动画布
|
||||||
|
/// </summary>
|
||||||
|
private bool IsCanvasDragging;
|
||||||
|
private bool IsSelectDragging;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前选取的控件
|
||||||
|
/// </summary>
|
||||||
|
private readonly List<NodeControlBase> selectNodeControls = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录开始拖动节点控件时的鼠标位置
|
||||||
|
/// </summary>
|
||||||
|
private Point startControlDragPoint;
|
||||||
|
/// <summary>
|
||||||
|
/// 记录移动画布开始时的鼠标位置
|
||||||
|
/// </summary>
|
||||||
|
private Point startCanvasDragPoint;
|
||||||
|
/// <summary>
|
||||||
|
/// 记录开始选取节点控件时的鼠标位置
|
||||||
|
/// </summary>
|
||||||
|
private Point startSelectControolPoint;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录开始连接的文本块
|
||||||
|
/// </summary>
|
||||||
|
//private NodeControlBase? startConnectNodeControl;
|
||||||
|
/// <summary>
|
||||||
|
/// 当前正在绘制的连接线
|
||||||
|
/// </summary>
|
||||||
|
//private Line? currentLine;
|
||||||
|
/// <summary>
|
||||||
|
/// 当前正在绘制的真假分支属性
|
||||||
|
/// </summary>
|
||||||
|
//private ConnectionInvokeType currentConnectionType;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 组合变换容器
|
||||||
|
/// </summary>
|
||||||
|
private readonly TransformGroup canvasTransformGroup;
|
||||||
|
/// <summary>
|
||||||
|
/// 缩放画布
|
||||||
|
/// </summary>
|
||||||
|
private readonly ScaleTransform scaleTransform;
|
||||||
|
/// <summary>
|
||||||
|
/// 平移画布
|
||||||
|
/// </summary>
|
||||||
|
private readonly TranslateTransform translateTransform;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private IFlowEnvironment EnvDecorator;
|
||||||
|
public FlowCanvasView()
|
||||||
|
{
|
||||||
|
ViewModel = App.GetService<Locator>().FlowCanvasViewModel;
|
||||||
|
|
||||||
|
EnvDecorator = App.GetService<IFlowEnvironment>();
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
#region 缩放平移容器
|
||||||
|
canvasTransformGroup = new TransformGroup();
|
||||||
|
scaleTransform = new ScaleTransform();
|
||||||
|
translateTransform = new TranslateTransform();
|
||||||
|
canvasTransformGroup.Children.Add(scaleTransform);
|
||||||
|
canvasTransformGroup.Children.Add(translateTransform);
|
||||||
|
FlowChartCanvas.RenderTransform = canvasTransformGroup;
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 鼠标在画布移动。
|
||||||
|
/// 选择控件状态下,调整选择框大小
|
||||||
|
/// 连接状态下,实时更新连接线的终点位置。
|
||||||
|
/// 移动画布状态下,移动画布。
|
||||||
|
/// </summary>
|
||||||
|
private void FlowChartCanvas_MouseMove(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
var myData = GlobalJunctionData.MyGlobalConnectingData;
|
||||||
|
if (myData.IsCreateing && e.LeftButton == MouseButtonState.Pressed)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (myData.Type == JunctionOfConnectionType.Invoke)
|
||||||
|
{
|
||||||
|
ViewModel.IsConnectionInvokeNode = true; // 正在连接节点的调用关系
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ViewModel.IsConnectionArgSourceNode = true; // 正在连接节点的调用关系
|
||||||
|
}
|
||||||
|
var currentPoint = e.GetPosition(FlowChartCanvas);
|
||||||
|
currentPoint.X -= 2;
|
||||||
|
currentPoint.Y -= 2;
|
||||||
|
myData.UpdatePoint(currentPoint);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (IsCanvasDragging && e.MiddleButton == MouseButtonState.Pressed) // 正在移动画布(按住中键)
|
||||||
|
{
|
||||||
|
Point currentMousePosition = e.GetPosition(this);
|
||||||
|
double deltaX = currentMousePosition.X - startCanvasDragPoint.X;
|
||||||
|
double deltaY = currentMousePosition.Y - startCanvasDragPoint.Y;
|
||||||
|
|
||||||
|
translateTransform.X += deltaX;
|
||||||
|
translateTransform.Y += deltaY;
|
||||||
|
|
||||||
|
startCanvasDragPoint = currentMousePosition;
|
||||||
|
|
||||||
|
foreach (var line in Connections)
|
||||||
|
{
|
||||||
|
line.RefreshLine(); // 画布移动时刷新所有连接线
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsSelectControl) // 正在选取节点
|
||||||
|
{
|
||||||
|
IsSelectDragging = e.LeftButton == MouseButtonState.Pressed;
|
||||||
|
// 获取当前鼠标位置
|
||||||
|
Point currentPoint = e.GetPosition(FlowChartCanvas);
|
||||||
|
|
||||||
|
// 更新选取矩形的位置和大小
|
||||||
|
double x = Math.Min(currentPoint.X, startSelectControolPoint.X);
|
||||||
|
double y = Math.Min(currentPoint.Y, startSelectControolPoint.Y);
|
||||||
|
double width = Math.Abs(currentPoint.X - startSelectControolPoint.X);
|
||||||
|
double height = Math.Abs(currentPoint.Y - startSelectControolPoint.Y);
|
||||||
|
|
||||||
|
Canvas.SetLeft(SelectionRectangle, x);
|
||||||
|
Canvas.SetTop(SelectionRectangle, y);
|
||||||
|
SelectionRectangle.Width = width;
|
||||||
|
SelectionRectangle.Height = height;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 放置操作,根据拖放数据创建相应的控件,并处理相关操作
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void FlowChartCanvas_Drop(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var canvasDropPosition = e.GetPosition(FlowChartCanvas); // 更新画布落点
|
||||||
|
PositionOfUI position = new PositionOfUI(canvasDropPosition.X, canvasDropPosition.Y);
|
||||||
|
if (e.Data.GetDataPresent(MouseNodeType.CreateDllNodeInCanvas))
|
||||||
|
{
|
||||||
|
if (e.Data.GetData(MouseNodeType.CreateDllNodeInCanvas) is MoveNodeData nodeData)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
Type when typeof(GlobalDataControl).IsAssignableFrom(droppedType) => NodeControlType.GlobalData,
|
||||||
|
Type when typeof(ScriptNodeControl).IsAssignableFrom(droppedType) => NodeControlType.Script,
|
||||||
|
Type when typeof(NetScriptNodeControl).IsAssignableFrom(droppedType) => NodeControlType.NetScript,
|
||||||
|
_ => NodeControlType.None,
|
||||||
|
};
|
||||||
|
if (nodeControlType != NodeControlType.None)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await EnvDecorator.CreateNodeAsync(nodeControlType, position); // 创建基础节点对象
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.ERROR, ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拖动效果,根据拖放数据是否为指定类型设置拖放效果
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void FlowChartCanvas_DragOver(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Data.GetDataPresent(MouseNodeType.CreateDllNodeInCanvas)
|
||||||
|
|| e.Data.GetDataPresent(MouseNodeType.CreateBaseNodeInCanvas))
|
||||||
|
{
|
||||||
|
e.Effects = DragDropEffects.Move;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e.Effects = DragDropEffects.None;
|
||||||
|
}
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在画布中尝试选取控件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void FlowChartCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (GlobalJunctionData.MyGlobalConnectingData.IsCreateing)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!IsSelectControl)
|
||||||
|
{
|
||||||
|
// 进入选取状态
|
||||||
|
IsSelectControl = true;
|
||||||
|
IsSelectDragging = false; // 初始化为非拖动状态
|
||||||
|
|
||||||
|
// 记录鼠标起始点
|
||||||
|
startSelectControolPoint = e.GetPosition(FlowChartCanvas);
|
||||||
|
|
||||||
|
// 初始化选取矩形的位置和大小
|
||||||
|
Canvas.SetLeft(SelectionRectangle, startSelectControolPoint.X);
|
||||||
|
Canvas.SetTop(SelectionRectangle, startSelectControolPoint.Y);
|
||||||
|
SelectionRectangle.Width = 0;
|
||||||
|
SelectionRectangle.Height = 0;
|
||||||
|
|
||||||
|
// 显示选取矩形
|
||||||
|
SelectionRectangle.Visibility = Visibility.Visible;
|
||||||
|
SelectionRectangle.ContextMenu ??= ConfiguerSelectionRectangle();
|
||||||
|
|
||||||
|
// 捕获鼠标,以便在鼠标移动到Canvas外部时仍能处理事件
|
||||||
|
FlowChartCanvas.CaptureMouse();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 如果已经是选取状态,单击则认为结束框选
|
||||||
|
CompleteSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Handled = true; // 防止事件传播影响其他控件
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在画布中释放鼠标按下,结束选取状态 / 停止创建连线,尝试连接节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void FlowChartCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (IsSelectControl)
|
||||||
|
{
|
||||||
|
// 松开鼠标时判断是否为拖动操作
|
||||||
|
if (IsSelectDragging)
|
||||||
|
{
|
||||||
|
// 完成拖动框选
|
||||||
|
CompleteSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 释放鼠标捕获
|
||||||
|
FlowChartCanvas.ReleaseMouseCapture();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建连线
|
||||||
|
if (GlobalJunctionData.MyGlobalConnectingData is ConnectingData myData && myData.IsCreateing)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (myData.IsCanConnected)
|
||||||
|
{
|
||||||
|
var canvas = this.FlowChartCanvas;
|
||||||
|
var currentendPoint = e.GetPosition(canvas); // 当前鼠标落点
|
||||||
|
var changingJunctionPosition = myData.CurrentJunction.TranslatePoint(new Point(0, 0), canvas);
|
||||||
|
var changingJunctionRect = new Rect(changingJunctionPosition, new Size(myData.CurrentJunction.Width, myData.CurrentJunction.Height));
|
||||||
|
|
||||||
|
if (changingJunctionRect.Contains(currentendPoint)) // 可以创建连接
|
||||||
|
{
|
||||||
|
#region 方法调用关系创建
|
||||||
|
if (myData.Type == JunctionOfConnectionType.Invoke)
|
||||||
|
{
|
||||||
|
this.EnvDecorator.ConnectInvokeNodeAsync(myData.StartJunction.MyNode.Guid, myData.CurrentJunction.MyNode.Guid,
|
||||||
|
myData.StartJunction.JunctionType,
|
||||||
|
myData.CurrentJunction.JunctionType,
|
||||||
|
myData.ConnectionInvokeType);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 参数来源关系创建
|
||||||
|
else if (myData.Type == JunctionOfConnectionType.Arg)
|
||||||
|
{
|
||||||
|
var argIndex = 0;
|
||||||
|
if (myData.StartJunction is ArgJunctionControl argJunction1)
|
||||||
|
{
|
||||||
|
argIndex = argJunction1.ArgIndex;
|
||||||
|
}
|
||||||
|
else if (myData.CurrentJunction is ArgJunctionControl argJunction2)
|
||||||
|
{
|
||||||
|
argIndex = argJunction2.ArgIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.EnvDecorator.ConnectArgSourceNodeAsync(myData.StartJunction.MyNode.Guid, myData.CurrentJunction.MyNode.Guid,
|
||||||
|
myData.StartJunction.JunctionType,
|
||||||
|
myData.CurrentJunction.JunctionType,
|
||||||
|
myData.ConnectionArgSourceType,
|
||||||
|
argIndex);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
EndConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
e.Handled = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region 拖动画布实现缩放平移效果
|
||||||
|
private void FlowChartCanvas_MouseDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
IsCanvasDragging = true;
|
||||||
|
startCanvasDragPoint = e.GetPosition(this);
|
||||||
|
FlowChartCanvas.CaptureMouse();
|
||||||
|
e.Handled = true; // 防止事件传播影响其他控件
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FlowChartCanvas_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (IsCanvasDragging)
|
||||||
|
{
|
||||||
|
IsCanvasDragging = false;
|
||||||
|
FlowChartCanvas.ReleaseMouseCapture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单纯缩放画布,不改变画布大小
|
||||||
|
private void FlowChartCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||||
|
{
|
||||||
|
// if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
||||||
|
{
|
||||||
|
if (e.Delta < 0 && scaleTransform.ScaleX < 0.05) return;
|
||||||
|
if (e.Delta > 0 && scaleTransform.ScaleY > 2.0) return;
|
||||||
|
// 获取鼠标在 Canvas 内的相对位置
|
||||||
|
var mousePosition = e.GetPosition(FlowChartCanvas);
|
||||||
|
|
||||||
|
// 缩放因子,根据滚轮方向调整
|
||||||
|
//double zoomFactor = e.Delta > 0 ? 0.1 : -0.1;
|
||||||
|
double zoomFactor = e.Delta > 0 ? 1.1 : 0.9;
|
||||||
|
|
||||||
|
// 当前缩放比例
|
||||||
|
double oldScale = scaleTransform.ScaleX;
|
||||||
|
double newScale = oldScale * zoomFactor;
|
||||||
|
//double newScale = oldScale + zoomFactor;
|
||||||
|
// 更新缩放比例
|
||||||
|
scaleTransform.ScaleX = newScale;
|
||||||
|
scaleTransform.ScaleY = newScale;
|
||||||
|
|
||||||
|
// 计算缩放前后鼠标相对于 Canvas 的位置差异
|
||||||
|
// double offsetX = mousePosition.X - (mousePosition.X * zoomFactor);
|
||||||
|
// double offsetY = mousePosition.Y - (mousePosition.Y * zoomFactor);
|
||||||
|
|
||||||
|
// 更新 TranslateTransform,确保以鼠标位置为中心进行缩放
|
||||||
|
translateTransform.X -= (mousePosition.X * (newScale - oldScale));
|
||||||
|
translateTransform.Y -= (mousePosition.Y * (newScale - oldScale));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置画布宽度高度
|
||||||
|
private void InitializeCanvas(double width, double height)
|
||||||
|
{
|
||||||
|
FlowChartCanvas.Width = width;
|
||||||
|
FlowChartCanvas.Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 动态调整区域大小
|
||||||
|
//private void Thumb_DragDelta_TopLeft(object sender, DragDeltaEventArgs e)
|
||||||
|
//{
|
||||||
|
// // 从左上角调整大小
|
||||||
|
// double newWidth = Math.Max(FlowChartCanvas.ActualWidth - e.HorizontalChange, 0);
|
||||||
|
// double newHeight = Math.Max(FlowChartCanvas.ActualHeight - e.VerticalChange, 0);
|
||||||
|
|
||||||
|
// FlowChartCanvas.Width = newWidth;
|
||||||
|
// FlowChartCanvas.Height = newHeight;
|
||||||
|
|
||||||
|
// Canvas.SetLeft(FlowChartCanvas, Canvas.GetLeft(FlowChartCanvas) + e.HorizontalChange);
|
||||||
|
// Canvas.SetTop(FlowChartCanvas, Canvas.GetTop(FlowChartCanvas) + e.VerticalChange);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private void Thumb_DragDelta_TopRight(object sender, DragDeltaEventArgs e)
|
||||||
|
//{
|
||||||
|
// // 从右上角调整大小
|
||||||
|
// double newWidth = Math.Max(FlowChartCanvas.ActualWidth + e.HorizontalChange, 0);
|
||||||
|
// double newHeight = Math.Max(FlowChartCanvas.ActualHeight - e.VerticalChange, 0);
|
||||||
|
|
||||||
|
// FlowChartCanvas.Width = newWidth;
|
||||||
|
// FlowChartCanvas.Height = newHeight;
|
||||||
|
|
||||||
|
// Canvas.SetTop(FlowChartCanvas, Canvas.GetTop(FlowChartCanvas) + e.VerticalChange);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private void Thumb_DragDelta_BottomLeft(object sender, DragDeltaEventArgs e)
|
||||||
|
//{
|
||||||
|
// // 从左下角调整大小
|
||||||
|
// double newWidth = Math.Max(FlowChartCanvas.ActualWidth - e.HorizontalChange, 0);
|
||||||
|
// double newHeight = Math.Max(FlowChartCanvas.ActualHeight + e.VerticalChange, 0);
|
||||||
|
|
||||||
|
// FlowChartCanvas.Width = newWidth;
|
||||||
|
// FlowChartCanvas.Height = newHeight;
|
||||||
|
|
||||||
|
// Canvas.SetLeft(FlowChartCanvas, Canvas.GetLeft(FlowChartCanvas) + e.HorizontalChange);
|
||||||
|
//}
|
||||||
|
|
||||||
|
private void Thumb_DragDelta_BottomRight(object sender, DragDeltaEventArgs e)
|
||||||
|
{
|
||||||
|
// 获取缩放后的水平和垂直变化
|
||||||
|
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);
|
||||||
|
|
||||||
|
newHeight = newHeight < 400 ? 400 : newHeight;
|
||||||
|
newWidth = newWidth < 400 ? 400 : newWidth;
|
||||||
|
|
||||||
|
InitializeCanvas(newWidth, newHeight);
|
||||||
|
|
||||||
|
//// 从右下角调整大小
|
||||||
|
//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)
|
||||||
|
//{
|
||||||
|
// // 从左侧调整大小
|
||||||
|
// double newWidth = Math.Max(FlowChartCanvas.ActualWidth - e.HorizontalChange, 0);
|
||||||
|
|
||||||
|
// FlowChartCanvas.Width = newWidth;
|
||||||
|
// Canvas.SetLeft(FlowChartCanvas, Canvas.GetLeft(FlowChartCanvas) + e.HorizontalChange);
|
||||||
|
//}
|
||||||
|
|
||||||
|
private void Thumb_DragDelta_Right(object sender, DragDeltaEventArgs e)
|
||||||
|
{
|
||||||
|
//从右侧调整大小
|
||||||
|
// 获取缩放后的水平变化
|
||||||
|
double horizontalChange = e.HorizontalChange * scaleTransform.ScaleX;
|
||||||
|
|
||||||
|
// 计算新的宽度,确保不会小于400
|
||||||
|
double newWidth = Math.Max(FlowChartCanvas.ActualWidth + horizontalChange, 400);
|
||||||
|
|
||||||
|
newWidth = newWidth < 400 ? 400 : newWidth;
|
||||||
|
InitializeCanvas(newWidth, FlowChartCanvas.Height);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//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 verticalChange = e.VerticalChange * scaleTransform.ScaleY;
|
||||||
|
// 计算新的高度,确保不会小于400
|
||||||
|
double newHeight = Math.Max(FlowChartCanvas.ActualHeight + verticalChange, 400);
|
||||||
|
newHeight = newHeight < 400 ? 400 : newHeight;
|
||||||
|
InitializeCanvas(FlowChartCanvas.Width, newHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void Test(double deltaX, double deltaY)
|
||||||
|
{
|
||||||
|
//Console.WriteLine((translateTransform.X, translateTransform.Y));
|
||||||
|
//translateTransform.X += deltaX;
|
||||||
|
//translateTransform.Y += deltaY;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// 完成选取操作
|
||||||
|
/// </summary>
|
||||||
|
private void CompleteSelection()
|
||||||
|
{
|
||||||
|
IsSelectControl = false;
|
||||||
|
|
||||||
|
// 隐藏选取矩形
|
||||||
|
SelectionRectangle.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
// 获取选取范围
|
||||||
|
Rect selectionArea = new Rect(Canvas.GetLeft(SelectionRectangle),
|
||||||
|
Canvas.GetTop(SelectionRectangle),
|
||||||
|
SelectionRectangle.Width,
|
||||||
|
SelectionRectangle.Height);
|
||||||
|
|
||||||
|
// 处理选取范围内的控件
|
||||||
|
// selectNodeControls.Clear();
|
||||||
|
foreach (UIElement element in FlowChartCanvas.Children)
|
||||||
|
{
|
||||||
|
Rect elementBounds = new Rect(Canvas.GetLeft(element), Canvas.GetTop(element),
|
||||||
|
element.RenderSize.Width, element.RenderSize.Height);
|
||||||
|
|
||||||
|
if (selectionArea.Contains(elementBounds))
|
||||||
|
{
|
||||||
|
if (element is NodeControlBase control)
|
||||||
|
{
|
||||||
|
if (!selectNodeControls.Contains(control))
|
||||||
|
{
|
||||||
|
selectNodeControls.Add(control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中后的操作
|
||||||
|
SelectedNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SelectedNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (selectNodeControls.Count == 0)
|
||||||
|
{
|
||||||
|
//Console.WriteLine($"没有选择控件");
|
||||||
|
SelectionRectangle.Visibility = Visibility.Collapsed;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (selectNodeControls.Count == 1)
|
||||||
|
{
|
||||||
|
// ChangeViewerObjOfNode(selectNodeControls[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Console.WriteLine($"一共选取了{selectNodeControls.Count}个控件");
|
||||||
|
foreach (var node in selectNodeControls)
|
||||||
|
{
|
||||||
|
//node.ViewModel.IsSelect =true;
|
||||||
|
// node.ViewModel.CancelSelect();
|
||||||
|
node.BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFC700"));
|
||||||
|
node.BorderThickness = new Thickness(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束连接操作,清理状态并移除虚线。
|
||||||
|
/// </summary>
|
||||||
|
private void EndConnection()
|
||||||
|
{
|
||||||
|
Mouse.OverrideCursor = null; // 恢复视觉效果
|
||||||
|
ViewModel.IsConnectionArgSourceNode = false;
|
||||||
|
ViewModel.IsConnectionInvokeNode = false;
|
||||||
|
GlobalJunctionData.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建菜单子项
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="header"></param>
|
||||||
|
/// <param name="handler"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static MenuItem CreateMenuItem(string header, RoutedEventHandler handler)
|
||||||
|
{
|
||||||
|
var menuItem = new MenuItem { Header = header };
|
||||||
|
menuItem.Click += handler;
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private ContextMenu ConfiguerSelectionRectangle()
|
||||||
|
{
|
||||||
|
var contextMenu = new ContextMenu();
|
||||||
|
contextMenu.Items.Add(CreateMenuItem("删除", (s, e) =>
|
||||||
|
{
|
||||||
|
if (selectNodeControls.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var node in selectNodeControls.ToArray())
|
||||||
|
{
|
||||||
|
var guid = node?.ViewModel?.NodeModel?.Guid;
|
||||||
|
if (!string.IsNullOrEmpty(guid))
|
||||||
|
{
|
||||||
|
EnvDecorator.RemoveNodeAsync(guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SelectionRectangle.Visibility = Visibility.Collapsed;
|
||||||
|
}));
|
||||||
|
return contextMenu;
|
||||||
|
// nodeControl.ContextMenu = contextMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Workbench/Views/FlowEditView.xaml
Normal file
13
Workbench/Views/FlowEditView.xaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<UserControl x:Class="Serein.Workbench.Views.FlowEditView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
Background="#FFD3D3D3">
|
||||||
|
<Grid>
|
||||||
|
<local:FlowCanvasView></local:FlowCanvasView>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
31
Workbench/Views/FlowEditView.xaml.cs
Normal file
31
Workbench/Views/FlowEditView.xaml.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using Serein.Workbench.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// FlowEditView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class FlowEditView : UserControl
|
||||||
|
{
|
||||||
|
public FlowEditView()
|
||||||
|
{
|
||||||
|
this.DataContext = App.GetService<Locator>().FlowEditViewModel;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
92
Workbench/Views/FlowLibrarysView.xaml
Normal file
92
Workbench/Views/FlowLibrarysView.xaml
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<UserControl x:Class="Serein.Workbench.Views.FlowLibrarysView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
xmlns:converter="clr-namespace:Serein.Workbench.Converters"
|
||||||
|
xmlns:custom="clr-namespace:Serein.Workbench.Customs"
|
||||||
|
xmlns:vm="clr-namespace:Serein.Workbench.ViewModels"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DataContext="{d:DesignInstance vm:FlowLibrarysViewModel}"
|
||||||
|
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
|
|
||||||
|
<UserControl.Resources>
|
||||||
|
<converter:CountToVisibilityConverter x:Key="CountToVisibilityConverter"/>
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<ScrollViewer>
|
||||||
|
<ItemsControl ItemsSource="{Binding FlowLibraryInfos}">
|
||||||
|
<ItemsControl.ItemTemplate >
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Margin="6,6,2,10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding LibraryName}" ></TextBlock>
|
||||||
|
<TextBlock Text="{Binding FilePath}" Margin="6,0,0,0"></TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!--<custom:FlowMethodInfoListBox Grid.Row="1" Nodes="{Binding ActionNodes}" BackgroundColor="#D0F1F9"/>
|
||||||
|
<custom:FlowMethodInfoListBox Grid.Row="2" Nodes="{Binding FlipflopNodes}" BackgroundColor="#FACFC1"/>
|
||||||
|
<custom:FlowMethodInfoListBox Grid.Row="3" Nodes="{Binding UINodes}" BackgroundColor="#FFFBD7"/>-->
|
||||||
|
|
||||||
|
<ListBox Grid.Row="1" Margin="6,2,2,2" ItemsSource="{Binding ActionNodes}"
|
||||||
|
Visibility="{Binding ActionNodes, Converter={StaticResource CountToVisibilityConverter}}"
|
||||||
|
Background="#D0F1F9">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Margin="2" >
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding NodeType}"></TextBlock>
|
||||||
|
<TextBlock Text="{Binding AnotherName}" Margin="4,0,0,0"></TextBlock>
|
||||||
|
<TextBlock Text="{Binding MethodName}" Margin="6,0,0,0"></TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
|
||||||
|
<ListBox Grid.Row="2" Margin="6,2,2,2" ItemsSource="{Binding FlipflopNodes}"
|
||||||
|
Visibility="{Binding FlipflopNodes, Converter={StaticResource CountToVisibilityConverter}}"
|
||||||
|
Background="#FACFC1">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Margin="2" >
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding NodeType}"></TextBlock>
|
||||||
|
<TextBlock Text="{Binding AnotherName}" Margin="4,0,0,0"></TextBlock>
|
||||||
|
<TextBlock Text="{Binding MethodName}" Margin="6,0,0,0"></TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
|
||||||
|
<ListBox Grid.Row="3" Margin="6,2,2,2" ItemsSource="{Binding UINodes}"
|
||||||
|
Visibility="{Binding UINodes, Converter={StaticResource CountToVisibilityConverter}}"
|
||||||
|
Background="#FFFBD7">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Margin="2" >
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding NodeType}"></TextBlock>
|
||||||
|
<TextBlock Text="{Binding AnotherName}" Margin="4,0,0,0"></TextBlock>
|
||||||
|
<TextBlock Text="{Binding MethodName}" Margin="6,0,0,0"></TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ScrollViewer>
|
||||||
|
</UserControl>
|
||||||
30
Workbench/Views/FlowLibrarysView.xaml.cs
Normal file
30
Workbench/Views/FlowLibrarysView.xaml.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Serein.Workbench.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// FlowLibrarysView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class FlowLibrarysView : UserControl
|
||||||
|
{
|
||||||
|
public FlowLibrarysView()
|
||||||
|
{
|
||||||
|
this.DataContext = App.GetService<Locator>().FlowLibrarysViewModel;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Workbench/Views/FlowWorkbenchView.xaml
Normal file
40
Workbench/Views/FlowWorkbenchView.xaml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<Window x:Class="Serein.Workbench.Views.FlowWorkbenchView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Loaded="Window_Loaded"
|
||||||
|
Title="FlowWorkbenchView" Height="450" Width="800">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="250"/>
|
||||||
|
<ColumnDefinition Width="5"/>
|
||||||
|
<ColumnDefinition Width="3*"/>
|
||||||
|
<ColumnDefinition Width="5"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<!--顶部菜单栏-->
|
||||||
|
<local:MainMenuBarView Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="5"/>
|
||||||
|
|
||||||
|
<!--左侧功能区-->
|
||||||
|
<Grid Grid.Row="1" Grid.Column="0" >
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"></RowDefinition>
|
||||||
|
<RowDefinition Height="*"></RowDefinition>
|
||||||
|
<!--<RowDefinition Height="3"></RowDefinition>-->
|
||||||
|
<!--<RowDefinition Height="3*"></RowDefinition>-->
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<local:BaseNodesView Grid.Row="0" Grid.ColumnSpan="1" Margin="0,0,0,15"/>
|
||||||
|
<local:FlowLibrarysView Grid.Row="1" Grid.ColumnSpan="1" Margin="0,0,0,15"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!--流程编辑区-->
|
||||||
|
<local:FlowEditView Grid.Row="1" Grid.Column="2"/>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
45
Workbench/Views/FlowWorkbenchView.xaml.cs
Normal file
45
Workbench/Views/FlowWorkbenchView.xaml.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using Serein.Workbench.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// FlowWorkbenchView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class FlowWorkbenchView : Window
|
||||||
|
{
|
||||||
|
public FlowWorkbenchView()
|
||||||
|
{
|
||||||
|
this.DataContext = App.GetService<Locator>().FlowWorkbenchViewModel;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.MaxHeight = SystemParameters.PrimaryScreenHeight;
|
||||||
|
this.WindowState = WindowState.Maximized;
|
||||||
|
// 设置全屏
|
||||||
|
/*this.WindowState = System.Windows.WindowState.Normal;
|
||||||
|
this.WindowStyle = System.Windows.WindowStyle.None;
|
||||||
|
this.ResizeMode = System.Windows.ResizeMode.NoResize;
|
||||||
|
this.Topmost = true;
|
||||||
|
|
||||||
|
this.Left = 0.0;
|
||||||
|
this.Top = 0.0;
|
||||||
|
this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
|
||||||
|
this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Workbench/Views/MainMenuBarView.xaml
Normal file
37
Workbench/Views/MainMenuBarView.xaml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<UserControl x:Class="Serein.Workbench.Views.MainMenuBarView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="70" d:DesignWidth="350">
|
||||||
|
<Grid >
|
||||||
|
<Menu DockPanel.Dock="Top" Grid.Row="0" Grid.ColumnSpan="5" Height="20">
|
||||||
|
<MenuItem Header="项目">
|
||||||
|
<MenuItem Header="保存项目" ></MenuItem>
|
||||||
|
<MenuItem Header="打开本地文件" ></MenuItem>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="拓展">
|
||||||
|
<MenuItem Header="动态编译" ></MenuItem>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="调试">
|
||||||
|
<MenuItem Header="运行(从起始节点)"></MenuItem>
|
||||||
|
<MenuItem Header="运行(从选定节点)" ></MenuItem>
|
||||||
|
<MenuItem Header="结束流程" ></MenuItem>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="视图">
|
||||||
|
<MenuItem Header="输出窗口" ></MenuItem>
|
||||||
|
<MenuItem Header="重置画布"></MenuItem>
|
||||||
|
<MenuItem Header="定位节点" ></MenuItem>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="远程">
|
||||||
|
<MenuItem Header="启动远程服务"></MenuItem>
|
||||||
|
|
||||||
|
<MenuItem Header="连接远程环境"></MenuItem>
|
||||||
|
</MenuItem>
|
||||||
|
<!--<MenuItem Header="说明"></MenuItem>-->
|
||||||
|
</Menu>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
30
Workbench/Views/MainMenuBarView.xaml.cs
Normal file
30
Workbench/Views/MainMenuBarView.xaml.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Serein.Workbench.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// MainMenuBarView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class MainMenuBarView : UserControl
|
||||||
|
{
|
||||||
|
public MainMenuBarView()
|
||||||
|
{
|
||||||
|
this.DataContext = App.GetService<Locator>().MainViewModel;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Workbench/Views/MainView.xaml
Normal file
13
Workbench/Views/MainView.xaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<UserControl x:Class="Serein.Workbench.Views.MainView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
30
Workbench/Views/MainView.xaml.cs
Normal file
30
Workbench/Views/MainView.xaml.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Serein.Workbench.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// MainView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class MainView : UserControl
|
||||||
|
{
|
||||||
|
public MainView()
|
||||||
|
{
|
||||||
|
this.DataContext = App.GetService<Locator>().MainViewModel;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user