修复流程图编辑器界面及初步的功能
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
using Moq;
|
using Moq;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
using XP.Common.Logging.Interfaces;
|
using XP.Common.Logging.Interfaces;
|
||||||
using XplorePlane.Models;
|
using XplorePlane.Models;
|
||||||
using XplorePlane.Services;
|
using XplorePlane.Services;
|
||||||
@@ -104,6 +107,36 @@ namespace XplorePlane.Tests.Pipeline
|
|||||||
Assert.Equal(i, vm.PipelineNodes[i].Order);
|
Assert.Equal(i, vm.PipelineNodes[i].Order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LoadImageFromFile_SetsSourceImage()
|
||||||
|
{
|
||||||
|
var vm = CreateVm();
|
||||||
|
var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".png");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var bitmap = TestHelpers.CreateTestBitmap(8, 8);
|
||||||
|
var encoder = new PngBitmapEncoder();
|
||||||
|
encoder.Frames.Add(BitmapFrame.Create(bitmap));
|
||||||
|
|
||||||
|
using (var stream = File.Create(tempPath))
|
||||||
|
{
|
||||||
|
encoder.Save(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.LoadImageFromFile(tempPath);
|
||||||
|
|
||||||
|
Assert.NotNull(vm.SourceImage);
|
||||||
|
Assert.NotNull(vm.PreviewImage);
|
||||||
|
Assert.Contains(Path.GetFileName(tempPath), vm.StatusMessage);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (File.Exists(tempPath))
|
||||||
|
File.Delete(tempPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── 6.2 RemoveOperatorCommand ─────────────────────────────────
|
// ── 6.2 RemoveOperatorCommand ─────────────────────────────────
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using Moq;
|
||||||
|
using XP.Common.Logging.Interfaces;
|
||||||
|
using XplorePlane.Services;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace XplorePlane.Tests.Services
|
||||||
|
{
|
||||||
|
public class ImageProcessingServiceTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void DiscoverProcessors_LoadsKnownProcessors()
|
||||||
|
{
|
||||||
|
var logger = new Mock<ILoggerService>();
|
||||||
|
logger.Setup(l => l.ForModule<ImageProcessingService>()).Returns(logger.Object);
|
||||||
|
|
||||||
|
using var service = new ImageProcessingService(logger.Object);
|
||||||
|
|
||||||
|
var processors = service.GetAvailableProcessors();
|
||||||
|
|
||||||
|
Assert.Contains("GaussianBlur", processors);
|
||||||
|
Assert.Contains("ShockFilter", processors);
|
||||||
|
Assert.Contains("BandPassFilter", processors);
|
||||||
|
Assert.Contains("Division", processors);
|
||||||
|
Assert.Contains("Contour", processors);
|
||||||
|
Assert.True(processors.Count >= 20, $"Expected many discovered processors, got {processors.Count}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -268,7 +268,6 @@ namespace XplorePlane
|
|||||||
|
|
||||||
// 注册视图和视图模型
|
// 注册视图和视图模型
|
||||||
containerRegistry.RegisterForNavigation<MainWindow>();
|
containerRegistry.RegisterForNavigation<MainWindow>();
|
||||||
containerRegistry.RegisterForNavigation<MainWindowB>();
|
|
||||||
containerRegistry.Register<MainViewModel>();
|
containerRegistry.Register<MainViewModel>();
|
||||||
containerRegistry.RegisterSingleton<NavigationPropertyPanelViewModel>();
|
containerRegistry.RegisterSingleton<NavigationPropertyPanelViewModel>();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("XplorePlane.Tests")]
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace XplorePlane.Services
|
||||||
|
{
|
||||||
|
internal static class ProcessorUiMetadata
|
||||||
|
{
|
||||||
|
private static readonly (string Category, string CategoryIcon, int Order)[] CategoryDefinitions =
|
||||||
|
{
|
||||||
|
("滤波与平滑", "🌀", 0),
|
||||||
|
("图像增强", "✨", 1),
|
||||||
|
("图像变换", "🔁", 2),
|
||||||
|
("数学运算", "➗", 3),
|
||||||
|
("形态学处理", "⬚", 4),
|
||||||
|
("边缘检测", "📐", 5),
|
||||||
|
("检测分析", "🔎", 6),
|
||||||
|
("其他", "⚙", 99),
|
||||||
|
};
|
||||||
|
|
||||||
|
internal static (string Category, string CategoryIcon, string OperatorIcon) Get(string operatorKey)
|
||||||
|
{
|
||||||
|
var category = GetCategory(operatorKey);
|
||||||
|
return (category, GetCategoryIcon(category), GetOperatorIcon(operatorKey, category));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetCategory(string operatorKey)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(operatorKey))
|
||||||
|
return "其他";
|
||||||
|
|
||||||
|
if (ContainsAny(operatorKey, "Blur", "Filter", "Shock"))
|
||||||
|
return "滤波与平滑";
|
||||||
|
|
||||||
|
if (ContainsAny(operatorKey, "Contrast", "Gamma", "Retinex", "Histogram", "Sharpen", "Layer",
|
||||||
|
"SubPixel", "SuperResolution", "HDR", "Effect", "PseudoColor", "Color"))
|
||||||
|
return "图像增强";
|
||||||
|
|
||||||
|
if (ContainsAny(operatorKey, "Mirror", "Rotate", "Grayscale", "Threshold"))
|
||||||
|
return "图像变换";
|
||||||
|
|
||||||
|
if (ContainsAny(operatorKey, "Division", "Multiplication", "Difference", "Integral", "Or"))
|
||||||
|
return "数学运算";
|
||||||
|
|
||||||
|
if (ContainsAny(operatorKey, "Morphology"))
|
||||||
|
return "形态学处理";
|
||||||
|
|
||||||
|
if (ContainsAny(operatorKey, "Edge"))
|
||||||
|
return "边缘检测";
|
||||||
|
|
||||||
|
if (ContainsAny(operatorKey, "Measurement", "Detection", "Contour", "FillRate", "Void", "Line", "PointToLine", "Ellipse", "Bga"))
|
||||||
|
return "检测分析";
|
||||||
|
|
||||||
|
return "其他";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int GetCategoryOrder(string category)
|
||||||
|
{
|
||||||
|
foreach (var definition in CategoryDefinitions)
|
||||||
|
{
|
||||||
|
if (string.Equals(definition.Category, category, StringComparison.Ordinal))
|
||||||
|
return definition.Order;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetCategoryIcon(string category)
|
||||||
|
{
|
||||||
|
foreach (var definition in CategoryDefinitions)
|
||||||
|
{
|
||||||
|
if (string.Equals(definition.Category, category, StringComparison.Ordinal))
|
||||||
|
return definition.CategoryIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "⚙";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetOperatorIcon(string operatorKey) => GetOperatorIcon(operatorKey, GetCategory(operatorKey));
|
||||||
|
|
||||||
|
private static string GetOperatorIcon(string operatorKey, string category)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(operatorKey))
|
||||||
|
return GetCategoryIcon(category);
|
||||||
|
|
||||||
|
if (ContainsAny(operatorKey, "Shock"))
|
||||||
|
return "⚡";
|
||||||
|
if (ContainsAny(operatorKey, "BandPass"))
|
||||||
|
return "📶";
|
||||||
|
if (ContainsAny(operatorKey, "GaussianBlur", "MeanFilter", "MedianFilter", "BilateralFilter", "LowPassFilter", "HighPassFilter"))
|
||||||
|
return "🌀";
|
||||||
|
if (ContainsAny(operatorKey, "Contrast"))
|
||||||
|
return "🌗";
|
||||||
|
if (ContainsAny(operatorKey, "Gamma"))
|
||||||
|
return "γ";
|
||||||
|
if (ContainsAny(operatorKey, "Retinex"))
|
||||||
|
return "🎛";
|
||||||
|
if (ContainsAny(operatorKey, "Histogram"))
|
||||||
|
return "📊";
|
||||||
|
if (ContainsAny(operatorKey, "Sharpen"))
|
||||||
|
return "✦";
|
||||||
|
if (ContainsAny(operatorKey, "SubPixel", "SuperResolution"))
|
||||||
|
return "🔬";
|
||||||
|
if (ContainsAny(operatorKey, "HDR"))
|
||||||
|
return "💡";
|
||||||
|
if (ContainsAny(operatorKey, "PseudoColor"))
|
||||||
|
return "🎨";
|
||||||
|
if (ContainsAny(operatorKey, "FilmEffect"))
|
||||||
|
return "🎞";
|
||||||
|
if (ContainsAny(operatorKey, "ColorLayer"))
|
||||||
|
return "🧪";
|
||||||
|
if (ContainsAny(operatorKey, "Mirror"))
|
||||||
|
return "↔";
|
||||||
|
if (ContainsAny(operatorKey, "Rotate"))
|
||||||
|
return "⟳";
|
||||||
|
if (ContainsAny(operatorKey, "Grayscale"))
|
||||||
|
return "◻";
|
||||||
|
if (ContainsAny(operatorKey, "Threshold"))
|
||||||
|
return "▣";
|
||||||
|
if (ContainsAny(operatorKey, "Division"))
|
||||||
|
return "➗";
|
||||||
|
if (ContainsAny(operatorKey, "Multiplication"))
|
||||||
|
return "✕";
|
||||||
|
if (ContainsAny(operatorKey, "Difference"))
|
||||||
|
return "Δ";
|
||||||
|
if (ContainsAny(operatorKey, "Integral"))
|
||||||
|
return "∫";
|
||||||
|
if (ContainsAny(operatorKey, "Or"))
|
||||||
|
return "∨";
|
||||||
|
if (ContainsAny(operatorKey, "Morphology"))
|
||||||
|
return "⬚";
|
||||||
|
if (ContainsAny(operatorKey, "Sobel", "Kirsch", "HorizontalEdge"))
|
||||||
|
return "📐";
|
||||||
|
if (ContainsAny(operatorKey, "Contour"))
|
||||||
|
return "✏";
|
||||||
|
if (ContainsAny(operatorKey, "Measurement"))
|
||||||
|
return "📏";
|
||||||
|
if (ContainsAny(operatorKey, "FillRate"))
|
||||||
|
return "🧮";
|
||||||
|
if (ContainsAny(operatorKey, "Void"))
|
||||||
|
return "⚪";
|
||||||
|
if (ContainsAny(operatorKey, "Ellipse"))
|
||||||
|
return "⭕";
|
||||||
|
if (ContainsAny(operatorKey, "PointToLine"))
|
||||||
|
return "📍";
|
||||||
|
if (ContainsAny(operatorKey, "Edge"))
|
||||||
|
return "📐";
|
||||||
|
|
||||||
|
return GetCategoryIcon(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ContainsAny(string value, params string[] terms)
|
||||||
|
{
|
||||||
|
foreach (var term in terms)
|
||||||
|
{
|
||||||
|
if (value.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,6 +60,7 @@ namespace XplorePlane.ViewModels
|
|||||||
SaveAsPipelineCommand = new DelegateCommand(async () => await SaveAsPipelineAsync());
|
SaveAsPipelineCommand = new DelegateCommand(async () => await SaveAsPipelineAsync());
|
||||||
DeletePipelineCommand = new DelegateCommand(async () => await DeletePipelineAsync());
|
DeletePipelineCommand = new DelegateCommand(async () => await DeletePipelineAsync());
|
||||||
LoadPipelineCommand = new DelegateCommand(async () => await LoadPipelineAsync());
|
LoadPipelineCommand = new DelegateCommand(async () => await LoadPipelineAsync());
|
||||||
|
LoadImageCommand = new DelegateCommand(LoadImage);
|
||||||
OpenToolboxCommand = new DelegateCommand(OpenToolbox);
|
OpenToolboxCommand = new DelegateCommand(OpenToolbox);
|
||||||
MoveNodeUpCommand = new DelegateCommand<PipelineNodeViewModel>(MoveNodeUp);
|
MoveNodeUpCommand = new DelegateCommand<PipelineNodeViewModel>(MoveNodeUp);
|
||||||
MoveNodeDownCommand = new DelegateCommand<PipelineNodeViewModel>(MoveNodeDown);
|
MoveNodeDownCommand = new DelegateCommand<PipelineNodeViewModel>(MoveNodeDown);
|
||||||
@@ -88,6 +89,7 @@ namespace XplorePlane.ViewModels
|
|||||||
if (SetProperty(ref _sourceImage, value))
|
if (SetProperty(ref _sourceImage, value))
|
||||||
{
|
{
|
||||||
ExecutePipelineCommand.RaiseCanExecuteChanged();
|
ExecutePipelineCommand.RaiseCanExecuteChanged();
|
||||||
|
RaisePropertyChanged(nameof(DisplayImage));
|
||||||
TriggerDebouncedExecution();
|
TriggerDebouncedExecution();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,8 +98,14 @@ namespace XplorePlane.ViewModels
|
|||||||
public BitmapSource PreviewImage
|
public BitmapSource PreviewImage
|
||||||
{
|
{
|
||||||
get => _previewImage;
|
get => _previewImage;
|
||||||
set => SetProperty(ref _previewImage, value);
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _previewImage, value))
|
||||||
|
RaisePropertyChanged(nameof(DisplayImage));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitmapSource DisplayImage => PreviewImage ?? SourceImage;
|
||||||
|
|
||||||
public string PipelineName
|
public string PipelineName
|
||||||
{
|
{
|
||||||
@@ -142,6 +150,7 @@ namespace XplorePlane.ViewModels
|
|||||||
public DelegateCommand SaveAsPipelineCommand { get; }
|
public DelegateCommand SaveAsPipelineCommand { get; }
|
||||||
public DelegateCommand DeletePipelineCommand { get; }
|
public DelegateCommand DeletePipelineCommand { get; }
|
||||||
public DelegateCommand LoadPipelineCommand { get; }
|
public DelegateCommand LoadPipelineCommand { get; }
|
||||||
|
public DelegateCommand LoadImageCommand { get; }
|
||||||
|
|
||||||
public DelegateCommand OpenToolboxCommand { get; }
|
public DelegateCommand OpenToolboxCommand { get; }
|
||||||
|
|
||||||
@@ -316,6 +325,45 @@ namespace XplorePlane.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LoadImage()
|
||||||
|
{
|
||||||
|
var dialog = new OpenFileDialog
|
||||||
|
{
|
||||||
|
Title = "加载图像",
|
||||||
|
Filter = "图像文件|*.bmp;*.png;*.jpg;*.jpeg;*.tif;*.tiff|所有文件|*.*"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dialog.ShowDialog() != true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LoadImageFromFile(dialog.FileName);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
StatusMessage = $"加载图像失败:{ex.Message}";
|
||||||
|
_logger.Error(ex, "加载图像失败:{Path}", dialog.FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void LoadImageFromFile(string filePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(filePath))
|
||||||
|
throw new ArgumentException("图像路径不能为空", nameof(filePath));
|
||||||
|
|
||||||
|
var bitmap = new BitmapImage();
|
||||||
|
bitmap.BeginInit();
|
||||||
|
bitmap.UriSource = new Uri(filePath, UriKind.Absolute);
|
||||||
|
bitmap.CacheOption = BitmapCacheOption.OnLoad;
|
||||||
|
bitmap.EndInit();
|
||||||
|
bitmap.Freeze();
|
||||||
|
|
||||||
|
SourceImage = bitmap;
|
||||||
|
PreviewImage = bitmap;
|
||||||
|
StatusMessage = $"已加载图像:{Path.GetFileName(filePath)}";
|
||||||
|
}
|
||||||
|
|
||||||
private void CancelExecution()
|
private void CancelExecution()
|
||||||
{
|
{
|
||||||
_executionCts?.Cancel();
|
_executionCts?.Cancel();
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
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"
|
||||||
Title="库版本信息"
|
Title="库版本信息"
|
||||||
Width="850"
|
Width="400"
|
||||||
Height="600"
|
Height="600"
|
||||||
ResizeMode="CanResizeWithGrip"
|
ResizeMode="CanResizeWithGrip"
|
||||||
WindowStartupLocation="CenterOwner">
|
WindowStartupLocation="CenterOwner">
|
||||||
@@ -4,11 +4,9 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
|
||||||
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
|
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
|
||||||
d:DesignHeight="700"
|
d:DesignHeight="700"
|
||||||
d:DesignWidth="350"
|
d:DesignWidth="350"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
@@ -48,13 +46,14 @@
|
|||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<!-- Row 0: 工具栏 -->
|
<!-- Row 0: 工具栏 -->
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<!-- Row 1: 流水线节点列表 -->
|
|
||||||
<RowDefinition Height="3*" />
|
<!-- Row 2: 流水线节点列表 -->
|
||||||
<!-- Row 2: 分隔线 -->
|
<RowDefinition Height="2*" MinHeight="180" />
|
||||||
|
<!-- Row 3: 分隔线 -->
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<!-- Row 3: 参数面板 -->
|
<!-- Row 4: 参数面板 -->
|
||||||
<RowDefinition Height="2*" MinHeight="80" />
|
<RowDefinition Height="2*" MinHeight="80" />
|
||||||
<!-- Row 4: 状态栏 -->
|
<!-- Row 5: 状态栏 -->
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
@@ -90,6 +89,12 @@
|
|||||||
Content="加载"
|
Content="加载"
|
||||||
Style="{StaticResource ToolbarBtn}"
|
Style="{StaticResource ToolbarBtn}"
|
||||||
ToolTip="加载流水线" />
|
ToolTip="加载流水线" />
|
||||||
|
<Button
|
||||||
|
Width="64"
|
||||||
|
Command="{Binding LoadImageCommand}"
|
||||||
|
Content="加载图像"
|
||||||
|
Style="{StaticResource ToolbarBtn}"
|
||||||
|
ToolTip="加载输入图像" />
|
||||||
<Button
|
<Button
|
||||||
Command="{Binding ExecutePipelineCommand}"
|
Command="{Binding ExecutePipelineCommand}"
|
||||||
Content="▶"
|
Content="▶"
|
||||||
@@ -109,6 +114,9 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 流水线节点列表(拖拽目标) -->
|
<!-- 流水线节点列表(拖拽目标) -->
|
||||||
<ListBox
|
<ListBox
|
||||||
x:Name="PipelineListBox"
|
x:Name="PipelineListBox"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using Prism.Ioc;
|
using Prism.Ioc;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
@@ -22,6 +23,18 @@ namespace XplorePlane.Views
|
|||||||
|
|
||||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (DataContext == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DataContext = ContainerLocator.Current?.Resolve<PipelineEditorViewModel>();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger?.Error(ex, "PipelineEditorViewModel 解析失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_logger?.Info("PipelineEditorView DataContext 类型={Type}",
|
_logger?.Info("PipelineEditorView DataContext 类型={Type}",
|
||||||
DataContext?.GetType().Name);
|
DataContext?.GetType().Name);
|
||||||
|
|
||||||
@@ -50,7 +63,7 @@ namespace XplorePlane.Views
|
|||||||
|
|
||||||
if (!e.Data.GetDataPresent(OperatorToolboxView.DragFormat))
|
if (!e.Data.GetDataPresent(OperatorToolboxView.DragFormat))
|
||||||
{
|
{
|
||||||
_logger?.Warn("Drop 事件触发但数据中无 {Format}", OperatorToolboxView.DragFormat);
|
_logger?.Warn("Drop 事件触发但数据中没有 {Format}", OperatorToolboxView.DragFormat);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,46 @@
|
|||||||
<Window x:Class="XplorePlane.Views.PipelineEditorWindow"
|
<Window x:Class="XplorePlane.Views.PipelineEditorWindow"
|
||||||
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:roi="clr-namespace:XP.ImageProcessing.RoiControl.Controls;assembly=XP.ImageProcessing.RoiControl"
|
||||||
xmlns:views="clr-namespace:XplorePlane.Views"
|
xmlns:views="clr-namespace:XplorePlane.Views"
|
||||||
Title="流水线编辑器"
|
Title="流水线编辑器"
|
||||||
Width="700" Height="750"
|
Width="1200"
|
||||||
|
Height="750"
|
||||||
WindowStartupLocation="CenterOwner"
|
WindowStartupLocation="CenterOwner"
|
||||||
ShowInTaskbar="False">
|
ShowInTaskbar="False">
|
||||||
<Grid>
|
<Grid Background="#F3F3F3">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="200" />
|
<ColumnDefinition Width="240" MinWidth="200" />
|
||||||
<ColumnDefinition Width="5" />
|
<ColumnDefinition Width="*" MinWidth="400" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="250" MinWidth="250" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<views:OperatorToolboxView Grid.Column="0" />
|
|
||||||
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" Background="#E0E0E0" />
|
<Border Grid.Column="0"
|
||||||
<views:PipelineEditorView Grid.Column="2" />
|
Margin="8"
|
||||||
|
Background="White"
|
||||||
|
BorderBrush="#D0D0D0"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="4">
|
||||||
|
<views:OperatorToolboxView />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Grid.Column="1"
|
||||||
|
Margin="8,8,4,8"
|
||||||
|
Background="White"
|
||||||
|
BorderBrush="#D0D0D0"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="4">
|
||||||
|
<roi:PolygonRoiCanvas ImageSource="{Binding DisplayImage}"
|
||||||
|
Background="White" />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Grid.Column="2"
|
||||||
|
Margin="4,8,8,8"
|
||||||
|
Background="White"
|
||||||
|
BorderBrush="#D0D0D0"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="4">
|
||||||
|
<views:PipelineEditorView />
|
||||||
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
|
using Prism.Ioc;
|
||||||
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using XplorePlane.ViewModels;
|
||||||
|
|
||||||
namespace XplorePlane.Views
|
namespace XplorePlane.Views
|
||||||
{
|
{
|
||||||
@@ -7,6 +10,15 @@ namespace XplorePlane.Views
|
|||||||
public PipelineEditorWindow()
|
public PipelineEditorWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DataContext = ContainerLocator.Current?.Resolve<PipelineEditorViewModel>();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:roi="clr-namespace:XP.ImageProcessing.RoiControl.Controls;assembly=XP.ImageProcessing.RoiControl"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
d:DesignHeight="400"
|
d:DesignHeight="400"
|
||||||
d:DesignWidth="600"
|
d:DesignWidth="600"
|
||||||
@@ -22,14 +23,10 @@
|
|||||||
FontWeight="SemiBold" Foreground="#333333" Text="实时图像" />
|
FontWeight="SemiBold" Foreground="#333333" Text="实时图像" />
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 图像显示区域,支持滚动 -->
|
<!-- 图像显示区域,支持滚动、缩放和ROI -->
|
||||||
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
<roi:PolygonRoiCanvas Grid.Row="1"
|
||||||
<Image Source="{Binding ImageSource}"
|
ImageSource="{Binding ImageSource}"
|
||||||
Stretch="None"
|
Background="White" />
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
RenderOptions.BitmapScalingMode="NearestNeighbor" />
|
|
||||||
</ScrollViewer>
|
|
||||||
|
|
||||||
<!-- 图像信息栏 -->
|
<!-- 图像信息栏 -->
|
||||||
<Border Grid.Row="2" Background="#F0F0F0" BorderBrush="#DDDDDD" BorderThickness="0,1,0,0">
|
<Border Grid.Row="2" Background="#F0F0F0" BorderBrush="#DDDDDD" BorderThickness="0,1,0,0">
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Remove="MainWindow.xaml" />
|
<Page Remove="MainWindow.xaml" />
|
||||||
|
<Page Remove="Views\Main\MainWindowB.xaml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- NuGet 包引用 -->
|
<!-- NuGet 包引用 -->
|
||||||
@@ -144,6 +145,7 @@
|
|||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<Link>Libs\Hardware\zh-TW\%(Filename)%(Extension)</Link>
|
<Link>Libs\Hardware\zh-TW\%(Filename)%(Extension)</Link>
|
||||||
</None>
|
</None>
|
||||||
|
<Compile Remove="Views\Main\MainWindowB.xaml.cs" />
|
||||||
|
|
||||||
<Resource Include="XplorerPlane.ico" />
|
<Resource Include="XplorerPlane.ico" />
|
||||||
|
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ CNC及矩阵功能的设计与评审,包含以下功能: √
|
|||||||
2026.4.20
|
2026.4.20
|
||||||
----------------------
|
----------------------
|
||||||
1、图像算子工具箱的图标 √
|
1、图像算子工具箱的图标 √
|
||||||
2、最新的图像算子集成到图像工具箱
|
2、最新的图像算子集成到图像工具箱 √
|
||||||
3、修复流程图编辑器
|
3、修复流程图编辑器界面及初步的功能 √
|
||||||
4、主页面加载图像的功能
|
4、主页面加载图像的功能
|
||||||
5、
|
5、
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user