129 lines
4.5 KiB
C#
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
|
|
};
|
|
}
|
|
}
|