CreateStructureMember_Change.cs 4.1 KB

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