MoveStructureMember_Change.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 MoveStructureMember_Change : Change
  10. {
  11. private Guid memberGuid;
  12. private Guid targetNodeGuid;
  13. private Guid originalFolderGuid;
  14. private ConnectionsData originalConnections;
  15. private Dictionary<Guid, VecD> originalPositions;
  16. private bool putInsideFolder;
  17. [GenerateMakeChangeAction]
  18. public MoveStructureMember_Change(Guid memberGuid, Guid targetNode, bool putInsideFolder)
  19. {
  20. this.memberGuid = memberGuid;
  21. this.targetNodeGuid = targetNode;
  22. this.putInsideFolder = putInsideFolder;
  23. }
  24. public override bool InitializeAndValidate(Document document)
  25. {
  26. var member = document.FindMember(memberGuid);
  27. var targetFolder = document.FindNode(targetNodeGuid);
  28. if (member is null || targetFolder is null)
  29. return false;
  30. originalConnections = NodeOperations.CreateConnectionsData(member);
  31. return true;
  32. }
  33. private static List<IChangeInfo> Move(Document document, Guid sourceNodeGuid, Guid targetNodeGuid,
  34. bool putInsideFolder, out Dictionary<Guid, VecD> originalPositions)
  35. {
  36. var sourceNode = document.FindMember(sourceNodeGuid);
  37. var targetNode = document.FindNode(targetNodeGuid);
  38. originalPositions = null;
  39. if (sourceNode is null || targetNode is not IRenderInput backgroundInput)
  40. return [];
  41. List<IChangeInfo> changes = new();
  42. Guid oldBackgroundId = sourceNode.Background.Node.Id;
  43. InputProperty<Painter?> inputProperty = backgroundInput.Background;
  44. if (targetNode is FolderNode folder && putInsideFolder)
  45. {
  46. inputProperty = folder.Content;
  47. }
  48. MoveStructureMember_ChangeInfo changeInfo = new(sourceNodeGuid, oldBackgroundId, targetNodeGuid);
  49. var previouslyConnected = inputProperty.Connection;
  50. bool isMovingBelow = false;
  51. inputProperty.Node.TraverseForwards(x =>
  52. {
  53. if (x.Id == sourceNodeGuid)
  54. {
  55. isMovingBelow = true;
  56. return false;
  57. }
  58. return true;
  59. });
  60. if (isMovingBelow)
  61. {
  62. changes.AddRange(NodeOperations.AdjustPositionsBeforeAppend(sourceNode, inputProperty.Node, out originalPositions));
  63. }
  64. changes.AddRange(NodeOperations.DetachStructureNode(sourceNode));
  65. changes.AddRange(NodeOperations.AppendMember(inputProperty, sourceNode.Output,
  66. sourceNode.Background,
  67. sourceNode.Id));
  68. if (!isMovingBelow)
  69. {
  70. changes.AddRange(NodeOperations.AdjustPositionsAfterAppend(sourceNode, inputProperty.Node,
  71. previouslyConnected?.Node as Node, out originalPositions));
  72. }
  73. if (targetNode is FolderNode)
  74. {
  75. changes.AddRange(AdjustPutIntoFolderPositions(targetNode, originalPositions));
  76. }
  77. changes.Add(changeInfo);
  78. return changes;
  79. }
  80. public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply,
  81. out bool ignoreInUndo)
  82. {
  83. var changes = Move(target, memberGuid, targetNodeGuid, putInsideFolder, out originalPositions);
  84. ignoreInUndo = false;
  85. return changes;
  86. }
  87. public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
  88. {
  89. StructureNode member = target.FindMember(memberGuid);
  90. List<IChangeInfo> changes = new List<IChangeInfo>();
  91. MoveStructureMember_ChangeInfo changeInfo = new(memberGuid, targetNodeGuid, originalFolderGuid);
  92. changes.AddRange(NodeOperations.DetachStructureNode(member));
  93. changes.AddRange(NodeOperations.ConnectStructureNodeProperties(originalConnections, member, target.NodeGraph));
  94. changes.AddRange(NodeOperations.RevertPositions(originalPositions, target));
  95. changes.Add(changeInfo);
  96. return changes;
  97. }
  98. private static List<IChangeInfo> AdjustPutIntoFolderPositions(Node targetNode, Dictionary<Guid, VecD> originalPositions)
  99. {
  100. List<IChangeInfo> changes = new();
  101. if (targetNode is FolderNode folder)
  102. {
  103. folder.Content.Connection.Node.TraverseBackwards(contentNode =>
  104. {
  105. if (contentNode is Node node)
  106. {
  107. if (!originalPositions.ContainsKey(node.Id))
  108. {
  109. originalPositions[node.Id] = node.Position;
  110. }
  111. node.Position = new VecD(node.Position.X, folder.Position.Y + 250);
  112. changes.Add(new NodePosition_ChangeInfo(node.Id, node.Position));
  113. }
  114. return true;
  115. });
  116. folder.Background.Connection?.Node.TraverseBackwards(bgNode =>
  117. {
  118. if (bgNode is Node node)
  119. {
  120. if (!originalPositions.ContainsKey(node.Id))
  121. {
  122. originalPositions[node.Id] = node.Position;
  123. }
  124. double pos = folder.Position.Y;
  125. if (folder.Content.Connection != null)
  126. {
  127. pos -= 250;
  128. }
  129. node.Position = new VecD(node.Position.X, pos);
  130. changes.Add(new NodePosition_ChangeInfo(node.Id, node.Position));
  131. }
  132. return true;
  133. });
  134. }
  135. return changes;
  136. }
  137. }