diff --git a/Library/Api/IFlowEnvironment.cs b/Library/Api/IFlowEnvironment.cs index e6f34de..872601e 100644 --- a/Library/Api/IFlowEnvironment.cs +++ b/Library/Api/IFlowEnvironment.cs @@ -313,13 +313,12 @@ namespace Serein.Library.Api /// public class CanvasCreateEventArgs : FlowEventArgs { - public CanvasCreateEventArgs( - FlowCanvasInfo info) + public CanvasCreateEventArgs(FlowCanvasModel model) { - Info = info; + Model = model; } - public FlowCanvasInfo Info { get; } + public FlowCanvasModel Model { get; } } /// @@ -888,7 +887,7 @@ namespace Serein.Library.Api /// /// 画布Guid /// - Task RemoteCanvasAsync(string canvasGuid); + Task RemoveCanvasAsync(string canvasGuid); /// diff --git a/NodeFlow/Env/FlowEnvironment.cs b/NodeFlow/Env/FlowEnvironment.cs index bb6158a..ee66013 100644 --- a/NodeFlow/Env/FlowEnvironment.cs +++ b/NodeFlow/Env/FlowEnvironment.cs @@ -783,9 +783,9 @@ namespace Serein.NodeFlow.Env Name = canvasName, Width = height, }; - var info = model.ToInfo(); FlowCanvass.Add(model.Guid, model); - OnCanvasCreate.Invoke(new CanvasCreateEventArgs(info)); + OnCanvasCreate.Invoke(new CanvasCreateEventArgs(model)); + var info = model.ToInfo(); return Task.FromResult(info); } @@ -794,7 +794,7 @@ namespace Serein.NodeFlow.Env /// /// 画布Guid /// - public Task RemoteCanvasAsync(string canvasGuid) + public Task RemoveCanvasAsync(string canvasGuid) { if (!FlowCanvass.TryGetValue(canvasGuid, out var model)) diff --git a/NodeFlow/Env/FlowEnvironmentDecorator.cs b/NodeFlow/Env/FlowEnvironmentDecorator.cs index c19b175..8d310a0 100644 --- a/NodeFlow/Env/FlowEnvironmentDecorator.cs +++ b/NodeFlow/Env/FlowEnvironmentDecorator.cs @@ -248,9 +248,9 @@ namespace Serein.NodeFlow.Env /// /// 画布Guid /// - public async Task RemoteCanvasAsync(string canvasGuid) + public async Task RemoveCanvasAsync(string canvasGuid) { - return await currentFlowEnvironment.RemoteCanvasAsync(canvasGuid); + return await currentFlowEnvironment.RemoveCanvasAsync(canvasGuid); } diff --git a/NodeFlow/Env/MsgControllerOfServer.cs b/NodeFlow/Env/MsgControllerOfServer.cs index 8504803..b896383 100644 --- a/NodeFlow/Env/MsgControllerOfServer.cs +++ b/NodeFlow/Env/MsgControllerOfServer.cs @@ -321,7 +321,7 @@ namespace Serein.NodeFlow.Env [AutoSocketHandle(ThemeValue = EnvMsgTheme.RemoveCanvas, IsReturnValue = false)] public async Task RemoveCanvas([Needful] string canvasGuid) { - var result = await environment.RemoteCanvasAsync(canvasGuid); // 监听到客户端创建节点的请求 + var result = await environment.RemoveCanvasAsync(canvasGuid); // 监听到客户端创建节点的请求 return new { state = result} ; } diff --git a/NodeFlow/Env/RemoteFlowEnvironment.cs b/NodeFlow/Env/RemoteFlowEnvironment.cs index a98f42c..7558825 100644 --- a/NodeFlow/Env/RemoteFlowEnvironment.cs +++ b/NodeFlow/Env/RemoteFlowEnvironment.cs @@ -458,7 +458,7 @@ namespace Serein.NodeFlow.Env /// /// 画布Guid /// - public async Task RemoteCanvasAsync(string canvasGuid) + public async Task RemoveCanvasAsync(string canvasGuid) { var result = await msgClient.SendAndWaitDataAsync(EnvMsgTheme.RemoveCanvas, new { diff --git a/Workbench/Api/IFlowEEForwardingService.cs b/Workbench/Api/IFlowEEForwardingService.cs index cb0d623..47e9dac 100644 --- a/Workbench/Api/IFlowEEForwardingService.cs +++ b/Workbench/Api/IFlowEEForwardingService.cs @@ -10,7 +10,7 @@ namespace Serein.Workbench.Api /// /// 流程事件管理,转发流程运行环境中触发的事件到工作台各个订阅者 /// - internal interface IFlowEEForwardingService : IFlowEnvironmentEvent + public interface IFlowEEForwardingService : IFlowEnvironmentEvent { } diff --git a/Workbench/App.xaml.cs b/Workbench/App.xaml.cs index 44d9b68..b200c20 100644 --- a/Workbench/App.xaml.cs +++ b/Workbench/App.xaml.cs @@ -39,7 +39,7 @@ namespace Serein.Workbench { collection.AddSingleton(); // 流程事件管理 collection.AddSingleton(); // 流程事件管理 - collection.AddSingleton(); // 节点操作管理 + collection.AddSingleton(); // 节点操作管理 // collection.AddSingleton(); // 按键事件管理 //collection.AddSingleton(); // 流程节点控件管理 } diff --git a/Workbench/Services/FlowNodeService.cs b/Workbench/Services/FlowNodeService.cs new file mode 100644 index 0000000..db24001 --- /dev/null +++ b/Workbench/Services/FlowNodeService.cs @@ -0,0 +1,192 @@ +using Serein.Library; +using Serein.Library.Api; +using Serein.Workbench.Api; +using Serein.Workbench.Node.View; +using Serein.Workbench.Node.ViewModel; +using Serein.Workbench.Views; + +namespace Serein.Workbench.Services +{ + /// + /// 流程节点管理 + /// + public class FlowNodeService + { + #region 流程节点操作的相关事件 + public Action OnCreateFlowCanvasView { get; set; } + public Action OnRemoveFlowCanvasView { get; set; } + #endregion + + + #region 创建节点相关的属性 + /// + /// 当前查看的画布 + /// + public FlowCanvasView CurrentSelectCanvas { get; set; } + + /// + /// 当前拖动的方法信息 + /// + public MethodDetailsInfo? CurrentDragMdInfo { get; set; } + + /// + /// 当前需要创建的节点类型 + /// + public NodeControlType? CurrentNodeControlType { get; set; } + + + /// + /// 当前鼠标位置 + /// + public PositionOfUI? CurrentMouseLocation { get; set; } + + /// + /// 当前选中的节点 + /// + public NodeControlBase? CurrentSelectNodeControl { get; set; } + #endregion + + /// + /// 连接开始节点 + /// + public NodeControlBase? ConnectionStartNode { get; set; } + /// + /// 连接最终落点节点 + /// + public NodeControlBase? ConnectionEndNode { get; set; } + + + /* + +*/ + + /// + /// 记录流程画布 + /// + private readonly Dictionary FlowCanvasViews = []; + /// + /// 记录加载的节点 + /// + private readonly Dictionary NodeControls = []; + + private readonly IFlowEnvironment flowEnvironment; + private readonly IFlowEEForwardingService flowEEForwardingService; + + #region 初始化 + public FlowNodeService(IFlowEnvironment flowEnvironment, + IFlowEEForwardingService flowEEForwardingService) + { + this.flowEnvironment = flowEnvironment; + this.flowEEForwardingService = flowEEForwardingService; + InitFlowEvent(); + } + + public void InitFlowEvent() + { + flowEEForwardingService.OnCanvasCreate += FlowEEForwardingService_OnCanvasCreate; + flowEEForwardingService.OnCanvasRemove += FlowEEForwardingService_OnCanvasRemove; + flowEEForwardingService.OnNodeCreate += FlowEEForwardingService_OnNodeCreate; + flowEEForwardingService.OnNodeRemove += FlowEEForwardingService_OnNodeRemove; + } + + private void FlowEEForwardingService_OnNodeRemove(NodeRemoveEventArgs eventArgs) + { + throw new NotImplementedException(); + } + + private void FlowEEForwardingService_OnNodeCreate(NodeCreateEventArgs eventArgs) + { + throw new NotImplementedException(); + } + + private void FlowEEForwardingService_OnCanvasRemove(CanvasRemoveEventArgs eventArgs) + { + OnRemoveFlowCanvasView.Invoke(eventArgs.CanvasGuid); + } + + private void FlowEEForwardingService_OnCanvasCreate(CanvasCreateEventArgs eventArgs) + { + var info = eventArgs.Model; + var model = eventArgs.Model; + FlowCanvasView canvasView = new FlowCanvasView(); + canvasView.ViewModel.CanvasGuid = info.Guid; + canvasView.ViewModel.Model = model; + FlowCanvasViews.Add(info.Guid, canvasView); + OnCreateFlowCanvasView.Invoke(canvasView); // 传递给订阅者 + } + + #endregion + + + + + #region 向运行环境发出请求 + + /// + /// 向运行环境发出请求:添加画布 + /// + /// + public void CreateFlowCanvas() + { + string canvasName = ""; + int height = 1000; + int width = 600; + _ = flowEnvironment.CreateCanvasAsync(canvasName, width, height); + } + + /// + /// 向运行环境发出请求:移除画布 + /// + public void RemoveFlowCanvas() + { + if (CurrentSelectCanvas is null) + { + return; + } + _ = flowEnvironment.RemoveCanvasAsync(CurrentSelectCanvas.ViewModel.CanvasGuid); + } + + /// + /// 向运行环境发出请求:创建节点 + /// + public void CreateNode() + { + string canvasGuid = CurrentSelectCanvas.ViewModel.CanvasGuid; + NodeControlType? nodeType = CurrentNodeControlType; + PositionOfUI? position = CurrentMouseLocation; + MethodDetailsInfo? methodDetailsInfo = CurrentDragMdInfo; + if (nodeType is null) + { + return; + } + if (position is null) + { + return; + } + _ = flowEnvironment.CreateNodeAsync(canvasGuid, (NodeControlType)nodeType, position, methodDetailsInfo); + } + + /// + /// 向运行环境发出请求:移除节点 + /// + public void RemoteNode() + { + NodeControlBase? node = CurrentSelectNodeControl; + if (node is null) + { + return; + } + var model = node.ViewModel.NodeModel; + if (model is null) + { + return; + } + + _ = flowEnvironment.RemoveNodeAsync(model.CanvasGuid, model.Guid); + } + + #endregion + + + } +} diff --git a/Workbench/Services/ProjectService.cs b/Workbench/Services/ProjectService.cs deleted file mode 100644 index 789551f..0000000 --- a/Workbench/Services/ProjectService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Serein.Workbench.Services -{ - internal class ProjectService - { - - } -} diff --git a/Workbench/ViewModels/FlowCanvasViewModel.cs b/Workbench/ViewModels/FlowCanvasViewModel.cs index df16e0a..fb9ea9f 100644 --- a/Workbench/ViewModels/FlowCanvasViewModel.cs +++ b/Workbench/ViewModels/FlowCanvasViewModel.cs @@ -1,4 +1,6 @@ using CommunityToolkit.Mvvm.ComponentModel; +using Serein.Library; +using Serein.Workbench.Node.View; using System; using System.Collections.Generic; using System.Linq; @@ -9,6 +11,12 @@ namespace Serein.Workbench.ViewModels { public partial class FlowCanvasViewModel : ObservableObject { + /// + /// 画布当前选中的节点 + /// + public NodeControlBase CurrentSelectNodeControl { get; set; } + + /// /// 正在创建节点方法调用关系 /// @@ -33,6 +41,12 @@ namespace Serein.Workbench.ViewModels [ObservableProperty] private string _canvasGuid; + /// + /// 画布数据实体 + /// + [ObservableProperty] + private FlowCanvasModel _model; + public FlowCanvasViewModel() diff --git a/Workbench/ViewModels/FlowEditViewModel.cs b/Workbench/ViewModels/FlowEditViewModel.cs index 24b0609..5f1549c 100644 --- a/Workbench/ViewModels/FlowEditViewModel.cs +++ b/Workbench/ViewModels/FlowEditViewModel.cs @@ -1,6 +1,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Serein.Workbench.Models; +using Serein.Workbench.Services; using Serein.Workbench.Views; using System; using System.Collections.Generic; @@ -10,6 +11,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; namespace Serein.Workbench.ViewModels { @@ -18,7 +20,7 @@ namespace Serein.Workbench.ViewModels /// public partial class FlowEditViewModel : ObservableObject { - public ObservableCollection Tabs { get; set; } + public ObservableCollection Tabs { get; set; } = []; public ICommand AddTabCommand { get; set; } public ICommand RemoveTabCommand { get; set; } public ICommand RenameTabCommand { get; set; } @@ -27,39 +29,59 @@ namespace Serein.Workbench.ViewModels private FlowCanvasModel _selectedTab; private int _addCount = 0; + private readonly FlowNodeService flowNodeService; - public FlowEditViewModel() + public FlowEditViewModel(FlowNodeService flowNodeService) { - Tabs = new ObservableCollection(); + this.flowNodeService = flowNodeService; AddTabCommand = new RelayCommand(AddTab); RemoveTabCommand = new RelayCommand(RemoveTab, CanRemoveTab); - // 初始化时添加一个默认的Tab - AddTab(); // 添加一个默认选项卡 + flowNodeService.OnCreateFlowCanvasView += OnCreateFlowCanvasView; // 环境创建了节点 + flowNodeService.OnRemoveFlowCanvasView += OnRemoveFlowCanvasView; + this.PropertyChanged += OnPropertyChanged; } - private void AddTab() + private void OnPropertyChanged(object? value, PropertyChangedEventArgs e) { - var flowCanvasView = new FlowCanvasView(); // 创建FlowCanvasView实例 - Tabs.Add(new FlowCanvasModel { Content = flowCanvasView ,Name = $"New Tab {_addCount++}"}); - SelectedTab = Tabs[Tabs.Count - 1]; // 选择刚添加的Tab - } - - private void RemoveTab() - { - if (Tabs.Count > 0 && SelectedTab != null) + if (nameof(SelectedTab).Equals(e.PropertyName) && value is FlowCanvasModel model) { - Tabs.Remove(SelectedTab); - SelectedTab = Tabs.Count > 0 ? Tabs[Tabs.Count - 1] : null; + flowNodeService.CurrentSelectCanvas = model.Content; // 选中的视图发生改变 } } - private bool CanRemoveTab() + #region 响应环境事件 + private void OnCreateFlowCanvasView(FlowCanvasView FlowCanvasView) { - return SelectedTab != null; + var model = new FlowCanvasModel { Content = FlowCanvasView, Name = FlowCanvasView.ViewModel.Name }; + Tabs.Add(model); + } + private void OnRemoveFlowCanvasView(string canvasGuid) + { + var tab = Tabs.FirstOrDefault(t => t.Content.ViewModel.Model.Guid.Equals(canvasGuid, StringComparison.OrdinalIgnoreCase)); + if (tab is null) + { + return; + } + Tabs.Remove(tab); + Tabs.Remove(SelectedTab); + if(Tabs.Count > 0 && Tabs[^1] is FlowCanvasModel view ) + { + SelectedTab = view; + } + } + #endregion + + + private void AddTab() => flowNodeService.CreateFlowCanvas(); + private void RemoveTab() + { + if (Tabs.Count > 0 && SelectedTab != null) flowNodeService.RemoveFlowCanvas(); } - + private bool CanRemoveTab() => SelectedTab != null; + + /// /// 进入编辑模式 diff --git a/Workbench/ViewModels/FlowLibrarysViewModel.cs b/Workbench/ViewModels/FlowLibrarysViewModel.cs index cdd91e5..122f978 100644 --- a/Workbench/ViewModels/FlowLibrarysViewModel.cs +++ b/Workbench/ViewModels/FlowLibrarysViewModel.cs @@ -2,6 +2,7 @@ using Serein.Library; using Serein.Workbench.Api; using Serein.Workbench.Models; +using Serein.Workbench.Services; using System; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/Workbench/ViewModels/MainMenuBarViewModel.cs b/Workbench/ViewModels/MainMenuBarViewModel.cs index 0a3a726..05f1d0e 100644 --- a/Workbench/ViewModels/MainMenuBarViewModel.cs +++ b/Workbench/ViewModels/MainMenuBarViewModel.cs @@ -1,12 +1,61 @@ using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Serein.Library.Api; +using System.Windows.Input; namespace Serein.Workbench.ViewModels { public class MainMenuBarViewModel : ObservableObject { - public MainMenuBarViewModel() + private readonly IFlowEnvironment environment; + + /// + /// 保存项目 + /// + public ICommand SaveProjectCommand { get; private set; } + /// + /// 加载本地文件 + /// + public ICommand LoadLocalProjectCommand { get; private set; } + /// + /// 加载远程项目 + /// + public ICommand LoadRemoteProjectCommand { get; private set; } + + /// + /// 增加流程图 + /// + public ICommand CreateFlowCanvasCommand { get; private set; } + + /// + /// 增加流程图 + /// + public ICommand RemoteFlowCanvasCommand { get; private set; } + + + /// + /// 打开环境输出窗口 + /// + public ICommand OpenEnvOutWindowCommand { get; private set; } + + /// + /// 打开动态编译窗口 + /// + public ICommand OpenDynamicCompilerCommand { get; private set; } + + + + public MainMenuBarViewModel(IFlowEnvironment environment) { - + this.environment = environment; + + SaveProjectCommand = new RelayCommand(SaveProject); } + + public void SaveProject() + { + + } + } } diff --git a/Workbench/Views/FlowCanvasView.xaml.cs b/Workbench/Views/FlowCanvasView.xaml.cs index 7cf93f9..b072ec1 100644 --- a/Workbench/Views/FlowCanvasView.xaml.cs +++ b/Workbench/Views/FlowCanvasView.xaml.cs @@ -26,7 +26,7 @@ namespace Serein.Workbench.Views /// public partial class FlowCanvasView : UserControl { - private FlowCanvasViewModel ViewModel; + public FlowCanvasViewModel ViewModel => ViewModel as FlowCanvasViewModel; /// /// 存储所有的连接。考虑集成在运行环境中。 /// diff --git a/Workbench/Views/MainMenuBarView.xaml b/Workbench/Views/MainMenuBarView.xaml index 5c6d43d..2789a97 100644 --- a/Workbench/Views/MainMenuBarView.xaml +++ b/Workbench/Views/MainMenuBarView.xaml @@ -10,25 +10,28 @@ - + + - - + + + + + - + + - -