188 lines
6.9 KiB
C#
188 lines
6.9 KiB
C#
// ── MainViewModel CNC 相关功能 ──
|
||
// 程序编排/矩阵检测/检测结果/检测报告等 CNC 子功能的入口命令与窗口管理。
|
||
using System;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
using XplorePlane.ViewModels.Cnc;
|
||
using XplorePlane.Views.Dialogs;
|
||
|
||
namespace XplorePlane.ViewModels.Main
|
||
{
|
||
/// <summary>
|
||
/// CNC 编排面板控制 — 打开/关闭/切换模式及内置检测模块插入。
|
||
/// 从 MainViewModel 拆分,保持 XAML 绑定不变。
|
||
/// </summary>
|
||
public partial class MainViewModel
|
||
{
|
||
#region CNC 编辑器生命周期
|
||
|
||
private void ExecuteOpenCncEditor()
|
||
{
|
||
IsCncEditorMode = true;
|
||
ImagePanelWidth = new GridLength(540);
|
||
_cncEditorViewModel.NewProgramCommand.Execute();
|
||
}
|
||
|
||
private async Task ExecuteOpenCncEditorAsync()
|
||
{
|
||
IsCncEditorMode = true;
|
||
ImagePanelWidth = new GridLength(540);
|
||
_cncEditorViewModel.NewProgramCommand.Execute();
|
||
}
|
||
|
||
/// <summary>关闭 CNC 编排面板,提示保存后恢复实时流水线。</summary>
|
||
private void ExecuteCloseCncEditor()
|
||
{
|
||
var stillDirty = _cncEditorViewModel.IsModified;
|
||
if (stillDirty)
|
||
{
|
||
if (_dialogs != null && _dialogs.Confirm("Cnc_ConfirmSaveBeforeClose", "Dialog_Confirm"))
|
||
{
|
||
_cncEditorViewModel.SaveProgramCommand.Execute();
|
||
stillDirty = _cncEditorViewModel.IsModified;
|
||
}
|
||
}
|
||
_cncEditorViewModel.WriteEditSession(isDirty: stillDirty);
|
||
IsCncEditorMode = false;
|
||
ImagePanelWidth = new GridLength(320);
|
||
}
|
||
|
||
#endregion CNC 编辑器生命周期
|
||
|
||
#region CNC 编辑动作分发(单例嵌入式面板)
|
||
|
||
private void ExecuteCncEditorAction(Action<CncEditorViewModel> action)
|
||
{
|
||
ArgumentNullException.ThrowIfNull(action);
|
||
try
|
||
{
|
||
if (!IsCncEditorMode)
|
||
{
|
||
IsCncEditorMode = true;
|
||
ImagePanelWidth = new GridLength(540);
|
||
_cncEditorViewModel.NewProgramCommand.Execute();
|
||
}
|
||
action(_cncEditorViewModel);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.Error(ex, "执行 CNC 编辑器动作失败。");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 对 CNC 单例执行动作但不主动弹出编排窗体。
|
||
/// 用于停止/暂停/单步/继续等运行控制命令。
|
||
/// </summary>
|
||
private void ExecuteCncEditorActionNoWindow(Action<CncEditorViewModel> action)
|
||
{
|
||
ArgumentNullException.ThrowIfNull(action);
|
||
action(_cncEditorViewModel);
|
||
}
|
||
|
||
#endregion CNC 编辑动作分发(单例嵌入式面板)
|
||
|
||
#region 内置检测模块插入
|
||
|
||
private bool CanExecuteInsertBuiltInInspectionModule()
|
||
{
|
||
return SelectedBuiltInInspectionModule != null;
|
||
}
|
||
|
||
private async Task ExecuteInsertBuiltInInspectionModuleAsync()
|
||
{
|
||
var module = SelectedBuiltInInspectionModule;
|
||
if (module == null)
|
||
return;
|
||
|
||
try
|
||
{
|
||
if (!IsCncEditorMode)
|
||
{
|
||
IsCncEditorMode = true;
|
||
ImagePanelWidth = new GridLength(540);
|
||
_cncEditorViewModel.NewProgramCommand.Execute();
|
||
}
|
||
await _cncEditorViewModel.InsertInspectionModuleFromPipelineFileAsync(module.FilePath);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.Error(ex, "Failed to insert built-in inspection module: {FilePath}", module.FilePath);
|
||
_dialogs.Show("Main_InsertModuleFailed", "Dialog_Error", ApplicationMessageKind.Error, ex.Message);
|
||
}
|
||
}
|
||
|
||
/// <summary>响应"把实时流水线作为检测模块加入 CNC"请求。</summary>
|
||
private async void OnAddPipelineToCncRequested(XplorePlane.Models.ImageProcessing.PipelineModel pipeline)
|
||
=> await OnAddPipelineToCncRequestedAsync(pipeline);
|
||
|
||
private async Task OnAddPipelineToCncRequestedAsync(XplorePlane.Models.ImageProcessing.PipelineModel pipeline)
|
||
{
|
||
try
|
||
{
|
||
if (pipeline?.Nodes == null || pipeline.Nodes.Count == 0)
|
||
{
|
||
_dialogs.Show("Main_EmptyLivePipeline", "Dialog_Info", ApplicationMessageKind.Information);
|
||
return;
|
||
}
|
||
if (!IsCncEditorMode)
|
||
{
|
||
IsCncEditorMode = true;
|
||
ImagePanelWidth = new GridLength(540);
|
||
_cncEditorViewModel.NewProgramCommand.Execute();
|
||
}
|
||
_cncEditorViewModel.InsertInspectionModuleFromPipeline(pipeline);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.Error(ex, "Failed to add current pipeline to CNC");
|
||
_dialogs.Show("Main_AddModuleFailed", "Dialog_Error", ApplicationMessageKind.Error, ex.Message);
|
||
}
|
||
}
|
||
|
||
private void LoadBuiltInInspectionModules()
|
||
{
|
||
BuiltInInspectionModules.Clear();
|
||
try
|
||
{
|
||
var toolsPath = _xpDataPathService.ToolsPath;
|
||
if (!Directory.Exists(toolsPath))
|
||
{
|
||
SelectedBuiltInInspectionModule = null;
|
||
return;
|
||
}
|
||
|
||
var files = Directory
|
||
.EnumerateFiles(toolsPath, "*.xppipe", SearchOption.AllDirectories)
|
||
.OrderBy(path => path, StringComparer.OrdinalIgnoreCase)
|
||
.Select(path => new BuiltInInspectionModuleItem(
|
||
GetBuiltInModuleDisplayName(toolsPath, path),
|
||
path))
|
||
.ToList();
|
||
|
||
foreach (var file in files)
|
||
BuiltInInspectionModules.Add(file);
|
||
|
||
SelectedBuiltInInspectionModule = BuiltInInspectionModules.FirstOrDefault();
|
||
_logger.Info("Loaded {Count} built-in inspection modules from {ToolsPath}", BuiltInInspectionModules.Count, toolsPath);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
SelectedBuiltInInspectionModule = null;
|
||
_logger.Error(ex, "Failed to load built-in inspection modules.");
|
||
}
|
||
}
|
||
|
||
private static string GetBuiltInModuleDisplayName(string toolsPath, string filePath)
|
||
{
|
||
var relativePath = Path.GetRelativePath(toolsPath, filePath);
|
||
var withoutExtension = Path.ChangeExtension(relativePath, null) ?? relativePath;
|
||
return withoutExtension.Replace(Path.DirectorySeparatorChar, '/');
|
||
}
|
||
|
||
#endregion 内置检测模块插入
|
||
}
|
||
}
|