using System;
using System.Threading.Tasks;
using System.Windows;
using HalconDotNet;
using TeamAAS.FlowEditor.Models;
using TeamAAS.FlowEditor.Plugins;
using TeamAAS.FlowEngine;
using TeamAAS.Vision;
namespace Plugins.Halcon.Views
{
///
/// HALCON 算子专用高级编辑窗体(普通编辑=属性面板常用参数;高级编辑=本窗体):
/// - 左侧参数面板:同一套模型属性(PropertyGridLib),改完即生效;
/// - 右侧大显示窗:HalconWindow(缩放/平移/ROI 绘制/保存),运行结果经图层总线渲染;
/// - 加载图像:从文件载入测试图并注册为流程「图像」输入变量(算子绑定 &{输入.图像} 时直接生效);
/// - 执行:用当前流程注册表跑一遍该算子(与画布运行同一执行路径),状态栏回报结果与耗时。
/// 窗体非模态(可边看流程边调参)。
///
public partial class HalconToolAdvancedEditor : Window
{
private readonly BasePluginModel _model;
private readonly HalconWindow _display;
private IFlowNodePlugin _plugin;
private bool _running;
/// 打开算子高级编辑窗体(非模态)。
public static void Show(BasePluginModel model)
{
if (model == null) return;
var win = new HalconToolAdvancedEditor(model);
win.Show();
win.Activate();
}
public HalconToolAdvancedEditor(BasePluginModel model)
{
InitializeComponent();
_model = model;
TxtTitle.Text = $"{model.ToolName ?? "Halcon 算子"} · {model.NodeName}";
Title = $"高级编辑 - {model.ToolName ?? model.GetType().Name}";
// 普通参数面板(与属性面板同一套模型,双向实时同步)
PropertyHost.Content = new PropertyGridLib.PropertyGrid { SelectedObject = model };
// 大显示窗
_display = new HalconWindow(1);
_display.SetCaption(model.ToolName ?? "预览");
DisplayHost.Content = _display;
// 图层总线:该算子发布图层 → 渲染(整组:底图+叠加,区域自动附带原图)
VisionLayerStore.Instance.LayerPublished += OnLayerPublished;
Closed += (s, e) => VisionLayerStore.Instance.LayerPublished -= OnLayerPublished;
}
/// 算子插件实例(懒创建;挂当前流程注册表,公式/输入变量按流程上下文解析)。
private IFlowNodePlugin Plugin
{
get
{
if (_plugin == null)
{
_plugin = PluginLoader.Instance.CreateInstance(_model.ToolName);
if (_plugin != null)
{
_plugin.GetModel = _model;
_plugin.Registry = PluginLoader.Instance.SelectFlow?.Registry;
}
}
return _plugin;
}
}
/// 该算子发布图层 → 整组渲染(含区域附带原图回退)。
private void OnLayerPublished(LayerPublishArgs args)
{
if (args == null || _model == null) return;
if (!string.Equals(args.FlowId, _model.FlowId, StringComparison.OrdinalIgnoreCase)) return;
if (!string.Equals(args.NodeName, _model.NodeName, StringComparison.OrdinalIgnoreCase)) return;
try
{
Dispatcher.Invoke(() =>
{
var layers = LayerComboHelper.ResolveLayers(args, null, args.FlowId);
if (layers.Count > 0) _display.ShowLayers(layers);
});
}
catch { }
}
/// 执行:后台线程跑一遍该算子(不卡 UI),完成回报状态与耗时。
private void BtnRun_Click(object sender, RoutedEventArgs e)
{
if (_running) return;
var plugin = Plugin;
if (plugin == null)
{
TxtStatus.Text = "创建插件实例失败(检查插件是否加载)";
return;
}
_running = true;
BtnRun.IsEnabled = false;
TxtStatus.Text = "执行中…";
Task.Run(() =>
{
try
{
var status = plugin.Run(System.Threading.CancellationToken.None);
SetStatus($"执行完成: {status},耗时 {plugin.CostTime}ms");
}
catch (Exception ex)
{
SetStatus("执行失败: " + ex.Message);
}
finally
{
try { Dispatcher.Invoke(() => { _running = false; BtnRun.IsEnabled = true; }); } catch { }
}
});
}
/// 加载测试图像:注册为流程「图像」输入变量并立即预览。
private void BtnLoadImage_Click(object sender, RoutedEventArgs e)
{
var dlg = new Microsoft.Win32.OpenFileDialog
{
Filter = "图像文件|*.png;*.jpg;*.jpeg;*.bmp;*.tif;*.tiff|所有文件|*.*",
Title = "加载测试图像"
};
if (dlg.ShowDialog(this) != true) return;
try
{
HOperatorSet.ReadImage(out HObject img, dlg.FileName);
var registry = PluginLoader.Instance.SelectFlow?.Registry;
if (!string.IsNullOrEmpty(_model.FlowId))
registry?.SetInputVariable(_model.FlowId, "图像", img);
_display.RefreshImage(img);
TxtStatus.Text = registry != null
? "已加载图像并注册为输入变量「图像」"
: "已加载图像(未找到流程注册表,仅预览)";
}
catch (Exception ex)
{
TxtStatus.Text = "加载失败: " + ex.Message;
}
}
private void SetStatus(string message)
{
try { Dispatcher.Invoke(() => TxtStatus.Text = message); } catch { }
}
}
}