Files
XplorePlane/XplorePlane/ViewModels/Main/MainViewModel.Cnc.cs
T
2026-08-10 14:13:32 +08:00

188 lines
6.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ── 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
}
}