Browse Source

Use NodeViewModels for the node picker

CPKreuz 1 year ago
parent
commit
2ce8722a11
33 changed files with 101 additions and 208 deletions
  1. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/Animable/TimeNodeViewModel.cs
  2. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/CombineChannelsNodeViewModel.cs
  3. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/CombineColorNodeViewModel.cs
  4. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/CombineVecDNodeViewModel.cs
  5. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/CombineVecINodeViewModel.cs
  6. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/SeparateChannelsNodeViewModel.cs
  7. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/SeparateColorNodeViewModel.cs
  8. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/SeparateVecDNodeViewModel.cs
  9. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/SeparateVecINodeViewModel.cs
  10. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/CreateImageNodeViewModel.cs
  11. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/DebugBlendModeNodeViewModel.cs
  12. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/EllipseNodeViewModel.cs
  13. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/FilterNodes/ApplyFilterNodeViewModel.cs
  14. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/FilterNodes/ColorMatrixFilterNodeViewModel.cs
  15. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/FilterNodes/GrayscaleNodeViewModel.cs
  16. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/FilterNodes/KernelFilterNodeViewModel.cs
  17. 3 7
      src/PixiEditor/ViewModels/Document/Nodes/FolderNodeViewModel.cs
  18. 3 8
      src/PixiEditor/ViewModels/Document/Nodes/ImageLayerNodeViewModel.cs
  19. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/LerpColorNodeViewModel.cs
  20. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/MathNodeViewModel.cs
  21. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/MergeNodeViewModel.cs
  22. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/ModifyImageLeftNodeViewModel.cs
  23. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/ModifyImageRightNodeViewModel.cs
  24. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/NoiseNodeViewModel.cs
  25. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/OutputNodeViewModel.cs
  26. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/Points/DistributePointsNodeViewModel.cs
  27. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/Points/RasterizePointsNodeViewModel.cs
  28. 2 7
      src/PixiEditor/ViewModels/Document/Nodes/Points/RemoveClosePointsNodeViewModel.cs
  29. 2 6
      src/PixiEditor/ViewModels/Document/Nodes/SampleImageNodeViewModel.cs
  30. 27 8
      src/PixiEditor/ViewModels/Nodes/NodeTypeInfo.cs
  31. 3 4
      src/PixiEditor/ViewModels/Nodes/NodeViewModel.cs
  32. 10 0
      src/PixiEditor/ViewModels/Nodes/NodeViewModelAttribute.cs
  33. 1 1
      src/PixiEditor/Views/Nodes/NodeGraphView.cs

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/Animable/TimeNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Animable;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.Animable;
 
-internal class TimeNodeViewModel : NodeViewModel<TimeNode>
-{
-    public override LocalizedString DisplayName => "TIME_NODE";
-    
-    public override LocalizedString Category => "ANIMATION";
-}
+[NodeViewModel("TIME_NODE", "ANIMATION")]
+internal class TimeNodeViewModel : NodeViewModel<TimeNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/CombineChannelsNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.CombineSeparate;
 
-internal class CombineChannelsNodeViewModel : NodeViewModel<CombineChannelsNode>
-{
-    public override LocalizedString DisplayName => "COMBINE_CHANNELS_NODE";
-    
-    public override LocalizedString Category => "IMAGE";
-}
+[NodeViewModel("COMBINE_CHANNELS_NODE", "IMAGE")]
+internal class CombineChannelsNodeViewModel : NodeViewModel<CombineChannelsNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/CombineColorNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.CombineSeparate;
 
-internal class CombineColorNodeViewModel : NodeViewModel<CombineColorNode>
-{
-    public override LocalizedString DisplayName => "COMBINE_COLOR_NODE";
-    
-    public override LocalizedString Category => "COLOR";
-}
+[NodeViewModel("COMBINE_COLOR_NODE", "COLOR")]
+internal class CombineColorNodeViewModel : NodeViewModel<CombineColorNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/CombineVecDNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.CombineSeparate;
 
-internal class CombineVecDNodeViewModel : NodeViewModel<CombineVecDNode>
-{
-    public override LocalizedString DisplayName => "COMBINE_VECD_NODE";
-    
-    public override LocalizedString Category => "NUMBERS";
-}
+[NodeViewModel("COMBINE_VECD_NODE", "NUMBERS")]
+internal class CombineVecDNodeViewModel : NodeViewModel<CombineVecDNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/CombineVecINodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.CombineSeparate;
 
-internal class CombineVecINodeViewModel : NodeViewModel<CombineVecINode>
-{
-    public override LocalizedString DisplayName => "COMBINE_VECI_NODE";
-    
-    public override LocalizedString Category => "NUMBERS";
-}
+[NodeViewModel("COMBINE_VECI_NODE", "NUMBERS")]
+internal class CombineVecINodeViewModel : NodeViewModel<CombineVecINode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/SeparateChannelsNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.CombineSeparate;
 
-internal class SeparateChannelsNodeViewModel : NodeViewModel<SeparateChannelsNode>
-{
-    public override LocalizedString DisplayName => "SEPARATE_CHANNELS_NODE";
-    
-    public override LocalizedString Category => "IMAGE";
-}
+[NodeViewModel("SEPARATE_CHANNELS_NODE", "IMAGE")]
+internal class SeparateChannelsNodeViewModel : NodeViewModel<SeparateChannelsNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/SeparateColorNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.CombineSeparate;
 
-internal class SeparateColorNodeViewModel : NodeViewModel<SeparateColorNode>
-{
-    public override LocalizedString DisplayName => "SEPARATE_COLOR_NODE";
-    
-    public override LocalizedString Category => "COLOR";
-}
+[NodeViewModel("SEPARATE_COLOR_NODE", "COLOR")]
+internal class SeparateColorNodeViewModel : NodeViewModel<SeparateColorNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/SeparateVecDNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.CombineSeparate;
 
-internal class SeparateVecDNodeViewModel : NodeViewModel<SeparateVecDNode>
-{
-    public override LocalizedString DisplayName => "SEPARATE_VECD_NODE";
-    
-    public override LocalizedString Category => "NUMBERS";
-}
+[NodeViewModel("SEPARATE_VECD_NODE", "NUMBERS")]
+internal class SeparateVecDNodeViewModel : NodeViewModel<SeparateVecDNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CombineSeparate/SeparateVecINodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.CombineSeparate;
 
-internal class SeparateVecINodeViewModel : NodeViewModel<SeparateVecINode>
-{
-    public override LocalizedString DisplayName => "SEPARATE_VECI_NODE";
-    
-    public override LocalizedString Category => "NUMBERS";
-}
+[NodeViewModel("SEPARATE_VECI_NODE", "NUMBERS")]
+internal class SeparateVecINodeViewModel : NodeViewModel<SeparateVecINode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/CreateImageNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class CreateImageNodeViewModel : NodeViewModel<CreateImageNode>
-{
-    public override LocalizedString DisplayName => "CREATE_IMAGE_NODE";
-    
-    public override LocalizedString Category => "IMAGE";
-}
+[NodeViewModel("CREATE_IMAGE_NODE", "IMAGE")]
+internal class CreateImageNodeViewModel : NodeViewModel<CreateImageNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/DebugBlendModeNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class DebugBlendModeNodeViewModel : NodeViewModel<DebugBlendModeNode>
-{
-    public override LocalizedString DisplayName { get; } = "Debug Blend Mode";
-
-    public override LocalizedString Category { get; } = "DEBUG";
-}
+[NodeViewModel("Debug Blend Mode", "")]
+internal class DebugBlendModeNodeViewModel : NodeViewModel<DebugBlendModeNode>;

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/EllipseNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class EllipseNodeViewModel : NodeViewModel<EllipseNode>
-{
-    public override LocalizedString DisplayName => "ELLIPSE_NODE";
-    
-    public override LocalizedString Category => "SHAPE";
-}
+[NodeViewModel("ELLIPSE_NODE", "SHAPE")]
+internal class EllipseNodeViewModel : NodeViewModel<EllipseNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/FilterNodes/ApplyFilterNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.FilterNodes;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.FilterNodes;
 
-internal class ApplyFilterNodeViewModel : NodeViewModel<ApplyFilterNode>
-{
-    public override LocalizedString DisplayName => "APPLY_FILTER_NODE";
-    
-    public override LocalizedString Category => "FILTERS";
-}
+[NodeViewModel("APPLY_FILTER_NODE", "FILTERS")]
+internal class ApplyFilterNodeViewModel : NodeViewModel<ApplyFilterNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/FilterNodes/ColorMatrixFilterNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.FilterNodes;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.FilterNodes;
 
-internal class ColorMatrixFilterNodeViewModel : NodeViewModel<ColorMatrixFilterNode>
-{
-    public override LocalizedString DisplayName => "COLOR_MATRIX_TRANSFORM_FILTER_NODE";
-    
-    public override LocalizedString Category => "FILTERS";
-}
+[NodeViewModel("COLOR_MATRIX_TRANSFORM_FILTER_NODE", "FILTERS")]
+internal class ColorMatrixFilterNodeViewModel : NodeViewModel<ColorMatrixFilterNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/FilterNodes/GrayscaleNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.FilterNodes;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.FilterNodes;
 
-internal class GrayscaleNodeViewModel : NodeViewModel<GrayscaleNode>
-{
-    public override LocalizedString DisplayName => "GRAYSCALE_FILTER_NODE";
-    
-    public override LocalizedString Category => "FILTERS";
-}
+[NodeViewModel("GRAYSCALE_FILTER_NODE", "FILTERS")]
+internal class GrayscaleNodeViewModel : NodeViewModel<GrayscaleNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/FilterNodes/KernelFilterNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.FilterNodes;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.FilterNodes;
 
-internal class KernelFilterNodeViewModel : NodeViewModel<KernelFilterNode>
-{
-    public override LocalizedString DisplayName => "KERNEL_FILTER_NODE";
-    
-    public override LocalizedString Category => "FILTERS";
-}
+[NodeViewModel("KERNEL_FILTER_NODE", "FILTERS")]
+internal class KernelFilterNodeViewModel : NodeViewModel<KernelFilterNode>;

+ 3 - 7
src/PixiEditor/ViewModels/Document/Nodes/FolderNodeViewModel.cs

@@ -1,17 +1,13 @@
 using System.Collections.ObjectModel;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.Extensions.Common.Localization;
-using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.Handlers;
+using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
-#nullable enable
+
+[NodeViewModel("FOLDER_NODE", "STRUCTURE")]
 internal class FolderNodeViewModel : StructureMemberViewModel<FolderNode>, IFolderHandler
 {
     public ObservableCollection<IStructureMemberHandler> Children { get; } = new();
-    
-    // Dependent on layer name
-    public override LocalizedString DisplayName => "";
-
-    public override LocalizedString Category => "STRUCTURE";
 }

+ 3 - 8
src/PixiEditor/ViewModels/Document/Nodes/ImageLayerNodeViewModel.cs

@@ -1,12 +1,12 @@
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
-using PixiEditor.Extensions.Common.Localization;
-using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.Handlers;
+using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class ImageLayerNodeViewModel : StructureMemberViewModel<LayerNode>, ILayerHandler
+[NodeViewModel("IMAGE_LAYER_NODE", "STRUCTURE")]
+internal class ImageLayerNodeViewModel : StructureMemberViewModel<ImageLayerNode>, ILayerHandler
 {
     bool lockTransparency;
     public void SetLockTransparency(bool lockTransparency)
@@ -36,9 +36,4 @@ internal class ImageLayerNodeViewModel : StructureMemberViewModel<LayerNode>, IL
             OnPropertyChanged(nameof(ShouldDrawOnMask));
         }
     }
-
-    // Dependent on layer name
-    public override LocalizedString DisplayName => "";
-
-    public override LocalizedString Category => "STRUCTURE";
 }

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/LerpColorNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class LerpColorNodeViewModel : NodeViewModel<LerpColorNode>
-{
-    public override LocalizedString DisplayName => "LERP_NODE";
-    
-    public override LocalizedString Category => "NUMBERS";
-}
+[NodeViewModel("LERP_NODE", "NUMBERS")]
+internal class LerpColorNodeViewModel : NodeViewModel<LerpColorNode>;

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/MathNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class MathNodeViewModel : NodeViewModel<MathNode>
-{
-    public override LocalizedString DisplayName => "MATH_NODE";
-    
-    public override LocalizedString Category => "NUMBERS";
-}
+[NodeViewModel("MATH_NODE", "NUMBERS")]
+internal class MathNodeViewModel : NodeViewModel<MathNode>;

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/MergeNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class MergeNodeViewModel : NodeViewModel<MergeNode>
-{
-    public override LocalizedString DisplayName => "MERGE_NODE";
-    
-    public override LocalizedString Category => "IMAGE";
-}
+[NodeViewModel("MERGE_NODE", "IMAGE")]
+internal class MergeNodeViewModel : NodeViewModel<MergeNode>;

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/ModifyImageLeftNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class ModifyImageLeftNodeViewModel : NodeViewModel<ModifyImageLeftNode>
-{
-    public override LocalizedString DisplayName => "MODIFY_IMAGE_LEFT_NODE";
-    
-    public override LocalizedString Category => "IMAGE";
-}
+[NodeViewModel("MODIFY_IMAGE_LEFT_NODE", "IMAGE")]
+internal class ModifyImageLeftNodeViewModel : NodeViewModel<ModifyImageLeftNode>;

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/ModifyImageRightNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class ModifyImageRightNodeViewModel : NodeViewModel<ModifyImageRightNode>
-{
-    public override LocalizedString DisplayName => "MODIFY_IMAGE_RIGHT_NODE";
-    
-    public override LocalizedString Category => "IMAGE";
-}
+[NodeViewModel("MODIFY_IMAGE_RIGHT_NODE", "IMAGE")]
+internal class ModifyImageRightNodeViewModel : NodeViewModel<ModifyImageRightNode>;

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/NoiseNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class NoiseNodeViewModel : NodeViewModel<NoiseNode>
-{
-    public override LocalizedString DisplayName => "NOISE_NODE";
-    
-    public override LocalizedString Category => "IMAGE";
-}
+[NodeViewModel("NOISE_NODE", "IMAGE")]
+internal class NoiseNodeViewModel : NodeViewModel<NoiseNode>;

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/OutputNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class OutputNodeViewModel : NodeViewModel<OutputNode>
-{
-    public override LocalizedString DisplayName => "OUTPUT_NODE";
-    
-    public override LocalizedString Category => "";
-}
+[NodeViewModel("OUTPUT_NODE", "", PickerName = "")]
+internal class OutputNodeViewModel : NodeViewModel<OutputNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/Points/DistributePointsNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Points;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.Points;
 
-internal class DistributePointsNodeViewModel : NodeViewModel<DistributePointsNode>
-{
-    public override LocalizedString DisplayName => "DISTRIBUTE_POINTS";
-    
-    public override LocalizedString Category => "SHAPE";
-}
+[NodeViewModel("DISTRIBUTE_POINTS", "SHAPE")]
+internal class DistributePointsNodeViewModel : NodeViewModel<DistributePointsNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/Points/RasterizePointsNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Points;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.Points;
 
-internal class RasterizePointsNodeViewModel : NodeViewModel<RasterizePointsNode>
-{
-    public override LocalizedString DisplayName => "RASTERIZE_POINTS";
-    
-    public override LocalizedString Category => "SHAPE";
-}
+[NodeViewModel("RASTERIZE_POINTS", "SHAPE")]
+internal class RasterizePointsNodeViewModel : NodeViewModel<RasterizePointsNode>;

+ 2 - 7
src/PixiEditor/ViewModels/Document/Nodes/Points/RemoveClosePointsNodeViewModel.cs

@@ -1,12 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Points;
-using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes.Points;
 
-internal class RemoveClosePointsNodeViewModel : NodeViewModel<RemoveClosePointsNode>
-{
-    public override LocalizedString DisplayName => "REMOVE_CLOSE_POINTS";
-    
-    public override LocalizedString Category => "SHAPE";
-}
+[NodeViewModel("REMOVE_CLOSE_POINTS", "SHAPE")]
+internal class RemoveClosePointsNodeViewModel : NodeViewModel<RemoveClosePointsNode>;

+ 2 - 6
src/PixiEditor/ViewModels/Document/Nodes/SampleImageNodeViewModel.cs

@@ -4,9 +4,5 @@ using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document.Nodes;
 
-internal class SampleImageNodeViewModel : NodeViewModel<SampleImageNode>
-{
-    public override LocalizedString DisplayName => "SAMPLE_IMAGE";
-    
-    public override LocalizedString Category => "IMAGE";
-}
+[NodeViewModel("SAMPLE_IMAGE", "IMAGE")]
+internal class SampleImageNodeViewModel : NodeViewModel<SampleImageNode>;

+ 27 - 8
src/PixiEditor/ViewModels/Nodes/NodeTypeInfo.cs

@@ -1,5 +1,6 @@
 using System.Reflection;
 using PixiEditor.ChangeableDocument.Changeables.Graph;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Fonts;
 using PixiEditor.UI.Common.Fonts;
@@ -8,8 +9,6 @@ namespace PixiEditor.ViewModels.Nodes;
 
 public class NodeTypeInfo
 {
-    public string UniqueName { get; }
-    
     public string DisplayName { get; }
     
     public string? PickerName { get; }
@@ -20,26 +19,46 @@ public class NodeTypeInfo
 
     public bool Hidden => PickerName is { Length: 0 };
     
+    public Type NodeViewModelType { get; }
+    
     public Type NodeType { get; }
     
     public string Icon { get; }
 
-    public NodeTypeInfo(Type type)
+    public NodeTypeInfo(Type viewModelType)
     {
-        NodeType = type;
-
-        var attribute = type.GetCustomAttribute<NodeInfoAttribute>();
+        NodeViewModelType = viewModelType;
+        NodeType = GetNodeType(NodeViewModelType.BaseType);
+        
+        var attribute = viewModelType.GetCustomAttribute<NodeViewModelAttribute>();
 
-        UniqueName = attribute.UniqueName;
         DisplayName = attribute.DisplayName;
         PickerName = attribute.PickerName;
         Category = attribute.Category ?? "";
 
-        if (NodeIcons.IconMap.TryGetValue(type, out var icon))
+        if (NodeIcons.IconMap.TryGetValue(NodeType, out var icon))
         {
             Icon = icon;
         }
 
         FinalPickerName = (PickerName ?? DisplayName);
     }
+
+    private Type GetNodeType(Type? baseType)
+    {
+        while (true)
+        {
+            if (baseType.IsGenericType)
+            {
+                var genericArgument = baseType.GetGenericArguments()[0];
+
+                if (genericArgument.IsAssignableTo(typeof(Node)))
+                {
+                    return genericArgument;
+                }
+            }
+
+            baseType = baseType.BaseType;
+        }
+    }
 }

+ 3 - 4
src/PixiEditor/ViewModels/Nodes/NodeViewModel.cs

@@ -32,11 +32,11 @@ internal abstract class NodeViewModel : ObservableObject, INodeHandler
 
     public Guid Id { get => id; private set => id = value; }
     
-    public abstract LocalizedString DisplayName { get; }
+    public LocalizedString DisplayName { get; set; }
     
-    public abstract LocalizedString Category { get; }
+    public LocalizedString Category { get; }
 
-    public virtual LocalizedString? PickerName { get; }
+    public LocalizedString? PickerName { get; }
 
     public string NodeNameBindable
     {
@@ -127,7 +127,6 @@ internal abstract class NodeViewModel : ObservableObject, INodeHandler
     
     public NodeViewModel()
     {
-        
     }
 
     public NodeViewModel(string nodeNameBindable, Guid id, VecD position, DocumentViewModel document, DocumentInternalParts internals)

+ 10 - 0
src/PixiEditor/ViewModels/Nodes/NodeViewModelAttribute.cs

@@ -0,0 +1,10 @@
+namespace PixiEditor.ViewModels.Nodes;
+
+public class NodeViewModelAttribute(string displayName, string? category) : Attribute
+{
+    public string DisplayName { get; } = displayName;
+
+    public string? Category { get; } = category;
+    
+    public string? PickerName { get; set; }
+}

+ 1 - 1
src/PixiEditor/Views/Nodes/NodeGraphView.cs

@@ -192,7 +192,7 @@ internal class NodeGraphView : Zoombox.Zoombox
         SocketDropCommand = new RelayCommand<NodeSocket>(SocketDrop);
         CreateNodeFromContextCommand = new RelayCommand<NodeTypeInfo>(CreateNodeType);
 
-        AllNodeTypes = new ObservableCollection<Type>(GatherAssemblyTypes<Node>());
+        AllNodeTypes = new ObservableCollection<Type>(GatherAssemblyTypes<NodeViewModel>());
         AllNodeTypeInfos = new ObservableCollection<NodeTypeInfo>(AllNodeTypes.Select(x => new NodeTypeInfo(x)));
     }