1 using System.Collections.Generic;
2 using UnityEditor.Experimental.GraphView;
4 using UnityEngine.UIElements;
5 using System.Reflection;
8 namespace UnityEditor.VFX.UI
10 class VFXGroupNode : Group, IControlledElement<VFXGroupNodeController>, IVFXMovable
12 Controller IControlledElement.controller
14 get { return m_Controller; }
16 public VFXGroupNodeController controller
18 get { return m_Controller; }
21 if (m_Controller != null)
23 m_Controller.UnregisterHandler(this);
26 if (m_Controller != null)
28 m_Controller.RegisterHandler(this);
33 VFXGroupNodeController m_Controller;
35 VisualElement m_GroupDropArea;
39 this.AddManipulator(new ContextualMenuManipulator(BuildContextualMenu));
41 m_GroupDropArea = this.Query("dropArea");
43 RegisterCallback<DragPerformEvent>(DragPerform);
44 RegisterCallback<DragUpdatedEvent>(DragUpdated);
45 RegisterCallback<DragLeaveEvent>(DragLeave);
48 public bool CanAcceptDrop()
50 VFXView view = GetFirstAncestorOfType<VFXView>();
53 return view.selection.Any(t => t is BlackboardField && (t as BlackboardField).GetFirstAncestorOfType<VFXBlackboardRow>() != null);
56 public void DragUpdated(DragUpdatedEvent evt)
59 m_GroupDropArea.AddToClassList("dragEntered");
62 public void DragPerform(DragPerformEvent evt)
64 m_GroupDropArea.RemoveFromClassList("dragEntered");
67 public void DragLeave(DragLeaveEvent evt)
69 m_GroupDropArea.RemoveFromClassList("dragEntered");
72 public void BuildContextualMenu(ContextualMenuPopulateEvent evt)
78 controller.position = GetPosition();
80 foreach (var node in containedElements.OfType<IVFXMovable>())
86 void IControlledElement.OnControllerChanged(ref ControllerChangedEvent e)
88 if (e.controller == controller)
94 public void SelfChange()
96 // 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
97 VFXView view = this.GetFirstAncestorOfType<VFXView>();
98 if (view == null) return;
101 m_ModificationFromController = true;
102 inRemoveElement = true;
103 title = controller.title;
106 var presenterContent = new HashSet<Controller>(controller.nodes);
107 var elementContent = containedElements.OfType<IControlledElement>().Where(t => t.controller is VFXNodeController || t.controller is VFXStickyNoteController).ToArray();
109 bool elementsChanged = false;
110 var elementToDelete = elementContent.Where(t => !presenterContent.Contains(t.controller)).ToArray();
111 foreach (var element in elementToDelete)
113 this.RemoveElement(element as GraphElement);
114 elementsChanged = true;
117 if (presenterContent.Count() != elementContent.Count())
119 var elementToAdd = presenterContent.Select(t => view.GetGroupNodeElement(t)).Except(elementContent.Cast<GraphElement>()).ToArray();
121 //bool someNodeNotFound = false;
122 foreach (var element in elementToAdd)
126 this.AddElement(element as GraphElement);
127 elementsChanged = true;
131 //someNodeNotFound = true;
136 // only update position if the groupnode is empty otherwise the size should be computed from the content.
137 if (presenterContent.Count() == 0)
139 SetPosition(controller.position);
144 UpdateGeometryFromContent();
147 m_ModificationFromController = false;
148 inRemoveElement = false;
151 bool m_ModificationFromController;
153 public static bool inRemoveElement {get; set; }
155 public void ElementsAddedToGroupNode(IEnumerable<GraphElement> elements)
157 if (!m_ModificationFromController)
159 controller.AddNodes(elements.OfType<ISettableControlledElement<VFXNodeController>>().Select(t => t.controller));
160 controller.AddStickyNotes(elements.OfType<VFXStickyNote>().Select(t => t.controller));
165 public void ElementsRemovedFromGroupNode(IEnumerable<GraphElement> elements)
167 if (!m_ModificationFromController && !inRemoveElement)
169 controller.RemoveNodes(elements.OfType<ISettableControlledElement<VFXNodeController>>().Select(t => t.controller));
170 controller.RemoveStickyNotes(elements.OfType<VFXStickyNote>().Select(t => t.controller));
174 public void GroupNodeTitleChanged(string title)
176 if (!m_ModificationFromController)
178 controller.title = title;