Files
XplorePlane/XplorePlane/ViewModels/ImageProcessing/OperatorToolboxViewModel.cs
T
2026-05-06 10:01:27 +08:00

129 lines
4.5 KiB
C#

using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using XplorePlane.Services;
namespace XplorePlane.ViewModels
{
public class OperatorDescriptor
{
public string Key { get; }
public string DisplayName { get; }
public string IconPath { get; }
public string Category { get; }
public string CategoryIcon { get; }
public OperatorDescriptor(string key, string displayName, string iconPath = "", string category = "通用", string categoryIcon = "⚙")
{
Key = key;
DisplayName = displayName;
IconPath = iconPath;
Category = category;
CategoryIcon = categoryIcon;
}
}
public class OperatorGroupViewModel
{
public string CategoryName { get; set; }
public string CategoryIcon { get; set; }
public ObservableCollection<OperatorDescriptor> Operators { get; set; } = new();
}
public class OperatorToolboxViewModel : BindableBase
{
private readonly IImageProcessingService _imageProcessingService;
private string _searchText = string.Empty;
private OperatorGroupViewModel _selectedGroup;
// UI 元数据(分类 + 图标)由 ProcessorUiMetadata 统一提供,保持工具箱与流水线图标一致
public OperatorToolboxViewModel(IImageProcessingService imageProcessingService)
{
_imageProcessingService = imageProcessingService ?? throw new ArgumentNullException(nameof(imageProcessingService));
AvailableOperators = new ObservableCollection<OperatorDescriptor>();
FilteredOperators = new ObservableCollection<OperatorDescriptor>();
FilteredGroups = new ObservableCollection<OperatorGroupViewModel>();
LoadOperators();
}
public ObservableCollection<OperatorDescriptor> AvailableOperators { get; }
public ObservableCollection<OperatorDescriptor> FilteredOperators { get; }
public ObservableCollection<OperatorGroupViewModel> FilteredGroups { get; }
public OperatorGroupViewModel SelectedGroup
{
get => _selectedGroup;
set => SetProperty(ref _selectedGroup, value);
}
public string SearchText
{
get => _searchText;
set
{
if (SetProperty(ref _searchText, value))
ApplyFilter();
}
}
private void LoadOperators()
{
AvailableOperators.Clear();
foreach (var key in _imageProcessingService.GetAvailableProcessors())
{
var displayName = _imageProcessingService.GetProcessorDisplayName(key);
var (category, categoryIcon, operatorIcon) = ProcessorUiMetadata.Get(key);
AvailableOperators.Add(new OperatorDescriptor(key, displayName ?? key, operatorIcon, category, categoryIcon));
}
ApplyFilter();
}
private void ApplyFilter()
{
FilteredOperators.Clear();
FilteredGroups.Clear();
SelectedGroup = null;
var filtered = string.IsNullOrWhiteSpace(SearchText)
? AvailableOperators
: AvailableOperators.Where(o =>
o.DisplayName.Contains(SearchText, StringComparison.OrdinalIgnoreCase) ||
o.Category.Contains(SearchText, StringComparison.OrdinalIgnoreCase));
foreach (var op in filtered)
FilteredOperators.Add(op);
var groups = filtered
.GroupBy(o => o.Category)
.OrderBy(g => GetCategoryOrder(g.Key));
foreach (var group in groups)
{
FilteredGroups.Add(new OperatorGroupViewModel
{
CategoryName = group.Key,
CategoryIcon = group.First().CategoryIcon,
Operators = new ObservableCollection<OperatorDescriptor>(group)
});
}
SelectedGroup = FilteredGroups.FirstOrDefault();
}
private static int GetCategoryOrder(string category) => category switch
{
"滤波与平滑" => 0,
"图像增强" => 1,
"图像变换" => 2,
"数学运算" => 3,
"形态学处理" => 4,
"边缘检测" => 5,
"检测分析" => 6,
_ => 99
};
}
}