VFXGroupNode.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System.Collections.Generic;
  2. using UnityEditor.Experimental.GraphView;
  3. using UnityEngine;
  4. using UnityEngine.UIElements;
  5. using System.Reflection;
  6. using System.Linq;
  7. namespace UnityEditor.VFX.UI
  8. {
  9. class VFXGroupNode : Group, IControlledElement<VFXGroupNodeController>, IVFXMovable
  10. {
  11. Controller IControlledElement.controller
  12. {
  13. get { return m_Controller; }
  14. }
  15. public VFXGroupNodeController controller
  16. {
  17. get { return m_Controller; }
  18. set
  19. {
  20. if (m_Controller != null)
  21. {
  22. m_Controller.UnregisterHandler(this);
  23. }
  24. m_Controller = value;
  25. if (m_Controller != null)
  26. {
  27. m_Controller.RegisterHandler(this);
  28. }
  29. }
  30. }
  31. VFXGroupNodeController m_Controller;
  32. VisualElement m_GroupDropArea;
  33. public VFXGroupNode()
  34. {
  35. this.AddManipulator(new ContextualMenuManipulator(BuildContextualMenu));
  36. m_GroupDropArea = this.Query("dropArea");
  37. RegisterCallback<DragPerformEvent>(DragPerform);
  38. RegisterCallback<DragUpdatedEvent>(DragUpdated);
  39. RegisterCallback<DragLeaveEvent>(DragLeave);
  40. capabilities |= Capabilities.Ascendable;
  41. }
  42. public bool CanAcceptDrop()
  43. {
  44. VFXView view = GetFirstAncestorOfType<VFXView>();
  45. if (view == null)
  46. return false;
  47. return view.selection.Any(t => t is BlackboardField && (t as BlackboardField).GetFirstAncestorOfType<VFXBlackboardRow>() != null);
  48. }
  49. public void DragUpdated(DragUpdatedEvent evt)
  50. {
  51. if (CanAcceptDrop())
  52. m_GroupDropArea.AddToClassList("dragEntered");
  53. }
  54. public void DragPerform(DragPerformEvent evt)
  55. {
  56. m_GroupDropArea.RemoveFromClassList("dragEntered");
  57. }
  58. public void DragLeave(DragLeaveEvent evt)
  59. {
  60. m_GroupDropArea.RemoveFromClassList("dragEntered");
  61. }
  62. public void BuildContextualMenu(ContextualMenuPopulateEvent evt)
  63. {
  64. }
  65. public void OnMoved()
  66. {
  67. controller.position = GetPosition();
  68. foreach (var node in containedElements.OfType<IVFXMovable>())
  69. {
  70. node.OnMoved();
  71. }
  72. }
  73. void IControlledElement.OnControllerChanged(ref ControllerChangedEvent e)
  74. {
  75. if (e.controller == controller)
  76. {
  77. SelfChange();
  78. }
  79. }
  80. public void SelfChange()
  81. {
  82. // use are custom data changed from the view because we can't listen simply to the VFXUI, because the VFXUI might have been modified because we were removed and the datawatch might call us before the view
  83. VFXView view = this.GetFirstAncestorOfType<VFXView>();
  84. if (view == null) return;
  85. m_ModificationFromController = true;
  86. inRemoveElement = true;
  87. title = controller.title;
  88. var presenterContent = new HashSet<Controller>(controller.nodes);
  89. var elementContent = containedElements.OfType<IControlledElement>().Where(t => t.controller is VFXNodeController || t.controller is VFXStickyNoteController).ToArray();
  90. bool elementsChanged = false;
  91. var elementToDelete = elementContent.Where(t => !presenterContent.Contains(t.controller)).ToArray();
  92. foreach (var element in elementToDelete)
  93. {
  94. this.RemoveElement(element as GraphElement);
  95. elementsChanged = true;
  96. }
  97. if (presenterContent.Count() != elementContent.Count())
  98. {
  99. var elementToAdd = presenterContent.Select(t => view.GetGroupNodeElement(t)).Except(elementContent.Cast<GraphElement>()).ToArray();
  100. //bool someNodeNotFound = false;
  101. foreach (var element in elementToAdd)
  102. {
  103. if (element != null)
  104. {
  105. this.AddElement(element as GraphElement);
  106. elementsChanged = true;
  107. }
  108. else
  109. {
  110. //someNodeNotFound = true;
  111. }
  112. }
  113. }
  114. // only update position if the groupnode is empty otherwise the size should be computed from the content.
  115. if (presenterContent.Count() == 0)
  116. {
  117. SetPosition(controller.position);
  118. }
  119. else
  120. {
  121. if (elementsChanged)
  122. UpdateGeometryFromContent();
  123. }
  124. m_ModificationFromController = false;
  125. inRemoveElement = false;
  126. }
  127. bool m_ModificationFromController;
  128. public static bool inRemoveElement { get; set; }
  129. public void ElementsAddedToGroupNode(IEnumerable<GraphElement> elements)
  130. {
  131. if (!m_ModificationFromController)
  132. {
  133. controller.AddNodes(elements.OfType<ISettableControlledElement<VFXNodeController>>().Select(t => t.controller));
  134. controller.AddStickyNotes(elements.OfType<VFXStickyNote>().Select(t => t.controller));
  135. OnMoved();
  136. }
  137. }
  138. public void ElementsRemovedFromGroupNode(IEnumerable<GraphElement> elements)
  139. {
  140. if (!m_ModificationFromController && !inRemoveElement)
  141. {
  142. controller.RemoveNodes(elements.OfType<ISettableControlledElement<VFXNodeController>>().Select(t => t.controller));
  143. controller.RemoveStickyNotes(elements.OfType<VFXStickyNote>().Select(t => t.controller));
  144. }
  145. }
  146. public void GroupNodeTitleChanged(string title)
  147. {
  148. if (!m_ModificationFromController)
  149. {
  150. controller.title = title;
  151. }
  152. }
  153. }
  154. }