Преглед изворни кода

Serialization almost works

flabbet пре 1 година
родитељ
комит
0d445fda7b
100 измењених фајлова са 776 додато и 397 уклоњено
  1. 3 2
      src/ChunkyImageLib/Chunk.cs
  2. 4 3
      src/ChunkyImageLib/ChunkyImage.cs
  3. 2 2
      src/ChunkyImageLib/ChunkyImageEx.cs
  4. 2 2
      src/ChunkyImageLib/CommittedChunkStorage.cs
  5. 1 1
      src/ChunkyImageLib/DataHolders/ShapeData.cs
  6. 2 2
      src/ChunkyImageLib/IReadOnlyChunkyImage.cs
  7. 2 2
      src/ChunkyImageLib/Operations/ApplyMaskOperation.cs
  8. 0 1
      src/ChunkyImageLib/Operations/BresenhamLineHelper.cs
  9. 2 2
      src/ChunkyImageLib/Operations/BresenhamLineOperation.cs
  10. 2 2
      src/ChunkyImageLib/Operations/ChunkyImageOperation.cs
  11. 1 1
      src/ChunkyImageLib/Operations/ClearPathOperation.cs
  12. 2 2
      src/ChunkyImageLib/Operations/DrawingSurfaceLineOperation.cs
  13. 3 3
      src/ChunkyImageLib/Operations/EllipseOperation.cs
  14. 2 2
      src/ChunkyImageLib/Operations/ImageOperation.cs
  15. 1 1
      src/ChunkyImageLib/Operations/OperationHelper.cs
  16. 1 1
      src/ChunkyImageLib/Operations/PaintOperation.cs
  17. 3 3
      src/ChunkyImageLib/Operations/PathOperation.cs
  18. 2 2
      src/ChunkyImageLib/Operations/PixelOperation.cs
  19. 2 2
      src/ChunkyImageLib/Operations/PixelsOperation.cs
  20. 1 1
      src/ChunkyImageLib/Operations/RectangleOperation.cs
  21. 1 1
      src/ChunkyImageLib/Operations/ReplaceColorOperation.cs
  22. 4 4
      src/PixiEditor.AvaloniaUI.Desktop/PixiEditor.AvaloniaUI.Desktop.csproj
  23. 1 1
      src/PixiEditor.AvaloniaUI/Helpers/Converters/ImagePathToBitmapConverter.cs
  24. 1 1
      src/PixiEditor.AvaloniaUI/Helpers/Converters/VectorPathToVisibleConverter.cs
  25. 160 66
      src/PixiEditor.AvaloniaUI/Helpers/DocumentViewModelBuilder.cs
  26. 2 2
      src/PixiEditor.AvaloniaUI/Helpers/Extensions/BitmapExtensions.cs
  27. 1 1
      src/PixiEditor.AvaloniaUI/Helpers/Extensions/PixelFormatHelper.cs
  28. 131 6
      src/PixiEditor.AvaloniaUI/Helpers/Extensions/PixiParserDocumentEx.cs
  29. 4 8
      src/PixiEditor.AvaloniaUI/Helpers/Extensions/PixiParserV3DocumentEx.cs
  30. 38 0
      src/PixiEditor.AvaloniaUI/Helpers/SerializationUtil.cs
  31. 2 1
      src/PixiEditor.AvaloniaUI/Helpers/SurfaceHelpers.cs
  32. 2 2
      src/PixiEditor.AvaloniaUI/Helpers/WriteableBitmapUtility.cs
  33. 1 0
      src/PixiEditor.AvaloniaUI/Models/Clipboard/DataImage.cs
  34. 2 1
      src/PixiEditor.AvaloniaUI/Models/Controllers/ClipboardController.cs
  35. 1 1
      src/PixiEditor.AvaloniaUI/Models/DocumentModels/DocumentStructureHelper.cs
  36. 12 2
      src/PixiEditor.AvaloniaUI/Models/DocumentModels/DocumentUpdater.cs
  37. 3 2
      src/PixiEditor.AvaloniaUI/Models/DocumentModels/Public/DocumentOperationsModule.cs
  38. 1 1
      src/PixiEditor.AvaloniaUI/Models/DocumentModels/UpdateableChangeExecutors/LineToolExecutor.cs
  39. 1 0
      src/PixiEditor.AvaloniaUI/Models/DocumentModels/UpdateableChangeExecutors/PasteImageExecutor.cs
  40. 1 1
      src/PixiEditor.AvaloniaUI/Models/Files/BmpFileType.cs
  41. 3 4
      src/PixiEditor.AvaloniaUI/Models/Files/ImageFileType.cs
  42. 1 1
      src/PixiEditor.AvaloniaUI/Models/Files/JpegFileType.cs
  43. 1 1
      src/PixiEditor.AvaloniaUI/Models/Files/PngFileType.cs
  44. 2 2
      src/PixiEditor.AvaloniaUI/Models/Handlers/IDocument.cs
  45. 1 0
      src/PixiEditor.AvaloniaUI/Models/Handlers/IKeyFrameHandler.cs
  46. 2 1
      src/PixiEditor.AvaloniaUI/Models/Handlers/INodeHandler.cs
  47. 1 1
      src/PixiEditor.AvaloniaUI/Models/Handlers/IReferenceLayerHandler.cs
  48. 1 2
      src/PixiEditor.AvaloniaUI/Models/Handlers/IStructureMemberHandler.cs
  49. 2 1
      src/PixiEditor.AvaloniaUI/Models/IO/Exporter.cs
  50. 1 0
      src/PixiEditor.AvaloniaUI/Models/IO/FileEncoders/IFileEncoder.cs
  51. 2 1
      src/PixiEditor.AvaloniaUI/Models/IO/FileEncoders/UniversalFileEncoder.cs
  52. 5 4
      src/PixiEditor.AvaloniaUI/Models/IO/Importer.cs
  53. 3 2
      src/PixiEditor.AvaloniaUI/Models/Rendering/CanvasUpdater.cs
  54. 3 3
      src/PixiEditor.AvaloniaUI/Models/Rendering/MemberPreviewUpdater.cs
  55. 9 9
      src/PixiEditor.AvaloniaUI/Models/UserData/RecentlyOpenedDocument.cs
  56. 0 4
      src/PixiEditor.AvaloniaUI/PixiEditor.AvaloniaUI.csproj
  57. 1 1
      src/PixiEditor.AvaloniaUI/Styles/Templates/NodeGraphView.axaml
  58. 131 112
      src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.Serialization.cs
  59. 66 24
      src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.cs
  60. 2 2
      src/PixiEditor.AvaloniaUI/ViewModels/Document/KeyFrameGroupViewModel.cs
  61. 1 0
      src/PixiEditor.AvaloniaUI/ViewModels/Document/KeyFrameViewModel.cs
  62. 2 2
      src/PixiEditor.AvaloniaUI/ViewModels/Document/NodeGraphViewModel.cs
  63. 2 2
      src/PixiEditor.AvaloniaUI/ViewModels/Document/ReferenceLayerViewModel.cs
  64. 1 20
      src/PixiEditor.AvaloniaUI/ViewModels/Document/StructureMemberViewModel.cs
  65. 20 6
      src/PixiEditor.AvaloniaUI/ViewModels/Nodes/NodeViewModel.cs
  66. 0 2
      src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/AnimationsViewModel.cs
  67. 26 12
      src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/FileViewModel.cs
  68. 1 1
      src/PixiEditor.AvaloniaUI/ViewModels/Tools/Tools/MoveToolViewModel.cs
  69. 2 1
      src/PixiEditor.AvaloniaUI/Views/Dialogs/ExportFilePopup.axaml.cs
  70. 1 1
      src/PixiEditor.AvaloniaUI/Views/Layers/FolderControl.axaml
  71. 1 1
      src/PixiEditor.AvaloniaUI/Views/Layers/LayerControl.axaml
  72. 1 0
      src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/FixedViewport.axaml.cs
  73. 1 0
      src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/Viewport.axaml.cs
  74. 1 0
      src/PixiEditor.AvaloniaUI/Views/Nodes/NodeView.cs
  75. 1 1
      src/PixiEditor.AvaloniaUI/Views/Overlays/SelectionOverlay/SelectionOverlay.cs
  76. 3 2
      src/PixiEditor.AvaloniaUI/Views/Rendering/Scene.cs
  77. 1 0
      src/PixiEditor.AvaloniaUI/Views/Visuals/SurfaceControl.cs
  78. 1 0
      src/PixiEditor.AvaloniaUI/Views/Visuals/SurfaceImage.cs
  79. 1 1
      src/PixiEditor.ChangeableDocument/ChangeInfos/Drawing/Selection_ChangeInfo.cs
  80. 9 1
      src/PixiEditor.ChangeableDocument/ChangeInfos/NodeGraph/CreateNode_ChangeInfo.cs
  81. 3 0
      src/PixiEditor.ChangeableDocument/ChangeInfos/NodeGraph/NodeName_ChangeInfo.cs
  82. 1 1
      src/PixiEditor.ChangeableDocument/ChangeInfos/Structure/CreateFolder_ChangeInfo.cs
  83. 1 1
      src/PixiEditor.ChangeableDocument/ChangeInfos/Structure/CreateLayer_ChangeInfo.cs
  84. 2 2
      src/PixiEditor.ChangeableDocument/Changeables/Animations/AnimationData.cs
  85. 2 2
      src/PixiEditor.ChangeableDocument/Changeables/Animations/KeyFrame.cs
  86. 3 1
      src/PixiEditor.ChangeableDocument/Changeables/Animations/KeyFrameData.cs
  87. 3 2
      src/PixiEditor.ChangeableDocument/Changeables/Document.cs
  88. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Context/NoNodeFuncContextException.cs
  89. 1 2
      src/PixiEditor.ChangeableDocument/Changeables/Graph/InputProperty.cs
  90. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IBackgroundInput.cs
  91. 2 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyFolderNode.cs
  92. 2 2
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyImageNode.cs
  93. 5 5
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyNode.cs
  94. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyNodeGraph.cs
  95. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/NodeGraph.cs
  96. 17 0
      src/PixiEditor.ChangeableDocument/Changeables/Graph/NodeInfoAttribute.cs
  97. 2 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Animable/TimeNode.cs
  98. 4 4
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineChannelsNode.cs
  99. 2 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineColorNode.cs
  100. 2 2
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineVecD.cs

+ 3 - 2
src/ChunkyImageLib/Chunk.cs

@@ -1,7 +1,8 @@
 using ChunkyImageLib.DataHolders;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib;

+ 4 - 3
src/ChunkyImageLib/ChunkyImage.cs

@@ -4,11 +4,12 @@ using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.Operations;
 using OneOf;
 using OneOf.Types;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Numerics;
 
 [assembly: InternalsVisibleTo("ChunkyImageLibTest")]

+ 2 - 2
src/ChunkyImageLib/ChunkyImageEx.cs

@@ -1,8 +1,8 @@
 using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.Operations;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib;

+ 2 - 2
src/ChunkyImageLib/CommittedChunkStorage.cs

@@ -1,7 +1,7 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib;

+ 1 - 1
src/ChunkyImageLib/DataHolders/ShapeData.cs

@@ -1,6 +1,6 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.DataHolders;

+ 2 - 2
src/ChunkyImageLib/IReadOnlyChunkyImage.cs

@@ -1,8 +1,8 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib;

+ 2 - 2
src/ChunkyImageLib/Operations/ApplyMaskOperation.cs

@@ -1,7 +1,7 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 0 - 1
src/ChunkyImageLib/Operations/BresenhamLineHelper.cs

@@ -1,5 +1,4 @@
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 2 - 2
src/ChunkyImageLib/Operations/BresenhamLineOperation.cs

@@ -1,8 +1,8 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 2 - 2
src/ChunkyImageLib/Operations/ChunkyImageOperation.cs

@@ -1,7 +1,7 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/ChunkyImageLib/Operations/ClearPathOperation.cs

@@ -1,6 +1,6 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 2 - 2
src/ChunkyImageLib/Operations/DrawingSurfaceLineOperation.cs

@@ -1,8 +1,8 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 3 - 3
src/ChunkyImageLib/Operations/EllipseOperation.cs

@@ -1,9 +1,9 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 2 - 2
src/ChunkyImageLib/Operations/ImageOperation.cs

@@ -1,7 +1,7 @@
 using ChunkyImageLib.DataHolders;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/ChunkyImageLib/Operations/OperationHelper.cs

@@ -1,6 +1,6 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/ChunkyImageLib/Operations/PaintOperation.cs

@@ -1,5 +1,5 @@
 using ChunkyImageLib.DataHolders;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 3 - 3
src/ChunkyImageLib/Operations/PathOperation.cs

@@ -1,9 +1,9 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 2 - 2
src/ChunkyImageLib/Operations/PixelOperation.cs

@@ -1,8 +1,8 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 2 - 2
src/ChunkyImageLib/Operations/PixelsOperation.cs

@@ -3,8 +3,8 @@ using System.Linq;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/ChunkyImageLib/Operations/RectangleOperation.cs

@@ -1,6 +1,6 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/ChunkyImageLib/Operations/ReplaceColorOperation.cs

@@ -1,7 +1,7 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;

+ 4 - 4
src/PixiEditor.AvaloniaUI.Desktop/PixiEditor.AvaloniaUI.Desktop.csproj

@@ -20,11 +20,11 @@
         <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)"/>
     </ItemGroup>
 
-    <ItemGroup>
-        <ProjectReference Include="..\PixiEditor.AvaloniaUI\PixiEditor.AvaloniaUI.csproj" />
-    </ItemGroup>
-
   <ItemGroup>
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
   </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\PixiEditor.AvaloniaUI\PixiEditor.AvaloniaUI.csproj" />
+  </ItemGroup>
 </Project>

+ 1 - 1
src/PixiEditor.AvaloniaUI/Helpers/Converters/ImagePathToBitmapConverter.cs

@@ -36,7 +36,7 @@ internal class ImagePathToBitmapConverter : SingleInstanceConverter<ImagePathToB
         return new Bitmap(AssetLoader.Open(uri));
     }
 
-    public static DrawingApi.Core.Surface.Bitmap LoadDrawingApiBitmapFromRelativePath(string path)
+    public static DrawingApi.Core.Surfaces.Bitmap LoadDrawingApiBitmapFromRelativePath(string path)
     {
         Uri uri = new($"avares://{Assembly.GetExecutingAssembly().FullName}{path}");
         if (!AssetLoader.Exists(uri))

+ 1 - 1
src/PixiEditor.AvaloniaUI/Helpers/Converters/VectorPathToVisibleConverter.cs

@@ -1,6 +1,6 @@
 using System.Globalization;
 using Avalonia.Data.Converters;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 
 namespace PixiEditor.AvaloniaUI.Helpers.Converters;
 

+ 160 - 66
src/PixiEditor.AvaloniaUI/Helpers/DocumentViewModelBuilder.cs

@@ -1,16 +1,22 @@
-using ChunkyImageLib;
+using System.Collections;
+using System.Reflection;
+using ChunkyImageLib;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.AvaloniaUI.Helpers.Extensions;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
+using PixiEditor.ChangeableDocument.Changeables.Graph;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
 using PixiEditor.Parser;
 using PixiEditor.Parser.Graph;
 using PixiEditor.Parser.Skia;
+using NodeGraph = PixiEditor.Parser.Graph.NodeGraph;
 
 namespace PixiEditor.AvaloniaUI.Helpers;
 
-internal class DocumentViewModelBuilder : PixiParserV3DocumentEx.ChildrenBuilder
+internal class DocumentViewModelBuilder
 {
     public int Width { get; set; }
     public int Height { get; set; }
@@ -20,7 +26,7 @@ internal class DocumentViewModelBuilder : PixiParserV3DocumentEx.ChildrenBuilder
 
     public ReferenceLayerBuilder ReferenceLayer { get; set; }
     public List<KeyFrameBuilder> AnimationData { get; set; } = new List<KeyFrameBuilder>();
-    
+
     public NodeGraphBuilder Graph { get; set; }
 
     public DocumentViewModelBuilder WithSize(int width, int height)
@@ -51,7 +57,8 @@ internal class DocumentViewModelBuilder : PixiParserV3DocumentEx.ChildrenBuilder
     public DocumentViewModelBuilder WithPalette<T>(IEnumerable<T> pallet, Func<T, PaletteColor> toColor) =>
         WithPalette(pallet.Select(toColor));
 
-    public DocumentViewModelBuilder WithReferenceLayer<T>(T reference, Action<T, ReferenceLayerBuilder, ImageEncoder?> builder,
+    public DocumentViewModelBuilder WithReferenceLayer<T>(T reference,
+        Action<T, ReferenceLayerBuilder, ImageEncoder?> builder,
         ImageEncoder? encoder)
     {
         if (reference != null)
@@ -72,7 +79,7 @@ internal class DocumentViewModelBuilder : PixiParserV3DocumentEx.ChildrenBuilder
 
         return this;
     }
-    
+
     public DocumentViewModelBuilder WithAnimationData(AnimationData? animationData)
     {
         AnimationData = new List<KeyFrameBuilder>();
@@ -84,26 +91,37 @@ internal class DocumentViewModelBuilder : PixiParserV3DocumentEx.ChildrenBuilder
 
         return this;
     }
-    
-    public DocumentViewModelBuilder WithGraph(NodeGraph graph)
+
+    public DocumentViewModelBuilder WithGraph(NodeGraph graph, ImageEncoder encoder, Action<NodeGraph, NodeGraphBuilder, ImageEncoder> builder)
     {
-        Graph = new NodeGraphBuilder();
-        
-        if (graph.AllNodes != null)
+        if (graph != null)
         {
-            foreach (var node in graph.AllNodes)
-            {
-                Graph.WithNode(new NodeBuilder()
-                    .WithId(node.Id)
-                    .WithPosition(node.Position)
-                    .WithName(node.Name)
-                    .WithUniqueNodeName(node.UniqueNodeName));
-            }
+            WithGraph(x => builder(graph, x, encoder));
         }
-        
+
+        return this;
+    }
+
+    public DocumentViewModelBuilder WithGraph(Action<NodeGraphBuilder> builder)
+    {
+        var graph = new NodeGraphBuilder();
+        builder(graph);
+        Graph = graph;
         return this;
     }
 
+    private static Dictionary<string, object> ToDictionary(NodePropertyValue[] values)
+    {
+        Dictionary<string, object> dictionary = new();
+
+        foreach (var value in values)
+        {
+            dictionary.Add(value.PropertyName, value.Value);
+        }
+
+        return dictionary;
+    }
+
     private static void BuildKeyFrames(List<IKeyFrame> root, List<KeyFrameBuilder> data)
     {
         foreach (var keyFrame in root)
@@ -112,30 +130,27 @@ internal class DocumentViewModelBuilder : PixiParserV3DocumentEx.ChildrenBuilder
             {
                 GroupKeyFrameBuilder builder = new GroupKeyFrameBuilder()
                     .WithVisibility(group.Enabled)
-                    .WithId(group.LayerGuid)
-                    .WithLayerGuid(group.LayerGuid);
+                    .WithNodeId(group.NodeId);
 
                 foreach (var child in group.Children)
                 {
-                    if(child is KeyFrameGroup childGroup)
+                    if (child is KeyFrameGroup childGroup)
                     {
-                        builder.WithChild<GroupKeyFrameBuilder>(x => BuildKeyFrames(childGroup.Children, null, documentRootFolder));
+                        builder.WithChild<GroupKeyFrameBuilder>(x =>
+                            BuildKeyFrames(childGroup.Children, null));
                     }
                     else if (child is RasterKeyFrame rasterKeyFrame)
                     {
                         builder.WithChild<RasterKeyFrameBuilder>(x => x
                             .WithVisibility(builder.IsVisible)
-                            .WithId(rasterKeyFrame.Guid)
-                            .WithLayerGuid(rasterKeyFrame.LayerGuid)
+                            .WithLayerGuid(rasterKeyFrame.NodeId)
                             .WithStartFrame(rasterKeyFrame.StartFrame)
-                            .WithDuration(rasterKeyFrame.Duration)
-                            .WithSurface(Surface.Load(rasterKeyFrame.ImageBytes)));
+                            .WithDuration(rasterKeyFrame.Duration));
                     }
                 }
 
                 data?.Add(builder);
             }
-
         }
     }
 
@@ -198,8 +213,7 @@ internal class KeyFrameBuilder()
     public int StartFrame { get; set; }
     public int Duration { get; set; }
     public bool IsVisible { get; set; }
-    public Guid LayerGuid { get; set; }
-    public Guid Id { get; set; }
+    public int LayerId { get; set; }
 
     public KeyFrameBuilder WithStartFrame(int startFrame)
     {
@@ -219,15 +233,9 @@ internal class KeyFrameBuilder()
         return this;
     }
 
-    public KeyFrameBuilder WithLayerGuid(Guid layerGuid)
+    public KeyFrameBuilder WithLayerGuid(int layerGuid)
     {
-        LayerGuid = layerGuid;
-        return this;
-    }
-
-    public KeyFrameBuilder WithId(Guid id)
-    {
-        Id = id;
+        LayerId = layerGuid;
         return this;
     }
 }
@@ -243,20 +251,30 @@ internal class GroupKeyFrameBuilder : KeyFrameBuilder
         Children.Add(childBuilder);
         return this;
     }
-    
-    public new GroupKeyFrameBuilder WithVisibility(bool isVisible) => base.WithVisibility(isVisible) as GroupKeyFrameBuilder;
-    public new GroupKeyFrameBuilder WithLayerGuid(Guid layerGuid) => base.WithLayerGuid(layerGuid) as GroupKeyFrameBuilder;
-    public new GroupKeyFrameBuilder WithId(Guid id) => base.WithId(id) as GroupKeyFrameBuilder;
-    public new GroupKeyFrameBuilder WithStartFrame(int startFrame) => base.WithStartFrame(startFrame) as GroupKeyFrameBuilder;
+
+    public new GroupKeyFrameBuilder WithVisibility(bool isVisible) =>
+        base.WithVisibility(isVisible) as GroupKeyFrameBuilder;
+
+    public new GroupKeyFrameBuilder WithNodeId(int layerGuid) =>
+        base.WithLayerGuid(layerGuid) as GroupKeyFrameBuilder;
+
+    public new GroupKeyFrameBuilder WithStartFrame(int startFrame) =>
+        base.WithStartFrame(startFrame) as GroupKeyFrameBuilder;
+
     public new GroupKeyFrameBuilder WithDuration(int duration) => base.WithDuration(duration) as GroupKeyFrameBuilder;
 }
 
 internal class RasterKeyFrameBuilder : KeyFrameBuilder
 {
-    public new RasterKeyFrameBuilder WithVisibility(bool isVisible) => base.WithVisibility(isVisible) as RasterKeyFrameBuilder;
-    public new RasterKeyFrameBuilder WithLayerGuid(Guid layerGuid) => base.WithLayerGuid(layerGuid) as RasterKeyFrameBuilder;
-    public new RasterKeyFrameBuilder WithId(Guid id) => base.WithId(id) as RasterKeyFrameBuilder;
-    public new RasterKeyFrameBuilder WithStartFrame(int startFrame) => base.WithStartFrame(startFrame) as RasterKeyFrameBuilder;
+    public new RasterKeyFrameBuilder WithVisibility(bool isVisible) =>
+        base.WithVisibility(isVisible) as RasterKeyFrameBuilder;
+
+    public new RasterKeyFrameBuilder WithLayerGuid(int layerId) =>
+        base.WithLayerGuid(layerId) as RasterKeyFrameBuilder;
+
+    public new RasterKeyFrameBuilder WithStartFrame(int startFrame) =>
+        base.WithStartFrame(startFrame) as RasterKeyFrameBuilder;
+
     public new RasterKeyFrameBuilder WithDuration(int duration) => base.WithDuration(duration) as RasterKeyFrameBuilder;
 }
 
@@ -264,41 +282,117 @@ internal class NodeGraphBuilder
 {
     public List<NodeBuilder> AllNodes { get; set; } = new List<NodeBuilder>();
 
-    public NodeGraphBuilder WithNode(NodeBuilder node)
+
+    public NodeGraphBuilder WithNode(Action<NodeBuilder> nodeBuilder)
     {
+        var node = new NodeBuilder();
+        nodeBuilder(node);
+
         AllNodes.Add(node);
+
         return this;
     }
-}
-
-internal class NodeBuilder
-{
-    public int Id { get; set; }
-    public Vector2 Position { get; set; }
-    public string Name { get; set; }
-    public string UniqueNodeName { get; set; }
 
-    public NodeBuilder WithId(int id)
+    public NodeGraphBuilder WithOutputNode(int? toConnectNodeId, string? toConnectPropName)
     {
-        Id = id;
+        var node = this.WithNodeOfType(typeof(OutputNode))
+            .WithId(AllNodes.Count + 1);
+
+        if (toConnectNodeId != null && toConnectPropName != null)
+        {
+            node.WithConnections(new[]
+            {
+                new PropertyConnection
+                {
+                    OutputNodeId = toConnectNodeId.Value,
+                    OutputPropertyName = toConnectPropName,
+                    InputPropertyName = OutputNode.InputPropertyName
+                }
+            });
+        }
+
+        AllNodes.Add(node);
         return this;
     }
 
-    public NodeBuilder WithPosition(Vector2 position)
+    public NodeGraphBuilder WithImageLayerNode(string name, Surface image, out int id)
     {
-        Position = position;
+        AllNodes.Add(
+            this.WithNodeOfType(typeof(ImageLayerNode))
+                .WithName(name)
+                .WithId(AllNodes.Count + 1)
+                .WithAdditionalData(
+                    new Dictionary<string, object> { { ImageLayerNode.ImageFramesKey, new List<Surface> { image } } }));
+
+        id = AllNodes.Count;
         return this;
     }
 
-    public NodeBuilder WithName(string name)
+    public NodeBuilder WithNodeOfType(Type nodeType)
     {
-        Name = name;
-        return this;
+        var node = new NodeBuilder();
+        node.WithUniqueNodeName(nodeType.GetCustomAttribute<NodeInfoAttribute>().UniqueName);
+
+        return node;
     }
 
-    public NodeBuilder WithUniqueNodeName(string uniqueNodeName)
+    internal class NodeBuilder
     {
-        UniqueNodeName = uniqueNodeName;
-        return this;
+        public int Id { get; set; }
+        public Vector2 Position { get; set; }
+        public string Name { get; set; }
+        public string UniqueNodeName { get; set; }
+        public Dictionary<string, object> InputValues { get; set; }
+        public Dictionary<string, object> AdditionalData { get; set; }
+        public Dictionary<int, (string inputPropName, string outputPropName)> InputConnections { get; set; }
+
+        public NodeBuilder WithId(int id)
+        {
+            Id = id;
+            return this;
+        }
+
+        public NodeBuilder WithPosition(Vector2 position)
+        {
+            Position = position;
+            return this;
+        }
+
+        public NodeBuilder WithName(string name)
+        {
+            Name = name;
+            return this;
+        }
+
+        public NodeBuilder WithUniqueNodeName(string uniqueNodeName)
+        {
+            UniqueNodeName = uniqueNodeName;
+            return this;
+        }
+
+        public NodeBuilder WithInputValues(Dictionary<string, object> values)
+        {
+            InputValues = values;
+            return this;
+        }
+
+        public NodeBuilder WithAdditionalData(Dictionary<string, object> data)
+        {
+            AdditionalData = data;
+            return this;
+        }
+
+        public NodeBuilder WithConnections(PropertyConnection[] nodeInputConnections)
+        {
+            InputConnections = new Dictionary<int, (string, string)>();
+
+            foreach (var connection in nodeInputConnections)
+            {
+                InputConnections.Add(connection.OutputNodeId,
+                    (connection.InputPropertyName, connection.OutputPropertyName));
+            }
+
+            return this;
+        }
     }
 }

+ 2 - 2
src/PixiEditor.AvaloniaUI/Helpers/Extensions/BitmapExtensions.cs

@@ -47,10 +47,10 @@ public static class BitmapExtensions
         return new WriteableBitmap(PixelFormats.Bgra8888, AlphaFormat.Premul, address, size, new Vector(96, 96), stride);
     }
 
-    public static DrawingApi.Core.Surface.Bitmap FromStream(Stream stream)
+    public static DrawingApi.Core.Surfaces.Bitmap FromStream(Stream stream)
     {
         using var memoryStream = new MemoryStream();
         stream.CopyTo(memoryStream);
-        return DrawingApi.Core.Surface.Bitmap.Decode(memoryStream.ToArray());
+        return DrawingApi.Core.Surfaces.Bitmap.Decode(memoryStream.ToArray());
     }
 }

+ 1 - 1
src/PixiEditor.AvaloniaUI/Helpers/Extensions/PixelFormatHelper.cs

@@ -1,5 +1,5 @@
 using Avalonia.Platform;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
 
 namespace PixiEditor.AvaloniaUI.Helpers.Extensions;
 

+ 131 - 6
src/PixiEditor.AvaloniaUI/Helpers/Extensions/PixiParserDocumentEx.cs

@@ -1,5 +1,9 @@
-using ChunkyImageLib;
+using System.Collections;
+using ChunkyImageLib;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
+using PixiEditor.DrawingApi.Skia;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
 using PixiEditor.Parser;
@@ -10,6 +14,16 @@ namespace PixiEditor.AvaloniaUI.Helpers.Extensions;
 
 internal static class PixiParserDocumentEx
 {
+    public static VecD ToVecD(this Vector2 vec)
+    {
+        return new VecD(vec.X, vec.Y);
+    }
+
+    public static Vector2 ToVector2(this VecD vec)
+    {
+        return new Vector2() { X = vec.X, Y = vec.Y };
+    }
+
     public static DocumentViewModel ToDocument(this Document document)
     {
         ImageEncoder? encoder = document.GetEncoder();
@@ -22,11 +36,111 @@ internal static class PixiParserDocumentEx
             .WithSize(document.Width, document.Height)
             .WithPalette(document.Palette, color => new PaletteColor(color.R, color.G, color.B))
             .WithSwatches(document.Swatches, x => new(x.R, x.G, x.B))
-            .WithReferenceLayer(document.ReferenceLayer, BuildReferenceLayer, document.GetEncoder())
-            .WithGraph(document.Graph)
+            .WithReferenceLayer(document.ReferenceLayer, BuildReferenceLayer, encoder)
+            .WithGraph(document.Graph, encoder, BuildGraph)
             .WithAnimationData(document.AnimationData));
     }
 
+    private static void BuildGraph(NodeGraph graph, NodeGraphBuilder graphBuilder, ImageEncoder encoder)
+    {
+        if (graph.AllNodes != null)
+        {
+            foreach (var node in graph.AllNodes)
+            {
+                graphBuilder.WithNode(x => x
+                    .WithId(node.Id)
+                    .WithPosition(node.Position)
+                    .WithName(node.Name)
+                    .WithUniqueNodeName(node.UniqueNodeName)
+                    .WithInputValues(ParseArbitraryData(ToDictionary(node.InputPropertyValues), encoder))
+                    .WithAdditionalData(ParseArbitraryData(node.AdditionalData, encoder))
+                    .WithConnections(node.InputConnections));
+            }
+        }
+    }
+
+    private static Dictionary<string, object> ParseArbitraryData(Dictionary<string, object> data, ImageEncoder encoder)
+    {
+        Dictionary<string, object> parsedData = new();
+
+        foreach (var item in data)
+        {
+            if (item.Value is IEnumerable enumerable)
+            {
+                List<object> parsedList = new();
+                foreach (var listElement in enumerable)
+                {
+                    if (TryParseSurface(listElement, encoder, out object parsed))
+                    {
+                        parsedList.Add(parsed);
+                    }
+                }
+
+                if (parsedList.Count > 0)
+                {
+                    // if all children are the same type
+                    if (parsedList.All(x => x is Surface))
+                    {
+                        parsedData.Add(item.Key, parsedList.Cast<Surface>());
+                    }
+                    else
+                    {
+                        parsedData.Add(item.Key, parsedList);
+                    }
+                }
+                else
+                {
+                    parsedData.Add(item.Key, item.Value);
+                }
+            }
+            else if (TryParseSurface(item, encoder, out object parsed))
+            {
+                parsedData.Add(item.Key, parsed);
+            }
+            else
+            {
+                parsedData.Add(item.Key, item.Value);
+            }
+        }
+
+        return parsedData;
+    }
+
+    private static bool TryParseSurface(object item, ImageEncoder encoder, out object parsed)
+    {
+        parsed = null;
+        if (item is IEnumerable<object> objEnumerable)
+        {
+            var array = objEnumerable.ToArray();
+            if (array.Count() == 3 && array.First() is IEnumerable<byte> bytes)
+            {
+                try
+                {
+                    parsed = DecodeSurface(bytes.ToArray(), encoder);
+                    return true;
+                }
+                catch
+                {
+                    parsed = item;
+                    return false;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private static Dictionary<string, object> ToDictionary(IEnumerable<NodePropertyValue> properties)
+    {
+        Dictionary<string, object> dict = new();
+        foreach (var property in properties)
+        {
+            dict[property.PropertyName] = property.Value;
+        }
+
+        return dict;
+    }
+
     private static void BuildReferenceLayer(
         ReferenceLayer referenceLayer,
         DocumentViewModelBuilder.ReferenceLayerBuilder layerBuilder,
@@ -46,9 +160,20 @@ internal static class PixiParserDocumentEx
         Surface surface = new Surface(new VecI(width, height));
 
         byte[] decoded =
-            encoder.Decode(imgBytes, out SKColorType colorType, out SKAlphaType alphaType);
-        surface.DrawBytes(surface.Size, decoded, colorType.ToColorType(), alphaType.ToAlphaType());
-        
+            encoder.Decode(imgBytes, out SKImageInfo info);
+        surface.DrawBytes(surface.Size, decoded, info.ColorType.ToColorType(), info.AlphaType.ToAlphaType());
+
+        return surface;
+    }
+    
+    private static Surface DecodeSurface(byte[] imgBytes, ImageEncoder encoder)
+    {
+        byte[] decoded =
+            encoder.Decode(imgBytes, out SKImageInfo info);
+        using Image img = Image.FromPixels(info.ToImageInfo(), decoded);
+        Surface surface = new Surface(img.Size);
+        surface.DrawingSurface.Canvas.DrawImage(img, 0, 0);
+
         return surface;
     }
 }

+ 4 - 8
src/PixiEditor.AvaloniaUI/Helpers/Extensions/PixiParserV3DocumentEx.cs

@@ -1,7 +1,8 @@
 using System.Diagnostics.CodeAnalysis;
 using ChunkyImageLib;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
 using PixiEditor.Parser;
@@ -12,16 +13,11 @@ namespace PixiEditor.AvaloniaUI.Helpers.Extensions;
 
 internal static class PixiParserV3DocumentEx
 {
-    public static VecD ToVecD(this Vector2 vec)
-    {
-        return new VecD(vec.X, vec.Y);
-    }
-
     public static DocumentViewModel ToDocument(this DeprecatedDocument document)
     {
         return DocumentViewModel.Build(b =>
         {
-            b.WithSize(document.Width, document.Height)
+            /*b.WithSize(document.Width, document.Height)
                 .WithPalette(document.Palette, x => new PaletteColor(x.R, x.G, x.B))
                 .WithSwatches(document.Swatches, x => new(x.R, x.G, x.B))
                 .WithReferenceLayer(document.ReferenceLayer, (r, builder) => builder
@@ -30,7 +26,7 @@ internal static class PixiParserV3DocumentEx
                     .WithIsTopmost(r.Topmost)
                     .WithSurface(Surface.Load(r.ImageBytes)));
 
-            BuildChildren(b, document.RootFolder.Children);
+            BuildChildren(b, document.RootFolder.Children);*/
         });
 
         void BuildChildren(ChildrenBuilder builder, IEnumerable<IStructureMember> members)

+ 38 - 0
src/PixiEditor.AvaloniaUI/Helpers/SerializationUtil.cs

@@ -0,0 +1,38 @@
+using ChunkyImageLib;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.Numerics;
+using PixiEditor.Parser;
+using PixiEditor.Parser.Skia;
+
+namespace PixiEditor.AvaloniaUI.Helpers;
+
+public static class SerializationUtil
+{
+    public static object SerializeObject(object? value, ImageEncoder encoder)
+    {
+        if (value is null)
+        {
+            return null;
+        }
+
+        if (value is Surface surface)
+        {
+            byte[] result = encoder.Encode(surface.ToByteArray(), surface.Size.X, surface.Size.Y);
+            IImageContainer container =
+                new ImageContainer { ImageBytes = result, ResourceOffset = 0, ResourceSize = result.Length };
+            return container;
+        }
+
+        if (value.GetType().IsValueType || value is string)
+        {
+            return value;
+        }
+
+        if (value is ISerializable serializable)
+        {
+            return serializable.Serialize();
+        }
+
+        throw new ArgumentException($"Type {value.GetType()} is not serializable and does not implement ISerializable");
+    }
+}

+ 2 - 1
src/PixiEditor.AvaloniaUI/Helpers/SurfaceHelpers.cs

@@ -1,8 +1,9 @@
 using Avalonia.Media.Imaging;
 using ChunkyImageLib;
 using PixiEditor.AvaloniaUI.Helpers.Extensions;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Helpers;

+ 2 - 2
src/PixiEditor.AvaloniaUI/Helpers/WriteableBitmapUtility.cs

@@ -3,8 +3,8 @@ using Avalonia.Media.Imaging;
 using Avalonia.Platform;
 using PixiEditor.AvaloniaUI.Helpers.Extensions;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Helpers;

+ 1 - 0
src/PixiEditor.AvaloniaUI/Models/Clipboard/DataImage.cs

@@ -1,4 +1,5 @@
 using ChunkyImageLib;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Numerics;
 

+ 2 - 1
src/PixiEditor.AvaloniaUI/Models/Controllers/ClipboardController.cs

@@ -19,8 +19,9 @@ using PixiEditor.AvaloniaUI.Models.Dialogs;
 using PixiEditor.AvaloniaUI.Models.IO;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.ChangeableDocument.Enums;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
 using PixiEditor.Numerics;
 using PixiEditor.Parser;
 using PixiEditor.Parser.Deprecated;

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/DocumentModels/DocumentStructureHelper.cs

@@ -27,7 +27,7 @@ internal class DocumentStructureHelper
         {
             if (newNode is IStructureMemberHandler structureMemberHandler)
             {
-                string childName = structureMemberHandler.NameBindable;
+                string childName = structureMemberHandler.NodeNameBindable;
                 if (childName.StartsWith(name))
                     count++;
             }

+ 12 - 2
src/PixiEditor.AvaloniaUI/Models/DocumentModels/DocumentUpdater.cs

@@ -18,6 +18,7 @@ using PixiEditor.ChangeableDocument.ChangeInfos.Root;
 using PixiEditor.ChangeableDocument.ChangeInfos.Root.ReferenceLayerChangeInfos;
 using PixiEditor.ChangeableDocument.ChangeInfos.Structure;
 using PixiEditor.ChangeableDocument.Enums;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Models.DocumentModels;
@@ -189,6 +190,9 @@ internal class DocumentUpdater
             case PropertyValueUpdated_ChangeInfo info:
                 ProcessNodePropertyValueUpdated(info);
                 break;
+            case NodeName_ChangeInfo info:
+                ProcessNodeName(info);
+                break;
         }
     }
 
@@ -492,13 +496,13 @@ internal class DocumentUpdater
     {
         T node = new T()
         {
-            NodeName = info.NodeName,
             InternalName = info.InternalName,
             Id = info.Id,
             Document = (DocumentViewModel)doc,
             Internals = helper
         };
-
+        
+        node.SetName(info.NodeName);
         node.SetPosition(info.Position);
         
         List<INodePropertyHandler> inputs = CreateProperties(info.Inputs, node, true);
@@ -588,4 +592,10 @@ internal class DocumentUpdater
         
         property.InternalSetValue(info.Value);
     }
+    
+    private void ProcessNodeName(NodeName_ChangeInfo info)
+    {
+        NodeViewModel node = doc.StructureHelper.FindNode<NodeViewModel>(info.NodeId);
+        node.SetName(info.NewName);
+    }
 }

+ 3 - 2
src/PixiEditor.AvaloniaUI/Models/DocumentModels/Public/DocumentOperationsModule.cs

@@ -15,8 +15,9 @@ using PixiEditor.AvaloniaUI.Models.Tools;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.ChangeableDocument.Actions.Undo;
 using PixiEditor.ChangeableDocument.Enums;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
 
@@ -408,7 +409,7 @@ internal class DocumentOperationsModule : IDocumentOperations
         //make a new layer, put combined image onto it, delete layers that were merged
         Internals.ActionAccumulator.AddActions(
             new CreateStructureMember_Action(parent.Id, newGuid, StructureMemberType.Layer),
-            new StructureMemberName_Action(newGuid, node.NameBindable),
+            new StructureMemberName_Action(newGuid, node.NodeNameBindable),
             new CombineStructureMembersOnto_Action(members.ToHashSet(), newGuid, Document.AnimationHandler.ActiveFrameBindable));
         foreach (var member in members)
             Internals.ActionAccumulator.AddActions(new DeleteStructureMember_Action(member));

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/DocumentModels/UpdateableChangeExecutors/LineToolExecutor.cs

@@ -4,7 +4,7 @@ using PixiEditor.AvaloniaUI.Models.Tools;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
 

+ 1 - 0
src/PixiEditor.AvaloniaUI/Models/DocumentModels/UpdateableChangeExecutors/PasteImageExecutor.cs

@@ -3,6 +3,7 @@ using ChunkyImageLib.DataHolders;
 using PixiEditor.AvaloniaUI.Models.Handlers;
 using PixiEditor.AvaloniaUI.Models.Tools;
 using PixiEditor.ChangeableDocument.Actions.Generated;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Numerics;
 

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/Files/BmpFileType.cs

@@ -1,5 +1,5 @@
 using Avalonia.Media;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Extensions.Common.Localization;
 
 namespace PixiEditor.AvaloniaUI.Models.Files;

+ 3 - 4
src/PixiEditor.AvaloniaUI/Models/Files/ImageFileType.cs

@@ -4,10 +4,9 @@ using PixiEditor.AvaloniaUI.Helpers;
 using PixiEditor.AvaloniaUI.Models.IO;
 using PixiEditor.AvaloniaUI.Models.IO.FileEncoders;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Models.Files;
@@ -94,7 +93,7 @@ internal abstract class ImageFileType : IoFileType
         try
         {
             if (!encoder.SupportsTransparency)
-                bitmap.DrawingSurface.Canvas.DrawColor(Colors.White, DrawingApi.Core.Surface.BlendMode.Multiply);
+                bitmap.DrawingSurface.Canvas.DrawColor(Colors.White, BlendMode.Multiply);
 
             await using var stream = new FileStream(savePath, FileMode.Create);
             await encoder.SaveAsync(stream, bitmap);

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/Files/JpegFileType.cs

@@ -1,5 +1,5 @@
 using Avalonia.Media;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Extensions.Common.Localization;
 
 namespace PixiEditor.AvaloniaUI.Models.Files;

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/Files/PngFileType.cs

@@ -1,5 +1,5 @@
 using Avalonia.Media;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Extensions.Common.Localization;
 
 namespace PixiEditor.AvaloniaUI.Models.Files;

+ 2 - 2
src/PixiEditor.AvaloniaUI/Models/Handlers/IDocument.cs

@@ -7,10 +7,10 @@ using PixiEditor.AvaloniaUI.Models.DocumentModels.Public;
 using PixiEditor.AvaloniaUI.Models.Structures;
 using PixiEditor.AvaloniaUI.Models.Tools;
 using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
 

+ 1 - 0
src/PixiEditor.AvaloniaUI/Models/Handlers/IKeyFrameHandler.cs

@@ -1,4 +1,5 @@
 using ChunkyImageLib;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.AvaloniaUI.Models.Handlers;
 

+ 2 - 1
src/PixiEditor.AvaloniaUI/Models/Handlers/INodeHandler.cs

@@ -3,6 +3,7 @@ using System.ComponentModel;
 using ChunkyImageLib;
 using PixiEditor.AvaloniaUI.Models.Structures;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Models.Handlers;
@@ -10,7 +11,7 @@ namespace PixiEditor.AvaloniaUI.Models.Handlers;
 public interface INodeHandler : INotifyPropertyChanged
 {
     public Guid Id { get; }
-    public string NodeName { get; set; }
+    public string NodeNameBindable { get; set; }
     public string InternalName { get; }
     public ObservableRangeCollection<INodePropertyHandler> Inputs { get; }
     public ObservableRangeCollection<INodePropertyHandler> Outputs { get; }

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/Handlers/IReferenceLayerHandler.cs

@@ -3,8 +3,8 @@ using Avalonia;
 using Avalonia.Media.Imaging;
 using ChunkyImageLib;
 using ChunkyImageLib.DataHolders;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Models.Handlers;

+ 1 - 2
src/PixiEditor.AvaloniaUI/Models/Handlers/IStructureMemberHandler.cs

@@ -2,8 +2,8 @@
 using Avalonia.Media.Imaging;
 using ChunkyImageLib;
 using PixiEditor.AvaloniaUI.Models.Layers;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.Numerics;
 using BlendMode = PixiEditor.ChangeableDocument.Enums.BlendMode;
 
@@ -12,7 +12,6 @@ namespace PixiEditor.AvaloniaUI.Models.Handlers;
 internal interface IStructureMemberHandler : INodeHandler
 {
     public bool HasMaskBindable { get; }
-    public string NameBindable { get; set; }
     public Surface? MaskPreviewSurface { get; set; }
     public Surface? PreviewSurface { get; set; }
     public bool MaskIsVisibleBindable { get; set; }

+ 2 - 1
src/PixiEditor.AvaloniaUI/Models/IO/Exporter.cs

@@ -7,7 +7,8 @@ using ChunkyImageLib;
 using PixiEditor.AvaloniaUI.Helpers;
 using PixiEditor.AvaloniaUI.Models.Files;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Models.IO;

+ 1 - 0
src/PixiEditor.AvaloniaUI/Models/IO/FileEncoders/IFileEncoder.cs

@@ -1,6 +1,7 @@
 using System.IO;
 using System.Threading.Tasks;
 using ChunkyImageLib;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.AvaloniaUI.Models.IO.FileEncoders;
 

+ 2 - 1
src/PixiEditor.AvaloniaUI/Models/IO/FileEncoders/UniversalFileEncoder.cs

@@ -1,7 +1,8 @@
 using System.IO;
 using System.Threading.Tasks;
 using ChunkyImageLib;
-using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.DrawingApi.Core.Surfaces;
 
 namespace PixiEditor.AvaloniaUI.Models.IO.FileEncoders;
 

+ 5 - 4
src/PixiEditor.AvaloniaUI/Models/IO/Importer.cs

@@ -8,17 +8,18 @@ using PixiEditor.AvaloniaUI.Exceptions;
 using PixiEditor.AvaloniaUI.Helpers;
 using PixiEditor.AvaloniaUI.Helpers.Extensions;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.Exceptions;
 using PixiEditor.Numerics;
 using PixiEditor.Parser;
 using PixiEditor.Parser.Deprecated;
 using Bitmap = Avalonia.Media.Imaging.Bitmap;
-using BlendMode = PixiEditor.DrawingApi.Core.Surface.BlendMode;
+using BlendMode = PixiEditor.DrawingApi.Core.Surfaces.BlendMode;
 
 namespace PixiEditor.AvaloniaUI.Models.IO;
 

+ 3 - 2
src/PixiEditor.AvaloniaUI/Models/Rendering/CanvasUpdater.cs

@@ -7,9 +7,10 @@ using PixiEditor.AvaloniaUI.Models.DocumentModels;
 using PixiEditor.AvaloniaUI.Models.Handlers;
 using PixiEditor.AvaloniaUI.Models.Rendering.RenderInfos;
 using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Models.Rendering;

+ 3 - 3
src/PixiEditor.AvaloniaUI/Models/Rendering/MemberPreviewUpdater.cs

@@ -14,10 +14,10 @@ using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Models.Rendering;

+ 9 - 9
src/PixiEditor.AvaloniaUI/Models/UserData/RecentlyOpenedDocument.cs

@@ -4,6 +4,7 @@ using System.Linq;
 using ChunkyImageLib;
 using CommunityToolkit.Mvvm.ComponentModel;
 using PixiEditor.AvaloniaUI.Helpers;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Extensions.Exceptions;
 using PixiEditor.Numerics;
@@ -88,8 +89,6 @@ internal class RecentlyOpenedDocument : ObservableObject
 
         if (FileExtension == ".pixi")
         {
-            SerializableDocument serializableDocument;
-
             try
             {
                 var document = PixiParser.Deserialize(filePath);
@@ -106,7 +105,14 @@ internal class RecentlyOpenedDocument : ObservableObject
 
                 try
                 {
-                    serializableDocument = DepractedPixiParser.Deserialize(filePath);
+                    var deprecatedDocument = DeprecatedPixiParser.Deserialize(filePath);
+                    
+                    if (deprecatedDocument.PreviewImage == null || deprecatedDocument.PreviewImage.Length == 0)
+                    {
+                        return null;
+                    }
+                    
+                    return Surface.Load(deprecatedDocument.PreviewImage);
                 }
                 catch
                 {
@@ -115,12 +121,6 @@ internal class RecentlyOpenedDocument : ObservableObject
                 }
             }
 
-            Surface surface = Surface.Combine(serializableDocument.Width, serializableDocument.Height,
-                serializableDocument.Layers
-                    .Where(x => x.Opacity > 0.8)
-                    .Select(x => (x.ToImage(), new VecI(x.OffsetX, x.OffsetY))).ToList());
-
-            return DownscaleToMaxSize(surface);
         }
 
         if (SupportedFilesHelper.IsExtensionSupported(FileExtension))

+ 0 - 4
src/PixiEditor.AvaloniaUI/PixiEditor.AvaloniaUI.csproj

@@ -89,11 +89,7 @@
     <ProjectReference Include="..\PixiEditor.Extensions.Runtime\PixiEditor.Extensions.Runtime.csproj"/>
     <ProjectReference Include="..\PixiEditor.Extensions.WasmRuntime\PixiEditor.Extensions.WasmRuntime.csproj"/>
     <ProjectReference Include="..\PixiEditor.Extensions\PixiEditor.Extensions.csproj"/>
-    <ProjectReference Include="..\PixiEditor.OperatingSystem\PixiEditor.OperatingSystem.csproj"/>
-    <ProjectReference Include="..\PixiEditor.Platform.MSStore\PixiEditor.Platform.MSStore.csproj"/>
     <ProjectReference Include="..\PixiEditor.Platform.Standalone\PixiEditor.Platform.Standalone.csproj"/>
-    <ProjectReference Include="..\PixiEditor.Platform.Steam\PixiEditor.Platform.Steam.csproj"/>
-    <ProjectReference Include="..\PixiEditor.Platform\PixiEditor.Platform.csproj"/>
     <ProjectReference Include="..\PixiEditor.UI.Common\PixiEditor.UI.Common.csproj"/>
     <ProjectReference Include="..\PixiEditor.UpdateModule\PixiEditor.UpdateModule.csproj"/>
     <ProjectReference Include="..\PixiEditor.Zoombox\PixiEditor.Zoombox.csproj"/>

+ 1 - 1
src/PixiEditor.AvaloniaUI/Styles/Templates/NodeGraphView.axaml

@@ -38,7 +38,7 @@
                                 <DataTemplate>
                                     <nodes:NodeView
                                         Node="{Binding}"
-                                        DisplayName="{Binding NodeName}"
+                                        DisplayName="{Binding NodeNameBindable}"
                                         Inputs="{Binding Inputs}"
                                         BorderBrush="{Binding InternalName, Converter={converters:NodeInternalNameToStyleConverter}, ConverterParameter='BorderBrush'}"
                                         BorderThickness="2"

+ 131 - 112
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.Serialization.cs

@@ -1,25 +1,28 @@
-using System.Collections.Generic;
+using System.Collections;
 using System.Drawing;
-using System.IO;
-using System.Linq;
 using ChunkyImageLib;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.AvaloniaUI.Helpers;
-using PixiEditor.AvaloniaUI.Models.Handlers;
+using PixiEditor.AvaloniaUI.Helpers.Extensions;
+using PixiEditor.AvaloniaUI.Models.IO;
 using PixiEditor.AvaloniaUI.Models.IO.FileEncoders;
+using PixiEditor.ChangeableDocument.Changeables;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Bridge;
-using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
 using PixiEditor.Parser;
 using PixiEditor.Parser.Collections;
-using BlendMode = PixiEditor.Parser.BlendMode;
+using PixiEditor.Parser.Graph;
+using PixiEditor.Parser.Skia;
+using PixiEditor.Parser.Skia.Encoders;
 using IKeyFrameChildrenContainer = PixiEditor.ChangeableDocument.Changeables.Interfaces.IKeyFrameChildrenContainer;
 using PixiDocument = PixiEditor.Parser.Document;
+using ReferenceLayer = PixiEditor.Parser.ReferenceLayer;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.Document;
 
@@ -27,24 +30,117 @@ internal partial class DocumentViewModel
 {
     public PixiDocument ToSerializable()
     {
-        var root = new Folder();
-        
+        Parser.Graph.NodeGraph graph = new();
+        ImageEncoder encoder = new QoiEncoder();
         var doc = Internals.Tracker.Document;
 
-        //AddMembers(doc.StructureRoot.Children, doc, root);
+        Dictionary<Guid, int> idMap = new();
+
+        AddNodes(doc.NodeGraph, graph, idMap, encoder);
 
         var document = new PixiDocument
         {
-            Width = Width, Height = Height,
-            Swatches = ToCollection(Swatches), Palette = ToCollection(Palette),
-            RootFolder = root, PreviewImage = (TryRenderWholeImage(0).Value as Surface)?.DrawingSurface.Snapshot().Encode().AsSpan().ToArray(),
+            Width = Width,
+            Height = Height,
+            Swatches = ToCollection(Swatches),
+            Palette = ToCollection(Palette),
+            Graph = graph,
+            PreviewImage =
+                (TryRenderWholeImage(0).Value as Surface)?.DrawingSurface.Snapshot().Encode().AsSpan().ToArray(),
             ReferenceLayer = GetReferenceLayer(doc),
-            AnimationData = ToAnimationData(doc.AnimationData)
+            AnimationData = ToAnimationData(doc.AnimationData, idMap),
+            ImageEncoderUsed = encoder.EncodedFormatName
         };
 
         return document;
     }
 
+    private static void AddNodes(IReadOnlyNodeGraph graph, NodeGraph targetGraph, Dictionary<Guid, int> idMap,
+        ImageEncoder encoder)
+    {
+        targetGraph.AllNodes = new List<Node>();
+
+        int id = 0;
+        foreach (var node in graph.AllNodes)
+        {
+            idMap[node.Id] = id + 1;
+            id++;
+        }
+        
+        foreach (var node in graph.AllNodes)
+        {
+            NodePropertyValue[] properties = new NodePropertyValue[node.InputProperties.Count];
+
+            for (int i = 0; i < node.InputProperties.Count(); i++)
+            {
+                properties[i] = new NodePropertyValue()
+                {
+                    PropertyName = node.InputProperties[i].InternalPropertyName,
+                    Value = SerializationUtil.SerializeObject(node.InputProperties[i].NonOverridenValue, encoder)
+                };
+            }
+
+            Dictionary<string, object> additionalData = new();
+            node.SerializeAdditionalData(additionalData);
+
+            Dictionary<string, object> converted = ConvertToSerializable(additionalData, encoder);
+
+            List<PropertyConnection> connections = new();
+
+            foreach (var inputProp in node.InputProperties)
+            {
+                if (inputProp.Connection != null)
+                {
+                    connections.Add(new PropertyConnection()
+                    {
+                        OutputNodeId = idMap[inputProp.Connection.Node.Id],
+                        OutputPropertyName = inputProp.Connection.InternalPropertyName,
+                        InputPropertyName = inputProp.InternalPropertyName
+                    });
+                }
+            }
+
+            Node parserNode = new Node()
+            {
+                Id = idMap[node.Id],
+                Name = node.DisplayName,
+                UniqueNodeName = node.GetNodeTypeUniqueName(),
+                Position = node.Position.ToVector2(),
+                InputPropertyValues = properties,
+                AdditionalData = converted,
+                InputConnections = connections.ToArray()
+            };
+
+            targetGraph.AllNodes.Add(parserNode);
+        }
+    }
+
+    private static Dictionary<string, object> ConvertToSerializable(
+        Dictionary<string, object> additionalData,
+        ImageEncoder encoder)
+    {
+        Dictionary<string, object> converted = new();
+        foreach (var (key, value) in additionalData)
+        {
+            if (value is IEnumerable enumerable)
+            {
+                List<object> list = new();
+                foreach (var item in enumerable)
+                {
+                    list.Add(SerializationUtil.SerializeObject(item, encoder));
+                }
+
+                converted[key] = list;
+            }
+            else
+            {
+                converted[key] = SerializationUtil.SerializeObject(value, encoder);
+            }
+        }
+
+        return converted;
+    }
+
     private static ReferenceLayer? GetReferenceLayer(IReadOnlyDocument document)
     {
         if (document.ReferenceLayer == null)
@@ -55,13 +151,13 @@ internal partial class DocumentViewModel
         var layer = document.ReferenceLayer!;
 
         var surface = new Surface(new VecI(layer.ImageSize.X, layer.ImageSize.Y));
-        
+
         surface.DrawBytes(surface.Size, layer.ImageBgra8888Bytes.ToArray(), ColorType.Bgra8888, AlphaType.Premul);
 
         var encoder = new UniversalFileEncoder(EncodedImageFormat.Png);
 
         using var stream = new MemoryStream();
-        
+
         encoder.Save(stream, surface);
 
         stream.Position = 0;
@@ -75,9 +171,9 @@ internal partial class DocumentViewModel
             OffsetY = (float)layer.Shape.TopLeft.Y,
             Corners = new Corners
             {
-                TopLeft = layer.Shape.TopLeft.ToVector2(), 
-                TopRight = layer.Shape.TopRight.ToVector2(), 
-                BottomLeft = layer.Shape.BottomLeft.ToVector2(), 
+                TopLeft = layer.Shape.TopLeft.ToVector2(),
+                TopRight = layer.Shape.TopRight.ToVector2(),
+                BottomLeft = layer.Shape.BottomLeft.ToVector2(),
                 BottomRight = layer.Shape.BottomRight.ToVector2()
             },
             Opacity = 1,
@@ -85,129 +181,53 @@ internal partial class DocumentViewModel
         };
     }
 
-    private static void AddMembers(IEnumerable<IReadOnlyStructureNode> members, IReadOnlyDocument document, Folder parent)
-    {
-        foreach (var member in members)
-        {
-            if (member is IReadOnlyFolderNode readOnlyFolder)
-            {
-                var folder = ToSerializable(readOnlyFolder);
-
-                //AddMembers(readOnlyFolder.Children, document, folder);
-
-                parent.Children.Add(folder);
-            }
-            else if (member is IReadOnlyLayerNode readOnlyLayer)
-            {
-                parent.Children.Add(ToSerializable(readOnlyLayer, document));
-            }
-        }
-    }
-    
-    private static Folder ToSerializable(IReadOnlyFolderNode folder)
-    {
-        return new Folder
-        {
-            Name = folder.MemberName,
-            BlendMode = (BlendMode)(int)folder.BlendMode.Value,
-            Enabled = folder.IsVisible.Value,
-            Opacity = folder.Opacity.Value,
-            ClipToMemberBelow = folder.ClipToPreviousMember.Value,
-            Mask = GetMask(folder.Mask.Value, folder.MaskIsVisible.Value)
-        };
-    }
-    
-    private static ImageLayer ToSerializable(IReadOnlyLayerNode layer, IReadOnlyDocument document)
-    {
-        var result = document.GetLayerRasterizedImage(layer.Id, 0);
-
-        var tightBounds = document.GetChunkAlignedLayerBounds(layer.Id, 0);
-        using var data = result?.Encode();
-        byte[] bytes = data?.AsSpan().ToArray();
-        var serializable = new ImageLayer
-        {
-            Width = result?.Width ?? 0, Height = result?.Height ?? 0, OffsetX = tightBounds?.X ?? 0, OffsetY = tightBounds?.Y ?? 0,
-            Enabled = layer.IsVisible.Value, BlendMode = (BlendMode)(int)layer.BlendMode.Value, ImageBytes = bytes,
-            ClipToMemberBelow = layer.ClipToPreviousMember.Value, Name = layer.MemberName,
-            Guid = layer.Id,
-            LockAlpha = layer is ITransparencyLockable { LockTransparency: true },
-            Opacity = layer.Opacity.Value, Mask = GetMask(layer.Mask.Value, layer.MaskIsVisible.Value)
-        };
-
-        return serializable;
-    }
-
-    private static Mask GetMask(IReadOnlyChunkyImage mask, bool maskVisible)
-    {
-        if (mask == null) 
-            return null;
-        
-        var maskBound = mask.FindChunkAlignedMostUpToDateBounds();
-
-        if (maskBound == null)
-        {
-            return new Mask();
-        }
-        
-        var surface = DrawingBackendApi.Current.SurfaceImplementation.Create(new ImageInfo(
-            maskBound.Value.Width,
-            maskBound.Value.Height));
-                
-        mask.DrawMostUpToDateRegionOn(new RectI(0, 0, maskBound.Value.Width, maskBound.Value.Height), ChunkResolution.Full, surface, new VecI(0, 0));
-
-        return new Mask
-        {
-            Width = maskBound.Value.Width, Height = maskBound.Value.Height,
-            OffsetX = maskBound.Value.X, OffsetY = maskBound.Value.Y,
-            Enabled = maskVisible, ImageBytes = surface.Snapshot().Encode().AsSpan().ToArray()
-        };
-    }
-
     private ColorCollection ToCollection(IList<PaletteColor> collection) =>
         new(collection.Select(x => Color.FromArgb(255, x.R, x.G, x.B)));
 
-    private AnimationData ToAnimationData(IReadOnlyAnimationData animationData)
+    private AnimationData ToAnimationData(IReadOnlyAnimationData animationData, Dictionary<Guid, int> idMap)
     {
         var animData = new AnimationData();
         animData.KeyFrameGroups = new List<KeyFrameGroup>();
-        BuildKeyFrames(animationData.KeyFrames, animData);
-        
+        BuildKeyFrames(animationData.KeyFrames, animData, idMap);
+
         return animData;
     }
 
-    private static void BuildKeyFrames(IReadOnlyList<IReadOnlyKeyFrame> root, AnimationData animationData)
+    private static void BuildKeyFrames(IReadOnlyList<IReadOnlyKeyFrame> root, AnimationData animationData,
+        Dictionary<Guid, int> idMap)
     {
         foreach (var keyFrame in root)
         {
-            if(keyFrame is IKeyFrameChildrenContainer container)
+            if (keyFrame is IKeyFrameChildrenContainer container)
             {
                 KeyFrameGroup group = new();
-                group.LayerGuid = keyFrame.LayerGuid;
+                group.NodeId = idMap[keyFrame.NodeId];
                 group.Enabled = keyFrame.IsVisible;
-                
+
                 foreach (var child in container.Children)
                 {
                     if (child is IKeyFrameChildrenContainer groupKeyFrame)
                     {
-                        BuildKeyFrames(groupKeyFrame.Children, null);
+                        BuildKeyFrames(groupKeyFrame.Children, null, idMap);
                     }
                     else if (child is IReadOnlyRasterKeyFrame rasterKeyFrame)
                     {
-                        BuildRasterKeyFrame(rasterKeyFrame, group);
+                        BuildRasterKeyFrame(rasterKeyFrame, group, idMap);
                     }
                 }
-                
+
                 animationData?.KeyFrameGroups.Add(group);
             }
         }
     }
 
-    private static void BuildRasterKeyFrame(IReadOnlyRasterKeyFrame rasterKeyFrame, KeyFrameGroup group)
+    private static void BuildRasterKeyFrame(IReadOnlyRasterKeyFrame rasterKeyFrame, KeyFrameGroup group,
+        Dictionary<Guid, int> idMap)
     {
         var bounds = rasterKeyFrame.Image.FindChunkAlignedMostUpToDateBounds();
 
         DrawingSurface surface = null;
-                        
+
         if (bounds != null)
         {
             surface = DrawingBackendApi.Current.SurfaceImplementation.Create(
@@ -220,10 +240,9 @@ internal partial class DocumentViewModel
 
         group.Children.Add(new RasterKeyFrame()
         {
-            LayerGuid = rasterKeyFrame.LayerGuid,
+            NodeId = idMap[rasterKeyFrame.NodeId],
             StartFrame = rasterKeyFrame.StartFrame,
             Duration = rasterKeyFrame.Duration,
-            ImageBytes = surface?.Snapshot().Encode().AsSpan().ToArray(),
         });
     }
 }

+ 66 - 24
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.cs

@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System.Collections;
+using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Collections.ObjectModel;
 using System.IO;
@@ -33,13 +34,15 @@ using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.ChangeableDocument.ChangeInfos;
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Numerics;
+using PixiEditor.Parser;
+using PixiEditor.Parser.Skia;
 using Color = PixiEditor.DrawingApi.Core.ColorsImpl.Color;
 using Colors = PixiEditor.DrawingApi.Core.ColorsImpl.Colors;
 using Node = PixiEditor.Parser.Graph.Node;
@@ -246,7 +249,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
     {
         var builderInstance = new DocumentViewModelBuilder();
         builder(builderInstance);
-        
+
         Dictionary<int, Guid> mappedIds = new();
 
         var viewModel = new DocumentViewModel();
@@ -281,22 +284,65 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
             Guid outputNodeGuid = Guid.NewGuid();
             acc.AddActions(new CreateNode_Action(typeof(OutputNode), outputNodeGuid));
         }
-        
+
         AddAnimationData(builderInstance.AnimationData);
 
         acc.AddFinishedActions(new DeleteRecordedChanges_Action());
         viewModel.MarkAsSaved();
 
         return viewModel;
+        
+        
+        void AddNodes(NodeGraphBuilder graph)
+        {
+            foreach (var node in graph.AllNodes)
+            {
+                AddNode(node.Id, node);
+            }
+
+            foreach (var node in graph.AllNodes)
+            {
+                Guid nodeGuid = mappedIds[node.Id];
+                if (node.InputConnections != null)
+                {
+                    foreach (var connection in node.InputConnections)
+                    {
+                        if (mappedIds.TryGetValue(connection.Key, out Guid outputNodeId))
+                        {
+                            acc.AddActions(new ConnectProperties_Action(nodeGuid, outputNodeId,
+                                connection.Value.inputPropName, connection.Value.outputPropName));
+                        }
+                    }
+                }
+            }
+        }
 
-        void AddNode(int id, Node serializedNode)
+        void AddNode(int id, NodeGraphBuilder.NodeBuilder serializedNode)
         {
             Guid guid = Guid.NewGuid();
             mappedIds.Add(id, guid);
-            acc.AddActions(new CreateNode_Action(serializedNode.UniqueNodeName, guid)); 
+            acc.AddActions(new CreateNodeFromName_Action(serializedNode.UniqueNodeName, guid));
+
+            if (serializedNode.InputValues != null)
+            {
+                foreach (var propertyValue in serializedNode.InputValues)
+                {
+                    acc.AddActions(new UpdatePropertyValue_Action(guid, propertyValue.Key, propertyValue.Value));
+                }
+            }
+
+            if (serializedNode.AdditionalData != null && serializedNode.AdditionalData.Count > 0)
+            {
+                acc.AddActions(new DeserializeNodeAdditionalData_Action(guid, serializedNode.AdditionalData));
+            }
+
+            if (!string.IsNullOrEmpty(serializedNode.Name))
+            {
+                acc.AddActions(new SetNodeName_Action(guid, serializedNode.Name));
+            }
         }
 
-        void AddMember(Guid parentGuid, DocumentViewModelBuilder.StructureMemberBuilder member)
+        /*void AddMember(Guid parentGuid, DocumentViewModelBuilder.StructureMemberBuilder member)
         {
             acc.AddActions(
                 new CreateStructureMember_Action(parentGuid, member.Id,
@@ -346,18 +392,18 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
             {
                 AddMembers(member.Id, folder.Children);
             }
-        }
+        }*/
 
-        void PasteImage(Guid guid, DocumentViewModelBuilder.SurfaceBuilder surface, int width, int height, int offsetX,
+        /*void PasteImage(Guid guid, DocumentViewModelBuilder.SurfaceBuilder surface, int width, int height, int offsetX,
             int offsetY, bool onMask, int frame, Guid? keyFrameGuid = default)
         {
             acc.AddActions(
                 new PasteImage_Action(surface.Surface, new(new RectD(new VecD(offsetX, offsetY), new(width, height))),
                     guid, true, onMask, frame, keyFrameGuid ?? default),
                 new EndPasteImage_Action());
-        }
+        }*/
 
-        void AddMembers(Guid parentGuid, IEnumerable<DocumentViewModelBuilder.StructureMemberBuilder> builders)
+        /*void AddMembers(Guid parentGuid, IEnumerable<DocumentViewModelBuilder.StructureMemberBuilder> builders)
         {
             foreach (var child in builders.Reverse())
             {
@@ -368,7 +414,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
 
                 AddMember(parentGuid, child);
             }
-        }
+        }*/
 
         void AddAnimationData(List<KeyFrameBuilder> data)
         {
@@ -376,24 +422,20 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
             {
                 if (keyFrame is RasterKeyFrameBuilder rasterKeyFrameBuilder)
                 {
-                    if (rasterKeyFrameBuilder.Id == default)
-                    {
-                        rasterKeyFrameBuilder.Id = Guid.NewGuid();
-                    }
-
+                    Guid keyFrameGuid = Guid.NewGuid();
                     acc.AddActions(
                         new CreateRasterKeyFrame_Action(
-                            rasterKeyFrameBuilder.LayerGuid,
-                            rasterKeyFrameBuilder.Id,
+                            mappedIds[rasterKeyFrameBuilder.LayerId],
+                            keyFrameGuid,
                             rasterKeyFrameBuilder.StartFrame, -1, default),
-                        new KeyFrameLength_Action(rasterKeyFrameBuilder.Id, rasterKeyFrameBuilder.StartFrame,
+                        new KeyFrameLength_Action(keyFrameGuid, rasterKeyFrameBuilder.StartFrame,
                             rasterKeyFrameBuilder.Duration),
                         new EndKeyFrameLength_Action());
 
-                    PasteImage(rasterKeyFrameBuilder.LayerGuid, rasterKeyFrameBuilder.Surface,
+                    /*PasteImage(rasterKeyFrameBuilder.LayerGuid, rasterKeyFrameBuilder.Surface,
                         rasterKeyFrameBuilder.Surface.Surface.Size.X,
                         rasterKeyFrameBuilder.Surface.Surface.Size.Y, 0, 0, false, rasterKeyFrameBuilder.StartFrame,
-                        rasterKeyFrameBuilder.Id);
+                        rasterKeyFrameBuilder.Id);*/
 
                     acc.AddFinishedActions();
                 }

+ 2 - 2
src/PixiEditor.AvaloniaUI/ViewModels/Document/KeyFrameGroupViewModel.cs

@@ -12,7 +12,7 @@ internal class KeyFrameGroupViewModel : KeyFrameViewModel, IKeyFrameGroupHandler
     public override int StartFrameBindable => Children.Count > 0 ? Children.Min(x => x.StartFrameBindable) : 0;
     public override int DurationBindable => Children.Count > 0 ? Children.Max(x => x.StartFrameBindable + x.DurationBindable) - StartFrameBindable : 0;
 
-    public string LayerName => Document.StructureHelper.Find(LayerGuid).NameBindable;
+    public string LayerName => Document.StructureHelper.Find(LayerGuid).NodeNameBindable;
 
     public override void SetVisibility(bool isVisible)
     {
@@ -32,7 +32,7 @@ internal class KeyFrameGroupViewModel : KeyFrameViewModel, IKeyFrameGroupHandler
     {
         Document.StructureHelper.Find(LayerGuid).PropertyChanged += (sender, args) =>
         {
-            if (args.PropertyName == nameof(StructureMemberViewModel.NameBindable))
+            if (args.PropertyName == nameof(StructureMemberViewModel.NodeNameBindable))
             {
                 OnPropertyChanged(nameof(LayerName));
             }

+ 1 - 0
src/PixiEditor.AvaloniaUI/ViewModels/Document/KeyFrameViewModel.cs

@@ -3,6 +3,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
 using PixiEditor.AvaloniaUI.Models.DocumentModels;
 using PixiEditor.AvaloniaUI.Models.Handlers;
 using PixiEditor.ChangeableDocument.Actions.Generated;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.Document;
 

+ 2 - 2
src/PixiEditor.AvaloniaUI/ViewModels/Document/NodeGraphViewModel.cs

@@ -34,9 +34,9 @@ internal class NodeGraphViewModel : ViewModelBase, INodeGraphHandler
 
     public void AddNode(INodeHandler node)
     {
-        if (OutputNode == null)
+        if (OutputNode == null && node.InternalName == typeof(OutputNode).GetCustomAttribute<NodeInfoAttribute>().UniqueName)
         {
-            OutputNode = node; // TODO: this is not really correct yet, a way to check what node type is added is needed
+            OutputNode = node; 
         }
 
         AllNodes.Add(node);

+ 2 - 2
src/PixiEditor.AvaloniaUI/ViewModels/Document/ReferenceLayerViewModel.cs

@@ -11,9 +11,9 @@ using PixiEditor.AvaloniaUI.Models.DocumentModels;
 using PixiEditor.AvaloniaUI.Models.Handlers;
 using PixiEditor.AvaloniaUI.ViewModels.Tools.Tools;
 using PixiEditor.ChangeableDocument.Actions.Generated;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.Document;

+ 1 - 20
src/PixiEditor.AvaloniaUI/ViewModels/Document/StructureMemberViewModel.cs

@@ -9,8 +9,8 @@ using PixiEditor.AvaloniaUI.Models.Layers;
 using PixiEditor.AvaloniaUI.ViewModels.Nodes;
 using PixiEditor.AvaloniaUI.Views.Nodes;
 using PixiEditor.ChangeableDocument.Actions.Generated;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.Numerics;
 using BlendMode = PixiEditor.ChangeableDocument.Enums.BlendMode;
 
@@ -18,30 +18,11 @@ namespace PixiEditor.AvaloniaUI.ViewModels.Document;
 #nullable enable
 internal abstract class StructureMemberViewModel : NodeViewModel, IStructureMemberHandler
 {
-    private string name = "";
-
     public StructureMemberViewModel()
     {
         
     }
 
-    public virtual void SetName(string name)
-    {
-        this.name = name;
-        OnPropertyChanged(nameof(NameBindable));
-        NodeName = NameBindable;
-    }
-
-    public string NameBindable
-    {
-        get => name;
-        set
-        {
-            if (!Document.UpdateableChangeActive)
-                Internals.ActionAccumulator.AddFinishedActions(new StructureMemberName_Action(Id, value));
-        }
-    }
-
     private bool isVisible;
 
     public void SetIsVisible(bool isVisible)

+ 20 - 6
src/PixiEditor.AvaloniaUI/ViewModels/Nodes/NodeViewModel.cs

@@ -9,12 +9,13 @@ using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.Nodes;
 internal class NodeViewModel : ObservableObject, INodeHandler
 {
-    private string nodeName;
+    private string nodeNameBindable;
     private VecD position;
     private ObservableRangeCollection<INodePropertyHandler> inputs = new();
     private ObservableRangeCollection<INodePropertyHandler> outputs = new();
@@ -29,10 +30,17 @@ internal class NodeViewModel : ObservableObject, INodeHandler
         init => id = value;
     }
 
-    public string NodeName
+    public string NodeNameBindable
     {
-        get => nodeName;
-        set => SetProperty(ref nodeName, value);
+        get => nodeNameBindable;
+        set
+        {
+            if (!Document.UpdateableChangeActive)
+            {
+                Internals.ActionAccumulator.AddFinishedActions(
+                    new SetNodeName_Action(Id, value));
+            }
+        } 
     }
 
     public string InternalName { get; init; }
@@ -84,9 +92,9 @@ internal class NodeViewModel : ObservableObject, INodeHandler
         
     }
 
-    public NodeViewModel(string nodeName, Guid id, VecD position, DocumentViewModel document, DocumentInternalParts internals)
+    public NodeViewModel(string nodeNameBindable, Guid id, VecD position, DocumentViewModel document, DocumentInternalParts internals)
     {
-        this.nodeName = nodeName;
+        this.nodeNameBindable = nodeNameBindable;
         this.id = id;
         this.position = position;
         Document = document;
@@ -98,6 +106,12 @@ internal class NodeViewModel : ObservableObject, INodeHandler
         position = newPosition;
         OnPropertyChanged(nameof(PositionBindable));
     }
+    
+    public void SetName(string newName)
+    {
+        nodeNameBindable = newName;
+        OnPropertyChanged(nameof(NodeNameBindable));
+    }
 
     public void TraverseBackwards(Func<INodeHandler, bool> func)
     {

+ 0 - 2
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/AnimationsViewModel.cs

@@ -5,8 +5,6 @@ using PixiEditor.AvaloniaUI.Models.Commands.Attributes.Commands;
 using PixiEditor.AvaloniaUI.Models.IO;
 using PixiEditor.AvaloniaUI.ViewModels.Dock;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.SubViewModels;

+ 26 - 12
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/FileViewModel.cs

@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Reflection;
 using System.Threading.Tasks;
 using Avalonia;
 using Avalonia.Controls;
@@ -19,6 +20,9 @@ using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.AvaloniaUI.Views;
 using PixiEditor.AvaloniaUI.Views.Dialogs;
 using PixiEditor.AvaloniaUI.Views.Windows;
+using PixiEditor.ChangeableDocument.Changeables.Graph;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.CommonApi.UserPreferences.Settings.PixiEditor;
@@ -26,6 +30,7 @@ using PixiEditor.Extensions.Exceptions;
 using PixiEditor.Numerics;
 using PixiEditor.OperatingSystem;
 using PixiEditor.Parser;
+using PixiEditor.Parser.Graph;
 using PixiEditor.UI.Common.Fonts;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.SubViewModels;
@@ -243,10 +248,12 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
 
         var doc = NewDocument(b => b
             .WithSize(image.Size)
-            .WithLayer(l => l
-                .WithName("Image")
-                .WithSize(image.Size)
-                .WithSurface(image)));
+            .WithGraph(x => x
+                .WithImageLayerNode(
+                    new LocalizedString("PASTED_IMAGE_NAME"),
+                    image, out int id)
+                .WithOutputNode(id, "Output")
+            ));
 
         if (associatePath)
         {
@@ -256,6 +263,7 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
         AddRecentlyOpened(path);
     }
 
+
     /// <summary>
     /// Opens a regular image file from path, creates a document from it, and adds it to the system.
     /// </summary>
@@ -263,10 +271,12 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
     {
         DocumentViewModel doc = NewDocument(b => b
             .WithSize(surface.Size)
-            .WithLayer(l => l
-                .WithName("Image")
-                .WithSize(surface.Size)
-                .WithSurface(surface)));
+            .WithGraph(x => x
+                .WithImageLayerNode(
+                    new LocalizedString("PASTED_IMAGE_NAME"),
+                    surface, out int id)
+                .WithOutputNode(id, "Output")
+            ));
 
         if (path == null)
         {
@@ -289,9 +299,12 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
         {
             NewDocument(b => b
                 .WithSize(newFile.Width, newFile.Height)
-                .WithLayer(l => l
-                    .WithName(new LocalizedString("BASE_LAYER_NAME"))
-                    .WithSurface(new Surface(new VecI(newFile.Width, newFile.Height)))));
+                .WithGraph(x => x
+                    .WithImageLayerNode(
+                        new LocalizedString("BASE_LAYER_NAME"),
+                        new Surface(new VecI(newFile.Width, newFile.Height)), out int id)
+                    .WithOutputNode(id, "Output")
+                ));
         }
     }
 
@@ -378,7 +391,8 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
             };
             if (await info.ShowDialog())
             {
-                var result = await Exporter.TrySaveUsingDataFromDialog(doc, info.FilePath, info.ChosenFormat, info.ExportConfig);
+                var result =
+                    await Exporter.TrySaveUsingDataFromDialog(doc, info.FilePath, info.ChosenFormat, info.ExportConfig);
                 if (result.result == SaveResult.Success)
                     IOperatingSystem.Current.OpenFolder(result.finalPath);
                 else

+ 1 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Tools/Tools/MoveToolViewModel.cs

@@ -7,7 +7,7 @@ using PixiEditor.AvaloniaUI.Models.Handlers.Tools;
 using PixiEditor.AvaloniaUI.ViewModels.Tools.ToolSettings.Toolbars;
 using PixiEditor.AvaloniaUI.Views.Overlays.BrushShapeOverlay;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Numerics;
 using PixiEditor.UI.Common.Fonts;

+ 2 - 1
src/PixiEditor.AvaloniaUI/Views/Dialogs/ExportFilePopup.axaml.cs

@@ -10,9 +10,10 @@ using PixiEditor.AvaloniaUI.Helpers;
 using PixiEditor.AvaloniaUI.Models.Files;
 using PixiEditor.AvaloniaUI.Models.IO;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Numerics;
-using Image = PixiEditor.DrawingApi.Core.Surface.ImageData.Image;
+using Image = PixiEditor.DrawingApi.Core.Surfaces.ImageData.Image;
 
 namespace PixiEditor.AvaloniaUI.Views.Dialogs;
 

+ 1 - 1
src/PixiEditor.AvaloniaUI/Views/Layers/FolderControl.axaml

@@ -101,7 +101,7 @@
                                 x:Name="editableTextBlock"
                                 d:Text="New Folder" FontSize="14"
                                 VerticalAlignment="Center"
-                                Text="{Binding Folder.NameBindable, ElementName=folderControl, Mode=TwoWay}" />
+                                Text="{Binding Folder.NodeNameBindable, ElementName=folderControl, Mode=TwoWay}" />
                             
                             <StackPanel Orientation="Horizontal">
                                 <TextBlock d:Text="100" Foreground="White" FontSize="11">

+ 1 - 1
src/PixiEditor.AvaloniaUI/Views/Layers/LayerControl.axaml

@@ -112,7 +112,7 @@
                             x:Name="editableTextBlock"
                             VerticalAlignment="Center"
                             d:Text="New Layer" FontSize="14"
-                            Text="{Binding Layer.NameBindable, ElementName=uc, Mode=TwoWay}" />
+                            Text="{Binding Layer.NodeNameBindable, ElementName=uc, Mode=TwoWay}" />
 
                         <StackPanel Orientation="Horizontal">
                             <TextBlock d:Text="100" Foreground="White" FontSize="11">

+ 1 - 0
src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/FixedViewport.axaml.cs

@@ -10,6 +10,7 @@ using ChunkyImageLib.DataHolders;
 using PixiEditor.AvaloniaUI.Models.DocumentModels;
 using PixiEditor.AvaloniaUI.Models.Position;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Numerics;
 

+ 1 - 0
src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/Viewport.axaml.cs

@@ -17,6 +17,7 @@ using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.AvaloniaUI.Views.Overlays;
 using PixiEditor.AvaloniaUI.Views.Rendering;
 using PixiEditor.AvaloniaUI.Views.Visuals;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Numerics;
 using PixiEditor.Zoombox;

+ 1 - 0
src/PixiEditor.AvaloniaUI/Views/Nodes/NodeView.cs

@@ -12,6 +12,7 @@ using PixiEditor.AvaloniaUI.Models.Handlers;
 using PixiEditor.AvaloniaUI.Models.Structures;
 using PixiEditor.AvaloniaUI.ViewModels.Nodes;
 using PixiEditor.AvaloniaUI.Views.Nodes.Properties;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.AvaloniaUI.Views.Nodes;
 

+ 1 - 1
src/PixiEditor.AvaloniaUI/Views/Overlays/SelectionOverlay/SelectionOverlay.cs

@@ -6,7 +6,7 @@ using Avalonia.Media;
 using Avalonia.Styling;
 using PixiEditor.AvaloniaUI.Animation;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Views.Overlays.SelectionOverlay;

+ 3 - 2
src/PixiEditor.AvaloniaUI/Views/Rendering/Scene.cs

@@ -19,12 +19,13 @@ using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.AvaloniaUI.Views.Overlays;
 using PixiEditor.AvaloniaUI.Views.Overlays.Pointers;
 using PixiEditor.AvaloniaUI.Views.Visuals;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Skia;
 using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Numerics;
-using Bitmap = PixiEditor.DrawingApi.Core.Surface.Bitmap;
-using Image = PixiEditor.DrawingApi.Core.Surface.ImageData.Image;
+using Bitmap = PixiEditor.DrawingApi.Core.Surfaces.Bitmap;
+using Image = PixiEditor.DrawingApi.Core.Surfaces.ImageData.Image;
 using Point = Avalonia.Point;
 
 namespace PixiEditor.AvaloniaUI.Views.Rendering;

+ 1 - 0
src/PixiEditor.AvaloniaUI/Views/Visuals/SurfaceControl.cs

@@ -8,6 +8,7 @@ using Avalonia.Rendering.SceneGraph;
 using Avalonia.Skia;
 using Avalonia.Threading;
 using ChunkyImageLib;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Numerics;
 

+ 1 - 0
src/PixiEditor.AvaloniaUI/Views/Visuals/SurfaceImage.cs

@@ -1,6 +1,7 @@
 using Avalonia;
 using Avalonia.Media;
 using ChunkyImageLib;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.AvaloniaUI.Views.Visuals;
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/ChangeInfos/Drawing/Selection_ChangeInfo.cs

@@ -1,4 +1,4 @@
-using PixiEditor.DrawingApi.Core.Surface.Vector;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 
 namespace PixiEditor.ChangeableDocument.ChangeInfos.Drawing;
 

+ 9 - 1
src/PixiEditor.ChangeableDocument/ChangeInfos/NodeGraph/CreateNode_ChangeInfo.cs

@@ -1,5 +1,6 @@
 using System.Collections;
 using System.Collections.Immutable;
+using System.Reflection;
 using PixiEditor.ChangeableDocument.Changeables.Graph;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
@@ -36,8 +37,15 @@ public record CreateNode_ChangeInfo(
                     return CreateFolder_ChangeInfo.FromFolder(folderNode);
             }
         }
+
+        string internalName = node.GetType().GetCustomAttribute<NodeInfoAttribute>()?.UniqueName;
+
+        if (string.IsNullOrEmpty(internalName))
+        {
+            throw new ArgumentException("Node does not have a unique name attribute. Please add [NodeInfo(\"UNIQUE_NAME\")] to the node class.");
+        }
         
-        return new CreateNode_ChangeInfo(node.InternalName, node.DisplayName, node.Position,
+        return new CreateNode_ChangeInfo(internalName, node.DisplayName, node.Position,
             node.Id,
             CreatePropertyInfos(node.InputProperties, true, node.Id), CreatePropertyInfos(node.OutputProperties, false, node.Id));
     }

+ 3 - 0
src/PixiEditor.ChangeableDocument/ChangeInfos/NodeGraph/NodeName_ChangeInfo.cs

@@ -0,0 +1,3 @@
+namespace PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
+
+public record NodeName_ChangeInfo(Guid NodeId, string NewName) : IChangeInfo;

+ 1 - 1
src/PixiEditor.ChangeableDocument/ChangeInfos/Structure/CreateFolder_ChangeInfo.cs

@@ -27,7 +27,7 @@ public record class CreateFolder_ChangeInfo : CreateStructureMember_ChangeInfo
     internal static CreateFolder_ChangeInfo FromFolder(FolderNode folder)
     {
         return new CreateFolder_ChangeInfo(
-            folder.InternalName,
+            folder.GetNodeTypeUniqueName(),
             folder.Opacity.Value,
             folder.IsVisible.Value,
             folder.ClipToPreviousMember.Value,

+ 1 - 1
src/PixiEditor.ChangeableDocument/ChangeInfos/Structure/CreateLayer_ChangeInfo.cs

@@ -33,7 +33,7 @@ public record class CreateLayer_ChangeInfo : CreateStructureMember_ChangeInfo
     internal static CreateLayer_ChangeInfo FromLayer(LayerNode layer)
     {
         return new CreateLayer_ChangeInfo(
-            layer.InternalName,
+            layer.GetNodeTypeUniqueName(),
             layer.Opacity.Value,
             layer.IsVisible.Value,
             layer.ClipToPreviousMember.Value,

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Animations/AnimationData.cs

@@ -17,7 +17,7 @@ internal class AnimationData : IReadOnlyAnimationData
 
     public void AddKeyFrame(KeyFrame keyFrame)
     {
-        Guid id = keyFrame.LayerGuid;
+        Guid id = keyFrame.NodeId;
         if (TryFindKeyFrameCallback(id, out GroupKeyFrame group))
         {
             group.Children.Add(keyFrame);
@@ -35,7 +35,7 @@ internal class AnimationData : IReadOnlyAnimationData
     {
         TryFindKeyFrameCallback<KeyFrame>(createdKeyFrameId, out _, (frame, parent) =>
         {
-            if (document.TryFindNode<Node>(frame.LayerGuid, out Node? node))
+            if (document.TryFindNode<Node>(frame.NodeId, out Node? node))
             {
                 node.RemoveKeyFrame(frame.Id);
             }

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Animations/KeyFrame.cs

@@ -42,7 +42,7 @@ public abstract class KeyFrame : IReadOnlyKeyFrame
     
     public int EndFrame => StartFrame + Duration;
     
-    public Guid LayerGuid { get; }
+    public Guid NodeId { get; }
     public Guid Id { get; set; }
 
     public bool IsVisible
@@ -61,7 +61,7 @@ public abstract class KeyFrame : IReadOnlyKeyFrame
     protected KeyFrame(Node node, int startFrame)
     {
         TargetNode = node;
-        LayerGuid = node.Id;
+        NodeId = node.Id;
         this.startFrame = startFrame;
         duration = 1;
         Id = Guid.NewGuid();

+ 3 - 1
src/PixiEditor.ChangeableDocument/Changeables/Animations/KeyFrameData.cs

@@ -5,7 +5,7 @@ public abstract class KeyFrameData : IDisposable
     public int StartFrame { get; set; }
     public int Duration { get; set; }
     public Guid KeyFrameGuid { get; }
-
+    
     public abstract bool RequiresUpdate { get; set; }
 
     public KeyFrameData(Guid keyFrameGuid, int startFrame, int duration)
@@ -21,6 +21,8 @@ public abstract class KeyFrameData : IDisposable
     }
 
     public abstract void Dispose();
+
+    public abstract object ToSerializable();
 }
 
 public abstract class KeyFrameData<T> : KeyFrameData

+ 3 - 2
src/PixiEditor.ChangeableDocument/Changeables/Document.cs

@@ -5,9 +5,10 @@ using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core.Surfaces.ImageData;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changeables;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Context/NoNodeFuncContextException.cs

@@ -1,4 +1,4 @@
-namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Context;
 
 public class NoNodeFuncContextException : Exception
 {

+ 1 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/InputProperty.cs

@@ -1,5 +1,4 @@
-using System.Reflection;
-using PixiEditor.ChangeableDocument.Changeables.Graph.Context;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Context;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.ChangeableDocument.Changes.NodeGraph;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IBackgroundInput.cs

@@ -1,5 +1,5 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 

+ 2 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyFolderNode.cs

@@ -1,4 +1,5 @@
-using PixiEditor.Numerics;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyImageNode.cs

@@ -1,6 +1,6 @@
-using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 
-namespace PixiEditor.ChangeableDocument.Changeables.Interfaces;
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 
 public interface IReadOnlyImageNode : IReadOnlyLayerNode, ITransparencyLockable
 {

+ 5 - 5
src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyNode.cs

@@ -1,6 +1,6 @@
 using PixiEditor.ChangeableDocument.Changeables.Animations;
 using PixiEditor.ChangeableDocument.Rendering;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
@@ -8,12 +8,10 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 public interface IReadOnlyNode
 {
     public Guid Id { get; }
-    public IReadOnlyCollection<IInputProperty> InputProperties { get; }
-    public IReadOnlyCollection<IOutputProperty> OutputProperties { get; }
+    public IReadOnlyList<IInputProperty> InputProperties { get; }
+    public IReadOnlyList<IOutputProperty> OutputProperties { get; }
     public VecD Position { get; }
     public Surface? CachedResult { get; }
-    
-    public string InternalName { get; }
     string DisplayName { get; }
 
     public Surface? Execute(RenderingContext context);
@@ -39,4 +37,6 @@ public interface IReadOnlyNode
     
     public IInputProperty? GetInputProperty(string internalName);
     public IOutputProperty? GetOutputProperty(string internalName);
+    public void SerializeAdditionalData(Dictionary<string,object> additionalData);
+    public string GetNodeTypeUniqueName();
 }

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyNodeGraph.cs

@@ -1,5 +1,5 @@
 using PixiEditor.ChangeableDocument.Rendering;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/NodeGraph.cs

@@ -3,7 +3,7 @@ using System.Diagnostics;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.ChangeableDocument.Rendering;
-using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph;
 

+ 17 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/NodeInfoAttribute.cs

@@ -0,0 +1,17 @@
+namespace PixiEditor.ChangeableDocument.Changeables.Graph;
+
+[AttributeUsage(AttributeTargets.Class)]
+public class NodeInfoAttribute : Attribute
+{
+    public string UniqueName { get; }
+
+    public NodeInfoAttribute(string uniqueName)
+    {
+        if (!uniqueName.StartsWith("PixiEditor"))
+        {
+            uniqueName = $"PixiEditor.{uniqueName}";
+        }
+        
+        UniqueName = uniqueName;
+    }
+}

+ 2 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Animable/TimeNode.cs

@@ -1,10 +1,11 @@
 using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Animable;
 
+[NodeInfo("Time")]
 public class TimeNode : Node
 {
-    protected override string NodeUniqueName { get; } = "Time";
     public override string DisplayName { get; set; } = "TIME_NODE";
     
     public OutputProperty<int> ActiveFrame { get; set; }

+ 4 - 4
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineChannelsNode.cs

@@ -1,10 +1,12 @@
 using PixiEditor.ChangeableDocument.Rendering;
-using PixiEditor.DrawingApi.Core.Surface;
-using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
 
+[NodeInfo("CombineChannels")]
 public class CombineChannelsNode : Node
 {
     private readonly Paint _screenPaint = new() { BlendMode = BlendMode.Screen };
@@ -38,8 +40,6 @@ public class CombineChannelsNode : Node
         Grayscale = CreateInput(nameof(Grayscale), "GRAYSCALE", false);
     }
 
-    protected override string NodeUniqueName => "CombineChannels";
-
     protected override Surface? OnExecute(RenderingContext context)
     {
         var size = GetSize();

+ 2 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineColorNode.cs

@@ -1,9 +1,11 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Context;
 using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
 
+[NodeInfo("CombineColor")]
 public class CombineColorNode : Node
 {
     public FuncOutputProperty<Color> Color { get; }
@@ -38,7 +40,6 @@ public class CombineColorNode : Node
         return new Color((byte)r, (byte)g, (byte)b, (byte)a);
     }
 
-    protected override string NodeUniqueName => "CombineColor";
 
     protected override Surface? OnExecute(RenderingContext context)
     {

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineVecD.cs

@@ -1,10 +1,12 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Context;
 using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.CombineSeparate;
 
+[NodeInfo("CombineVecD")]
 public class CombineVecD : Node
 {
     public FuncOutputProperty<VecD> Vector { get; }
@@ -32,8 +34,6 @@ public class CombineVecD : Node
         return new VecD(r, g);
     }
 
-    protected override string NodeUniqueName => "CombineVecD";
-
     protected override Surface? OnExecute(RenderingContext context)
     {
         return null;

Неке датотеке нису приказане због велике количине промена