Browse Source

Serialization and deserialization works

flabbet 1 year ago
parent
commit
d531f8beb8

+ 15 - 36
src/PixiEditor.AvaloniaUI/Helpers/DocumentViewModelBuilder.cs

@@ -125,21 +125,12 @@ internal class DocumentViewModelBuilder
                 .WithVisibility(group.Enabled)
                 .WithVisibility(group.Enabled)
                 .WithNodeId(group.NodeId);
                 .WithNodeId(group.NodeId);
 
 
-            foreach (var child in group.ChildrenIds)
+            foreach (var child in group.Children)
             {
             {
-                /*if (child is KeyFrameGroup childGroup)
-                {
-                    builder.WithChild<GroupKeyFrameBuilder>(x =>
-                        BuildKeyFrames(childGroup.Children, null));
-                }*/
-                /*else if (child is RasterKeyFrame rasterKeyFrame)
-                {
-                    builder.WithChild<RasterKeyFrameBuilder>(x => x
-                        .WithVisibility(builder.IsVisible)
-                        .WithLayerGuid(rasterKeyFrame.NodeId)
-                        .WithStartFrame(rasterKeyFrame.StartFrame)
-                        .WithDuration(rasterKeyFrame.Duration));
-                }*/
+                builder.WithChild<KeyFrameBuilder>(x => x
+                    .WithVisibility(child.IsEnabled)
+                    .WithKeyFrameId(child.KeyFrameId)
+                    .WithNodeId(child.NodeId));
             }
             }
 
 
             data?.Add(builder);
             data?.Add(builder);
@@ -202,32 +193,25 @@ internal class DocumentViewModelBuilder
 
 
 internal class KeyFrameBuilder()
 internal class KeyFrameBuilder()
 {
 {
-    public int StartFrame { get; set; }
-    public int Duration { get; set; }
     public bool IsVisible { get; set; }
     public bool IsVisible { get; set; }
-    public int LayerId { get; set; }
+    public int NodeId { get; set; }
+    public int KeyFrameId { get; set; }
 
 
-    public KeyFrameBuilder WithStartFrame(int startFrame)
-    {
-        StartFrame = startFrame;
-        return this;
-    }
-
-    public KeyFrameBuilder WithDuration(int duration)
+    public KeyFrameBuilder WithVisibility(bool isVisible)
     {
     {
-        Duration = duration;
+        IsVisible = isVisible;
         return this;
         return this;
     }
     }
 
 
-    public KeyFrameBuilder WithVisibility(bool isVisible)
+    public KeyFrameBuilder WithKeyFrameId(int layerId)
     {
     {
-        IsVisible = isVisible;
+        KeyFrameId = layerId;
         return this;
         return this;
     }
     }
 
 
-    public KeyFrameBuilder WithLayerGuid(int layerGuid)
+    public KeyFrameBuilder WithNodeId(int nodeId)
     {
     {
-        LayerId = layerGuid;
+        NodeId = nodeId;
         return this;
         return this;
     }
     }
 }
 }
@@ -248,12 +232,7 @@ internal class GroupKeyFrameBuilder : KeyFrameBuilder
         base.WithVisibility(isVisible) as GroupKeyFrameBuilder;
         base.WithVisibility(isVisible) as GroupKeyFrameBuilder;
 
 
     public new GroupKeyFrameBuilder WithNodeId(int layerGuid) =>
     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;
+        base.WithKeyFrameId(layerGuid) as GroupKeyFrameBuilder;
 }
 }
 
 
 internal class NodeGraphBuilder
 internal class NodeGraphBuilder
@@ -377,7 +356,7 @@ internal class NodeGraphBuilder
         public NodeBuilder WithKeyFrames(KeyFrameData[] keyFrames)
         public NodeBuilder WithKeyFrames(KeyFrameData[] keyFrames)
         {
         {
             KeyFrames = keyFrames;
             KeyFrames = keyFrames;
-            return this;   
+            return this;
         }
         }
     }
     }
 }
 }

+ 3 - 3
src/PixiEditor.AvaloniaUI/Helpers/Extensions/PixiParserV3DocumentEx.cs

@@ -357,12 +357,12 @@ internal static class PixiParserV3DocumentEx
             base.WithVisibility(isVisible) as RasterKeyFrameBuilder;
             base.WithVisibility(isVisible) as RasterKeyFrameBuilder;
 
 
         public new RasterKeyFrameBuilder WithLayerGuid(int layerId) =>
         public new RasterKeyFrameBuilder WithLayerGuid(int layerId) =>
-            base.WithLayerGuid(layerId) as RasterKeyFrameBuilder;
+            base.WithKeyFrameId(layerId) as RasterKeyFrameBuilder;
 
 
-        public new RasterKeyFrameBuilder WithStartFrame(int startFrame) =>
+        /*public new RasterKeyFrameBuilder WithStartFrame(int startFrame) =>
             base.WithStartFrame(startFrame) as RasterKeyFrameBuilder;
             base.WithStartFrame(startFrame) as RasterKeyFrameBuilder;
 
 
         public new RasterKeyFrameBuilder WithDuration(int duration) =>
         public new RasterKeyFrameBuilder WithDuration(int duration) =>
-            base.WithDuration(duration) as RasterKeyFrameBuilder;
+            base.WithDuration(duration) as RasterKeyFrameBuilder;*/
     }
     }
 }
 }

+ 12 - 16
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.Serialization.cs

@@ -55,7 +55,7 @@ internal partial class DocumentViewModel
             PreviewImage =
             PreviewImage =
                 (TryRenderWholeImage(0).Value as Surface)?.DrawingSurface.Snapshot().Encode().AsSpan().ToArray(),
                 (TryRenderWholeImage(0).Value as Surface)?.DrawingSurface.Snapshot().Encode().AsSpan().ToArray(),
             ReferenceLayer = GetReferenceLayer(doc),
             ReferenceLayer = GetReferenceLayer(doc),
-            AnimationData = ToAnimationData(doc.AnimationData, nodeIdMap),
+            AnimationData = ToAnimationData(doc.AnimationData, nodeIdMap, keyFrameIdMap),
             ImageEncoderUsed = encoder.EncodedFormatName
             ImageEncoderUsed = encoder.EncodedFormatName
         };
         };
 
 
@@ -210,35 +210,31 @@ internal partial class DocumentViewModel
     private ColorCollection ToCollection(IList<PaletteColor> collection) =>
     private ColorCollection ToCollection(IList<PaletteColor> collection) =>
         new(collection.Select(x => Color.FromArgb(255, x.R, x.G, x.B)));
         new(collection.Select(x => Color.FromArgb(255, x.R, x.G, x.B)));
 
 
-    private AnimationData ToAnimationData(IReadOnlyAnimationData animationData, Dictionary<Guid, int> idMap)
+    private AnimationData ToAnimationData(IReadOnlyAnimationData animationData, Dictionary<Guid, int> nodeIdMap, Dictionary<Guid, int> keyFrameIds)
     {
     {
         var animData = new AnimationData();
         var animData = new AnimationData();
         animData.KeyFrameGroups = new List<KeyFrameGroup>();
         animData.KeyFrameGroups = new List<KeyFrameGroup>();
-        BuildKeyFrames(animationData.KeyFrames, animData, idMap);
+        BuildKeyFrames(animationData.KeyFrames, animData, nodeIdMap, keyFrameIds);
 
 
         return animData;
         return animData;
     }
     }
 
 
     private static void BuildKeyFrames(IReadOnlyList<IReadOnlyKeyFrame> root, AnimationData animationData,
     private static void BuildKeyFrames(IReadOnlyList<IReadOnlyKeyFrame> root, AnimationData animationData,
-        Dictionary<Guid, int> idMap)
+        Dictionary<Guid, int> nodeIdMap, Dictionary<Guid, int> keyFrameIds)
     {
     {
         foreach (var keyFrame in root)
         foreach (var keyFrame in root)
         {
         {
             if (keyFrame is IKeyFrameChildrenContainer container)
             if (keyFrame is IKeyFrameChildrenContainer container)
             {
             {
                 KeyFrameGroup group = new();
                 KeyFrameGroup group = new();
-                group.NodeId = idMap[keyFrame.NodeId];
+                group.NodeId = nodeIdMap[keyFrame.NodeId];
                 group.Enabled = keyFrame.IsVisible;
                 group.Enabled = keyFrame.IsVisible;
 
 
                 foreach (var child in container.Children)
                 foreach (var child in container.Children)
                 {
                 {
-                    if (child is IKeyFrameChildrenContainer groupKeyFrame)
+                    if (child is IReadOnlyRasterKeyFrame rasterKeyFrame)
                     {
                     {
-                        BuildKeyFrames(groupKeyFrame.Children, null, idMap);
-                    }
-                    else if (child is IReadOnlyRasterKeyFrame rasterKeyFrame)
-                    {
-                        BuildRasterKeyFrame(rasterKeyFrame, group, idMap);
+                        BuildRasterKeyFrame(rasterKeyFrame, group, nodeIdMap, keyFrameIds);
                     }
                     }
                 }
                 }
 
 
@@ -248,7 +244,7 @@ internal partial class DocumentViewModel
     }
     }
 
 
     private static void BuildRasterKeyFrame(IReadOnlyRasterKeyFrame rasterKeyFrame, KeyFrameGroup group,
     private static void BuildRasterKeyFrame(IReadOnlyRasterKeyFrame rasterKeyFrame, KeyFrameGroup group,
-        Dictionary<Guid, int> idMap)
+        Dictionary<Guid, int> idMap, Dictionary<Guid, int> keyFrameIds)
     {
     {
         var bounds = rasterKeyFrame.Image.FindChunkAlignedMostUpToDateBounds();
         var bounds = rasterKeyFrame.Image.FindChunkAlignedMostUpToDateBounds();
 
 
@@ -264,11 +260,11 @@ internal partial class DocumentViewModel
                 new VecI(0, 0));
                 new VecI(0, 0));
         }
         }
 
 
-        /*group.Children.Add(new RasterKeyFrame()
+        group.Children.Add(new ElementKeyFrame()
         {
         {
             NodeId = idMap[rasterKeyFrame.NodeId],
             NodeId = idMap[rasterKeyFrame.NodeId],
-            StartFrame = rasterKeyFrame.StartFrame,
-            Duration = rasterKeyFrame.Duration,
-        });*/
+            KeyFrameId = keyFrameIds[rasterKeyFrame.Id],
+            IsEnabled = rasterKeyFrame.IsVisible
+        });
     }
     }
 }
 }

+ 12 - 16
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.cs

@@ -296,7 +296,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
             acc.AddActions(new CreateNode_Action(typeof(OutputNode), outputNodeGuid));
             acc.AddActions(new CreateNode_Action(typeof(OutputNode), outputNodeGuid));
         }
         }
 
 
-        AddAnimationData(builderInstance.AnimationData);
+        AddAnimationData(builderInstance.AnimationData, mappedNodeIds, mappedKeyFrameIds);
 
 
         acc.AddFinishedActions(new DeleteRecordedChanges_Action());
         acc.AddFinishedActions(new DeleteRecordedChanges_Action());
         viewModel.MarkAsSaved();
         viewModel.MarkAsSaved();
@@ -441,29 +441,25 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
             }
             }
         }*/
         }*/
 
 
-        void AddAnimationData(List<KeyFrameBuilder> data)
+        void AddAnimationData(List<KeyFrameBuilder> data, Dictionary<int, Guid> mappedIds, 
+            Dictionary<int, Guid> mappedKeyFrameIds)
         {
         {
             foreach (var keyFrame in data)
             foreach (var keyFrame in data)
             {
             {
-                /*if (keyFrame is RasterKeyFrameBuilder rasterKeyFrameBuilder)
+                if (keyFrame is GroupKeyFrameBuilder groupKeyFrameBuilder)
+                {
+                    AddAnimationData(groupKeyFrameBuilder.Children, mappedIds, mappedKeyFrameIds);
+                }
+                else
                 {
                 {
-                    Guid keyFrameGuid = Guid.NewGuid();
                     acc.AddActions(
                     acc.AddActions(
                         new CreateRasterKeyFrame_Action(
                         new CreateRasterKeyFrame_Action(
-                            mappedIds[rasterKeyFrameBuilder.LayerId],
-                            keyFrameGuid,
-                            rasterKeyFrameBuilder.StartFrame, -1, default),
-                        new KeyFrameLength_Action(keyFrameGuid, rasterKeyFrameBuilder.StartFrame,
-                            rasterKeyFrameBuilder.Duration),
-                        new EndKeyFrameLength_Action());
-
+                            mappedIds[keyFrame.NodeId],
+                            mappedKeyFrameIds[keyFrame.KeyFrameId],
+                            -1, -1, default));
+                    
                     acc.AddFinishedActions();
                     acc.AddFinishedActions();
                 }
                 }
-                else */
-                if (keyFrame is GroupKeyFrameBuilder groupKeyFrameBuilder)
-                {
-                    AddAnimationData(groupKeyFrameBuilder.Children);
-                }
             }
             }
         }
         }
     }
     }

+ 17 - 6
src/PixiEditor.ChangeableDocument/Changes/Animation/CreateRasterKeyFrame_Change.cs

@@ -7,7 +7,7 @@ namespace PixiEditor.ChangeableDocument.Changes.Animation;
 internal class CreateRasterKeyFrame_Change : Change
 internal class CreateRasterKeyFrame_Change : Change
 {
 {
     private readonly Guid _targetLayerGuid;
     private readonly Guid _targetLayerGuid;
-    private readonly int _frame;
+    private int _frame;
     private readonly Guid? cloneFrom;
     private readonly Guid? cloneFrom;
     private int? cloneFromFrame;
     private int? cloneFromFrame;
     private ImageLayerNode? _layer;
     private ImageLayerNode? _layer;
@@ -36,15 +36,26 @@ internal class CreateRasterKeyFrame_Change : Change
         var cloneFromImage = cloneFrom.HasValue
         var cloneFromImage = cloneFrom.HasValue
             ? target.FindMemberOrThrow<ImageLayerNode>(cloneFrom.Value).GetLayerImageAtFrame(cloneFromFrame ?? 0)
             ? target.FindMemberOrThrow<ImageLayerNode>(cloneFrom.Value).GetLayerImageAtFrame(cloneFromFrame ?? 0)
             : null;
             : null;
-        
+
         ImageLayerNode targetNode = target.FindMemberOrThrow<ImageLayerNode>(_targetLayerGuid);
         ImageLayerNode targetNode = target.FindMemberOrThrow<ImageLayerNode>(_targetLayerGuid);
-        
+
         ChunkyImage img = cloneFromImage?.CloneFromCommitted() ?? new ChunkyImage(target.Size);
         ChunkyImage img = cloneFromImage?.CloneFromCommitted() ?? new ChunkyImage(target.Size);
-        
+
         var keyFrame =
         var keyFrame =
             new RasterKeyFrame(createdKeyFrameId, targetNode, _frame, target, img);
             new RasterKeyFrame(createdKeyFrameId, targetNode, _frame, target, img);
-        
-        targetNode.AddFrame(createdKeyFrameId, new KeyFrameData(createdKeyFrameId, _frame, 1, ImageLayerNode.ImageLayerKey) { Data = img });
+
+        var existingData = targetNode.KeyFrames.FirstOrDefault(x => x.KeyFrameGuid == createdKeyFrameId);
+
+        if (existingData is null)
+        {
+            targetNode.AddFrame(createdKeyFrameId,
+                new KeyFrameData(createdKeyFrameId, _frame, 1, ImageLayerNode.ImageLayerKey) { Data = img });
+        }
+        else
+        {
+            _frame = existingData.StartFrame;
+        }
+
         target.AnimationData.AddKeyFrame(keyFrame);
         target.AnimationData.AddKeyFrame(keyFrame);
         ignoreInUndo = false;
         ignoreInUndo = false;
         return new CreateRasterKeyFrame_ChangeInfo(_targetLayerGuid, _frame, createdKeyFrameId, cloneFrom.HasValue);
         return new CreateRasterKeyFrame_ChangeInfo(_targetLayerGuid, _frame, createdKeyFrameId, cloneFrom.HasValue);

+ 22 - 23
src/PixiEditor.ChangeableDocument/Changes/NodeGraph/SetKeyFrameData_Change.cs

@@ -11,9 +11,10 @@ internal class SetKeyFrameData_Change : Change
     private int startFrame;
     private int startFrame;
     private int duration;
     private int duration;
     private string affectedElement;
     private string affectedElement;
-    
+
     [GenerateMakeChangeAction]
     [GenerateMakeChangeAction]
-    public SetKeyFrameData_Change(Guid nodeId, Guid keyFrameId, object data, int startFrame, int duration, string affectedElement)
+    public SetKeyFrameData_Change(Guid nodeId, Guid keyFrameId, object data, int startFrame, int duration,
+        string affectedElement)
     {
     {
         this.nodeId = nodeId;
         this.nodeId = nodeId;
         this.keyFrameId = keyFrameId;
         this.keyFrameId = keyFrameId;
@@ -22,48 +23,46 @@ internal class SetKeyFrameData_Change : Change
         this.duration = duration;
         this.duration = duration;
         this.affectedElement = affectedElement;
         this.affectedElement = affectedElement;
     }
     }
-    
+
     public override bool InitializeAndValidate(Document target)
     public override bool InitializeAndValidate(Document target)
     {
     {
         return target.TryFindNode(nodeId, out Node node);
         return target.TryFindNode(nodeId, out Node node);
     }
     }
 
 
-    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply,
+        out bool ignoreInUndo)
     {
     {
         Node node = target.FindNode(nodeId);
         Node node = target.FindNode(nodeId);
 
 
         KeyFrameData keyFrame = node.KeyFrames.FirstOrDefault(
         KeyFrameData keyFrame = node.KeyFrames.FirstOrDefault(
-            x => x.KeyFrameGuid == keyFrameId 
-                 || IsSpecialRootKeyFrame(x)); 
-        
-        if (keyFrame is null)
-        {
-            keyFrame = new KeyFrameData(keyFrameId, startFrame, duration, affectedElement);
-        }
-        
-        keyFrame.Data = data;
-        keyFrame.StartFrame = startFrame;
-        keyFrame.Duration = duration;
-        keyFrame.AffectedElement = affectedElement;
-        
-        if (!node.KeyFrames.Contains(keyFrame))
+            x => x.KeyFrameGuid == keyFrameId
+                 || IsSpecialRootKeyFrame(x));
+
+
+        var newKeyFrame = new KeyFrameData(keyFrameId, startFrame, duration, affectedElement) { Data = data };
+
+        if (keyFrame != null)
         {
         {
-            node.AddFrame(keyFrameId, keyFrame);
+            node.RemoveKeyFrame(keyFrame.KeyFrameGuid);
         }
         }
-        
+         
+        node.AddFrame(keyFrameId, newKeyFrame);
+
         ignoreInUndo = false;
         ignoreInUndo = false;
-        
+
         return new None();
         return new None();
     }
     }
 
 
     private bool IsSpecialRootKeyFrame(KeyFrameData x)
     private bool IsSpecialRootKeyFrame(KeyFrameData x)
     {
     {
-        return (x is { StartFrame: 0, Duration: 0 } && startFrame == 0 && duration == 0 && x.AffectedElement == affectedElement);
+        return (x is { StartFrame: 0, Duration: 0 } && startFrame == 0 && duration == 0 &&
+                x.AffectedElement == affectedElement);
     }
     }
 
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
     {
-        throw new InvalidOperationException("Cannot revert SetKeyFrameData_Change, this change is only meant for setting key frame data.");
+        throw new InvalidOperationException(
+            "Cannot revert SetKeyFrameData_Change, this change is only meant for setting key frame data.");
         return new None(); // do not remove, code generator doesn't work without it 
         return new None(); // do not remove, code generator doesn't work without it 
     }
     }
 }
 }