CreateStructureMember_Change.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using Drawie.Numerics;
  2. using PixiEditor.ChangeableDocument.Changeables.Graph;
  3. using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
  4. using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
  5. using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
  6. using PixiEditor.ChangeableDocument.ChangeInfos.Structure;
  7. using PixiEditor.ChangeableDocument.Changes.NodeGraph;
  8. namespace PixiEditor.ChangeableDocument.Changes.Structure;
  9. internal class CreateStructureMember_Change : Change
  10. {
  11. private Guid newMemberGuid;
  12. private Guid parentGuid;
  13. private Type structureMemberOfType;
  14. private ConnectionsData? connectionsData;
  15. private Dictionary<Guid, VecD> originalPositions;
  16. [GenerateMakeChangeAction]
  17. public CreateStructureMember_Change(Guid parent, Guid newGuid,
  18. Type ofType)
  19. {
  20. this.parentGuid = parent;
  21. this.structureMemberOfType = ofType;
  22. newMemberGuid = newGuid;
  23. }
  24. public override bool InitializeAndValidate(Document target)
  25. {
  26. if (structureMemberOfType == null || structureMemberOfType.IsAbstract || structureMemberOfType.IsInterface ||
  27. !structureMemberOfType.IsAssignableTo(typeof(StructureNode)))
  28. return false;
  29. return target.TryFindNode<Node>(parentGuid, out _);
  30. }
  31. public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document document, bool firstApply,
  32. out bool ignoreInUndo)
  33. {
  34. StructureNode member = (StructureNode)NodeOperations.CreateNode(structureMemberOfType, document);
  35. member.Id = newMemberGuid;
  36. document.TryFindNode<Node>(parentGuid, out var parentNode);
  37. List<IChangeInfo> changes = new() { CreateChangeInfo(member) };
  38. InputProperty<Painter> targetInput = parentNode.InputProperties.FirstOrDefault(x =>
  39. x.ValueType == typeof(Painter)) as InputProperty<Painter>;
  40. var previouslyConnected = targetInput.Connection;
  41. if (member is FolderNode folder)
  42. {
  43. document.NodeGraph.AddNode(member);
  44. AppendFolder(targetInput, folder, changes);
  45. }
  46. else
  47. {
  48. document.NodeGraph.AddNode(member);
  49. var connectPropertyChangeInfo =
  50. NodeOperations.AppendMember(targetInput, member.Output, member.Background, member.Id);
  51. changes.AddRange(connectPropertyChangeInfo);
  52. }
  53. changes.AddRange(NodeOperations.AdjustPositionsAfterAppend(member, targetInput.Node, previouslyConnected?.Node as Node, out originalPositions));
  54. ignoreInUndo = false;
  55. return changes;
  56. }
  57. private IChangeInfo CreateChangeInfo(StructureNode member)
  58. {
  59. return member switch
  60. {
  61. LayerNode layer => CreateLayer_ChangeInfo.FromLayer(layer),
  62. FolderNode folderNode => CreateFolder_ChangeInfo.FromFolder(folderNode),
  63. _ => throw new NotSupportedException(),
  64. };
  65. }
  66. public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document document)
  67. {
  68. var container = document.FindNodeOrThrow<Node>(parentGuid);
  69. InputProperty<Painter> backgroundInput = container.InputProperties.FirstOrDefault(x =>
  70. x.ValueType == typeof(Painter)) as InputProperty<Painter>;
  71. StructureNode child = document.FindMemberOrThrow(newMemberGuid);
  72. var childBackgroundConnection = child.Background.Connection;
  73. child.Dispose();
  74. document.NodeGraph.RemoveNode(child);
  75. List<IChangeInfo> changes = new() { new DeleteStructureMember_ChangeInfo(newMemberGuid), };
  76. if (childBackgroundConnection != null)
  77. {
  78. childBackgroundConnection?.ConnectTo(backgroundInput);
  79. ConnectProperty_ChangeInfo change = new(childBackgroundConnection.Node.Id,
  80. backgroundInput.Node.Id, childBackgroundConnection.InternalPropertyName,
  81. backgroundInput.InternalPropertyName);
  82. changes.Add(change);
  83. }
  84. changes.AddRange(NodeOperations.RevertPositions(originalPositions, document));
  85. return changes;
  86. }
  87. private static void AppendFolder(InputProperty<Painter> backgroundInput, FolderNode folder,
  88. List<IChangeInfo> changes)
  89. {
  90. var appened = NodeOperations.AppendMember(backgroundInput, folder.Output, folder.Background, folder.Id);
  91. changes.AddRange(appened);
  92. }
  93. }