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; 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(layerGuid, out LayerNode? layer)) return false; duplicateGuid = Guid.NewGuid(); connectionsData = NodeOperations.CreateConnectionsData(layer); return true; } public override OneOf> Apply(Document target, bool firstApply, out bool ignoreInUndo) { (LayerNode existingLayer, Node parent) = ((LayerNode, Node))target.FindChildAndParentOrThrow(layerGuid); LayerNode clone = (LayerNode)existingLayer.Clone(); clone.Id = duplicateGuid; InputProperty targetInput = parent.InputProperties.FirstOrDefault(x => x.ValueType == typeof(Painter) && x.Connection is { Node: StructureNode }) as InputProperty; List 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 operations; } public override OneOf> Revert(Document target) { var (member, parent) = target.FindChildAndParentOrThrow(duplicateGuid); target.NodeGraph.RemoveNode(member); member.Dispose(); List changes = new(); changes.AddRange(NodeOperations.DetachStructureNode(member)); changes.Add(new DeleteStructureMember_ChangeInfo(member.Id)); if (connectionsData is not null) { Node originalNode = target.FindNodeOrThrow(layerGuid); changes.AddRange(NodeOperations.ConnectStructureNodeProperties(connectionsData, originalNode, target.NodeGraph)); } return changes; } }