Browse Source

Key frame groups now delete along with nodes

flabbet 1 year ago
parent
commit
7f3d5d7ad4

+ 12 - 0
src/PixiEditor.ChangeableDocument/Changeables/Animations/AnimationData.cs

@@ -23,6 +23,10 @@ internal class AnimationData : IReadOnlyAnimationData
         {
             group.Children.Add(keyFrame);
         }
+        else if (keyFrame is GroupKeyFrame groupKeyFrame)
+        {
+            keyFrames.Add(groupKeyFrame);
+        }
         else
         {
             var node = document.FindNodeOrThrow<Node>(id);
@@ -36,6 +40,14 @@ internal class AnimationData : IReadOnlyAnimationData
     {
         TryFindKeyFrameCallback<KeyFrame>(createdKeyFrameId, out _, (frame, parent) =>
         {
+            if (frame is GroupKeyFrame group)
+            {
+                keyFrames.Remove(group);
+                foreach (var child in group.Children)
+                {
+                    RemoveKeyFrame(child.Id); 
+                }
+            }
             if (document.TryFindNode<Node>(frame.NodeId, out Node? node))
             {
                 node.RemoveKeyFrame(frame.Id);

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Animations/GroupKeyFrame.cs

@@ -40,7 +40,7 @@ internal class GroupKeyFrame : KeyFrame, IKeyFrameChildrenContainer
 
     public override KeyFrame Clone()
     {
-        var clone = new GroupKeyFrame(TargetNode, StartFrame, document) { Id = this.Id };
+        var clone = new GroupKeyFrame(TargetNode, StartFrame, document) { Id = this.Id, IsVisible = IsVisible };
         foreach (var child in Children)
         {
             clone.Children.Add(child.Clone());

+ 3 - 7
src/PixiEditor.ChangeableDocument/Changeables/Animations/RasterKeyFrame.cs

@@ -8,23 +8,19 @@ internal class RasterKeyFrame : KeyFrame, IReadOnlyRasterKeyFrame
     public Document Document { get; set; }
 
     private ImageLayerNode targetNode;
-    private ChunkyImage targetImage;
 
-    public RasterKeyFrame(Guid id, ImageLayerNode node, int startFrame, Document document, ChunkyImage keyFrameImage)
+    public RasterKeyFrame(Guid id, ImageLayerNode node, int startFrame, Document document)
         : base(node, startFrame)
     {
         Id = id;
         targetNode = node;
-        targetImage = keyFrameImage;
-
         Document = document;
     }
 
     public override KeyFrame Clone()
     {
-        var image = targetImage.CloneFromCommitted();
-        return new RasterKeyFrame(Id, targetNode, StartFrame, Document, image) { Duration = Duration, IsVisible = IsVisible };
+        return new RasterKeyFrame(Id, targetNode, StartFrame, Document) { Duration = Duration, IsVisible = IsVisible };
     }
 
-    public IReadOnlyChunkyImage Image => targetImage;
+    public IReadOnlyChunkyImage Image => targetNode.GetLayerImageByKeyFrameGuid(Id);
 }

+ 12 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Node.cs

@@ -328,6 +328,18 @@ public abstract class Node : IReadOnlyNode, IDisposable
             var newOutput = cloneOutput.Clone(clone);
             clone.outputs[i].Value = newOutput.Value; 
         }
+        
+        foreach (var keyFrame in keyFrames)
+        {
+            KeyFrameData newKeyFrame = new KeyFrameData(keyFrame.KeyFrameGuid, keyFrame.StartFrame, keyFrame.Duration,
+                keyFrame.AffectedElement)
+            {
+                IsVisible = keyFrame.IsVisible, Duration = keyFrame.Duration,
+                Data = keyFrame.Data is ICloneable cloneable ? cloneable.Clone() : keyFrame.Data
+            };
+            
+            clone.keyFrames.Add(newKeyFrame);
+        }
 
         return clone;
     }

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Animation/CreateRasterKeyFrame_Change.cs

@@ -42,7 +42,7 @@ internal class CreateRasterKeyFrame_Change : Change
         ChunkyImage img = cloneFromImage?.CloneFromCommitted() ?? new ChunkyImage(target.Size);
 
         var keyFrame =
-            new RasterKeyFrame(createdKeyFrameId, targetNode, _frame, target, img);
+            new RasterKeyFrame(createdKeyFrameId, targetNode, _frame, target);
 
         var existingData = targetNode.KeyFrames.FirstOrDefault(x => x.KeyFrameGuid == createdKeyFrameId);
 

+ 37 - 1
src/PixiEditor.ChangeableDocument/Changes/NodeGraph/DeleteNode_Change.cs

@@ -1,4 +1,7 @@
-using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.Changeables.Animations;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.Changeables.Interfaces;
+using PixiEditor.ChangeableDocument.ChangeInfos.Animation;
 using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
 
 namespace PixiEditor.ChangeableDocument.Changes.NodeGraph;
@@ -10,6 +13,8 @@ internal class DeleteNode_Change : Change
     private ConnectionsData originalConnections;
 
     private Node savedCopy;
+    
+    private GroupKeyFrame savedKeyFrameGroup;
 
     [GenerateMakeChangeAction]
     public DeleteNode_Change(Guid nodeId)
@@ -28,9 +33,17 @@ internal class DeleteNode_Change : Change
 
         savedCopy = node.Clone();
 
+        savedKeyFrameGroup = CloneGroupKeyFrame(target, NodeId);
+
         return true;
     }
 
+    public static GroupKeyFrame CloneGroupKeyFrame(Document target, Guid id)
+    {
+        GroupKeyFrame group = target.AnimationData.KeyFrames.FirstOrDefault(x => x.TargetNode.Id == id) as GroupKeyFrame;
+        return group.Clone() as GroupKeyFrame;
+    }
+
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply,
         out bool ignoreInUndo)
     {
@@ -43,6 +56,12 @@ internal class DeleteNode_Change : Change
 
         changes.Add(new DeleteNode_ChangeInfo(NodeId));
 
+        if (savedKeyFrameGroup != null)
+        {
+            target.AnimationData.RemoveKeyFrame(savedKeyFrameGroup.Id);
+            changes.Add(new DeleteKeyFrame_ChangeInfo(savedKeyFrameGroup.Id));
+        }
+
         return changes;
     }
 
@@ -60,10 +79,27 @@ internal class DeleteNode_Change : Change
         changes.Add(createChange);
 
         changes.AddRange(NodeOperations.ConnectStructureNodeProperties(originalConnections, copy, doc.NodeGraph));
+        
+        RevertKeyFrames(doc, savedKeyFrameGroup, changes);
 
         return changes;
     }
 
+    public static void RevertKeyFrames(Document doc, GroupKeyFrame savedKeyFrameGroup, List<IChangeInfo> changes)
+    {
+        if (savedKeyFrameGroup != null)
+        {
+            doc.AnimationData.AddKeyFrame(savedKeyFrameGroup.Clone());
+            foreach (var keyFrame in savedKeyFrameGroup.Children)
+            {
+                changes.Add(new CreateRasterKeyFrame_ChangeInfo(keyFrame.NodeId, keyFrame.StartFrame, keyFrame.Id, false));
+                changes.Add(new KeyFrameLength_ChangeInfo(keyFrame.Id, keyFrame.StartFrame, keyFrame.Duration));
+            } 
+            
+            changes.Add(new KeyFrameVisibility_ChangeInfo(savedKeyFrameGroup.Id, savedKeyFrameGroup.IsVisible));
+        }
+    }
+
     public override void Dispose()
     {
         savedCopy?.Dispose();

+ 24 - 10
src/PixiEditor.ChangeableDocument/Changes/Structure/DeleteStructureMember_Change.cs

@@ -1,5 +1,7 @@
-using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.Changeables.Animations;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.ChangeInfos.Animation;
 using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
 using PixiEditor.ChangeableDocument.ChangeInfos.Structure;
 using PixiEditor.ChangeableDocument.Changes.NodeGraph;
@@ -10,9 +12,11 @@ internal class DeleteStructureMember_Change : Change
 {
     private Guid memberGuid;
     private int originalIndex;
-    private ConnectionsData originalConnections; 
+    private ConnectionsData originalConnections;
     private StructureNode? savedCopy;
 
+    private GroupKeyFrame savedKeyFrameGroup;
+
     [GenerateMakeChangeAction]
     public DeleteStructureMember_Change(Guid memberGuid)
     {
@@ -25,10 +29,13 @@ internal class DeleteStructureMember_Change : Change
         if (member is null)
             return false;
 
-        originalConnections = NodeOperations.CreateConnectionsData(member); 
-        
+        originalConnections = NodeOperations.CreateConnectionsData(member);
+
         savedCopy = (StructureNode)member.Clone();
         savedCopy.Id = memberGuid;
+
+        savedKeyFrameGroup = DeleteNode_Change.CloneGroupKeyFrame(document, memberGuid);
+
         return true;
     }
 
@@ -51,11 +58,17 @@ internal class DeleteStructureMember_Change : Change
                 bgConnection.ConnectTo(connection);
                 changes.Add(new ConnectProperty_ChangeInfo(bgConnection.Node.Id, connection.Node.Id,
                     bgConnection.InternalPropertyName, connection.InternalPropertyName));
-                
+
                 node.Output.DisconnectFrom(connection);
             }
         }
 
+        if (savedKeyFrameGroup != null)
+        {
+            document.AnimationData.RemoveKeyFrame(savedKeyFrameGroup.Id);
+            changes.Add(new DeleteKeyFrame_ChangeInfo(savedKeyFrameGroup.Id));
+        }
+
         node.Dispose();
         ignoreInUndo = false;
 
@@ -74,15 +87,17 @@ internal class DeleteStructureMember_Change : Change
 
         IChangeInfo createChange = copy switch
         {
-            LayerNode => CreateLayer_ChangeInfo.FromLayer((LayerNode)copy),
-            FolderNode => CreateFolder_ChangeInfo.FromFolder((FolderNode)copy),
+            LayerNode node => CreateLayer_ChangeInfo.FromLayer(node),
+            FolderNode node => CreateFolder_ChangeInfo.FromFolder(node),
             _ => throw new NotSupportedException(),
         };
-        
+
         changes.Add(createChange);
 
-        changes.AddRange(NodeOperations.ConnectStructureNodeProperties(originalConnections, copy, doc.NodeGraph)); 
+        changes.AddRange(NodeOperations.ConnectStructureNodeProperties(originalConnections, copy, doc.NodeGraph));
         
+        DeleteNode_Change.RevertKeyFrames(doc, savedKeyFrameGroup, changes);
+
         return changes;
     }
 
@@ -91,4 +106,3 @@ internal class DeleteStructureMember_Change : Change
         savedCopy?.Dispose();
     }
 }
-

+ 9 - 2
src/PixiEditor/ViewModels/Document/AnimationDataViewModel.cs

@@ -170,8 +170,15 @@ internal class AnimationDataViewModel : ObservableObject, IAnimationHandler
     {
         TryFindKeyFrame<KeyFrameViewModel>(keyFrameId, out _, (frame, parent) =>
         {
-            parent.Children.Remove(frame);
-            keyFrames.NotifyCollectionChanged(NotifyCollectionChangedAction.Remove, (KeyFrameViewModel)frame);
+            if (frame is not KeyFrameGroupViewModel group)
+            {
+                parent.Children.Remove(frame);
+                keyFrames.NotifyCollectionChanged(NotifyCollectionChangedAction.Remove, (KeyFrameViewModel)frame);
+            }
+            else
+            {
+                keyFrames.Remove(group);
+            }
         });
         
         allKeyFrames.RemoveAll(x => x.Id == keyFrameId);