Browse Source

Fixed duplicate layer

flabbet 1 year ago
parent
commit
0e15d51bf6

+ 4 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.cs

@@ -454,9 +454,12 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
             }
         }*/
 
-        void AddAnimationData(AnimationDataBuilder data, Dictionary<int, Guid> mappedIds,
+        void AddAnimationData(AnimationDataBuilder? data, Dictionary<int, Guid> mappedIds,
             Dictionary<int, Guid> mappedKeyFrameIds)
         {
+            if(data is null)
+                return;
+            
             acc.AddActions(new SetFrameRate_Action(data.FrameRate));
             foreach (var keyFrame in data.KeyFrameGroups)
             {

+ 9 - 9
src/PixiEditor.ChangeableDocument/Changeables/Document.cs

@@ -26,7 +26,7 @@ internal class Document : IChangeable, IReadOnlyDocument
     IReadOnlyList<IReadOnlyStructureNode> IReadOnlyDocument.FindMemberPath(Guid guid) => FindMemberPath(guid);
     IReadOnlyStructureNode IReadOnlyDocument.FindMemberOrThrow(Guid guid) => FindMemberOrThrow(guid);
 
-    (IReadOnlyStructureNode, IReadOnlyFolderNode) IReadOnlyDocument.FindChildAndParentOrThrow(Guid guid) =>
+    (IReadOnlyStructureNode, IReadOnlyNode) IReadOnlyDocument.FindChildAndParentOrThrow(Guid guid) =>
         FindChildAndParentOrThrow(guid);
 
     IReadOnlyReferenceLayer? IReadOnlyDocument.ReferenceLayer => ReferenceLayer;
@@ -304,12 +304,12 @@ internal class Document : IChangeable, IReadOnlyDocument
     /// <param name="childGuid">The <see cref="StructureNode.Id"/> of the member</param>
     /// <returns>A value tuple consisting of child (<see cref="ValueTuple{T, T}.Item1"/>) and parent (<see cref="ValueTuple{T, T}.Item2"/>)</returns>
     /// <exception cref="ArgumentException">Thrown if the member and parent could not be found</exception>
-    public (StructureNode, FolderNode) FindChildAndParentOrThrow(Guid childGuid)
+    public (StructureNode, Node) FindChildAndParentOrThrow(Guid childGuid)
     {
-        var path = FindMemberPath(childGuid);
+        var path = FindNodePath(childGuid);
         if (path.Count < 2)
             throw new ArgumentException("Couldn't find child and parent");
-        return (path[0], (FolderNode)path[1]);
+        return (path[0] as StructureNode, path[1]);
     }
 
     /// <summary>
@@ -357,21 +357,21 @@ internal class Document : IChangeable, IReadOnlyDocument
     {
         if (NodeGraph.OutputNode == null) return [];
 
-        var list = new List<Node>();
+        var list = new List<StructureNode>();
         var targetNode = FindNode(guid);
         if (targetNode == null)
         {
             return [];
         }
-        FillNodePath(targetNode, list);
-        return list.Cast<StructureNode>().ToList();
+        FillNodePath<StructureNode>(targetNode, list);
+        return list.ToList();
     }
 
-    private bool FillNodePath(Node node, List<Node> toFill)
+    private bool FillNodePath<T>(Node node, List<T> toFill) where T : Node
     {
         node.TraverseForwards(newNode =>
         {
-            if (newNode is StructureNode strNode)
+            if (newNode is T strNode)
             {
                 toFill.Add(strNode);
             }

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IReadOnlyDocument.cs

@@ -92,7 +92,7 @@ public interface IReadOnlyDocument : IDisposable
     /// <param name="childGuid">The <see cref="IReadOnlyStructureNode.GuidValue"/> of the member</param>
     /// <returns>A value tuple consisting of child (<see cref="ValueTuple{T, T}.Item1"/>) and parent (<see cref="ValueTuple{T, T}.Item2"/>)</returns>
     /// <exception cref="ArgumentException">Thrown if the member and parent could not be found</exception>
-    (IReadOnlyStructureNode, IReadOnlyFolderNode) FindChildAndParentOrThrow(Guid childGuid);
+    (IReadOnlyStructureNode, IReadOnlyNode) FindChildAndParentOrThrow(Guid childGuid);
 
     /// <summary>
     /// Finds the path to the member with <paramref name="guid"/>, the first element will be the member

+ 44 - 13
src/PixiEditor.ChangeableDocument/Changes/Structure/DuplicateLayer_Change.cs

@@ -1,49 +1,80 @@
-using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.Changeables.Graph;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
 using PixiEditor.ChangeableDocument.ChangeInfos.Structure;
+using PixiEditor.ChangeableDocument.Changes.NodeGraph;
+using PixiEditor.DrawingApi.Core;
 
 namespace PixiEditor.ChangeableDocument.Changes.Structure;
+
 internal class DuplicateLayer_Change : Change
 {
     private readonly Guid layerGuid;
     private Guid duplicateGuid;
+    
+    private ConnectionsData? connectionsData;
 
     [GenerateMakeChangeAction]
     public DuplicateLayer_Change(Guid layerGuid)
     {
         this.layerGuid = layerGuid;
     }
+
     public override bool InitializeAndValidate(Document target)
     {
         if (!target.TryFindMember<LayerNode>(layerGuid, out LayerNode? layer))
             return false;
         duplicateGuid = Guid.NewGuid();
+        
+        connectionsData = NodeOperations.CreateConnectionsData(layer);
+        
         return true;
     }
 
-    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)
     {
-        (LayerNode existingLayer, FolderNode parent) = ((LayerNode, FolderNode))target.FindChildAndParentOrThrow(layerGuid);
+        (LayerNode existingLayer, Node parent) = ((LayerNode, Node))target.FindChildAndParentOrThrow(layerGuid);
+
 
         LayerNode clone = (LayerNode)existingLayer.Clone();
         clone.Id = duplicateGuid;
 
-        /*int index = parent.Children.IndexOf(existingLayerNode);
-        parent.Children = parent.Children.Insert(index, clone);
+        InputProperty<Surface?> targetInput = parent.InputProperties.FirstOrDefault(x =>
+            x.ValueType == typeof(Surface) &&
+            x.Connection.Node is StructureNode) as InputProperty<Surface?>;
+
+        List<IChangeInfo> operations = new();
+
+        target.NodeGraph.AddNode(clone);
+
+        operations.Add(CreateLayer_ChangeInfo.FromLayer(clone));
+
+        operations.AddRange(NodeOperations.AppendMember(targetInput, clone.Output, clone.Background, clone.Id));
 
         ignoreInUndo = false;
-        return CreateLayer_ChangeInfo.FromLayer(parent.Id, index, clone);*/
-//TODO: Implement
-        ignoreInUndo = false;
-        return new None();
+
+        return operations;
     }
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        /*var (member, parent) = target.FindChildAndParentOrThrow(duplicateGuid);
-        parent.Children = parent.Children.Remove(member);
+        var (member, parent) = target.FindChildAndParentOrThrow(duplicateGuid);
+
+        target.NodeGraph.RemoveNode(member);
         member.Dispose();
-        return new DeleteStructureMember_ChangeInfo(duplicateGuid, parent.Id);*/
 
-        return new None();
+        List<IChangeInfo> changes = new();
+
+        changes.AddRange(NodeOperations.DetachStructureNode(member));
+        changes.Add(new DeleteStructureMember_ChangeInfo(member.Id));
+        
+        if (connectionsData is not null)
+        {
+            Node originalNode = target.FindNodeOrThrow<Node>(layerGuid);
+            changes.AddRange(NodeOperations.ConnectStructureNodeProperties(connectionsData, originalNode, target.NodeGraph));
+        }
+        
+        return changes;
     }
 }