private bool AcceptsElementInternal(GraphElement element, ref int proposedIndex, int maxIndex) { return(element != null && !(element is Scope) && !(element is StackNode) && !(element is TokenNode) && (element.GetContainingScope() as Group) == null && AcceptsElement(element, ref proposedIndex, maxIndex)); }
private void AddElementInternal(GraphElement element) { if (element == null) { throw new ArgumentException("Cannot add null element"); } if (containedElements.Contains(element)) { throw new ArgumentException("The specified element is already contained in this scope."); } string reasonWhyNotAccepted = "Cannot add the specified element to this scope."; if (!AcceptsElement(element, ref reasonWhyNotAccepted)) { throw new ArgumentException(reasonWhyNotAccepted); } // Removes the element from its current scope Scope currentScope = element.GetContainingScope(); if (currentScope != null) { currentScope.RemoveElement(element); } m_ContainedElements.Add(element); // To update the scope geometry whenever the added element's geometry changes element.RegisterCallback <GeometryChangedEvent>(OnSubElementGeometryChanged); ScheduleUpdateGeometryFromContent(); }
public void RemoveElement(GraphElement graphElement) { // TODO : Find a better way to remove a graphElement from its scope when it is removed from the GraphView. Scope scope = graphElement.GetContainingScope(); if (scope != null) { scope.RemoveElement(graphElement); } graphElement.RemoveFromHierarchy(); }
protected new void OnMouseMove(MouseMoveEvent e) { if (!m_Active) { return; } if (m_GraphView == null) { return; } var ve = (VisualElement)e.target; Vector2 gvMousePos = ve.ChangeCoordinatesTo(m_GraphView.contentContainer, e.localMousePosition); m_PanDiff = GetEffectivePanSpeed(gvMousePos); if (m_PanDiff != Vector3.zero) { m_PanSchedule.Resume(); } else { m_PanSchedule.Pause(); } // We need to monitor the mouse diff "by hand" because we stop positioning the graph elements once the // mouse has gone out. m_MouseDiff = m_originalMouse - e.mousePosition; var groupElementsDraggedOut = e.shiftKey ? new Dictionary <Group, List <GraphElement> >() : null; foreach (KeyValuePair <GraphElement, OriginalPos> v in m_OriginalPos) { GraphElement ce = v.Key; // Protect against stale visual elements that have been deparented since the start of the manipulation if (ce.shadow.parent == null) { continue; } if (!v.Value.dragStarted) { // TODO Would probably be a good idea to batch stack items as we do for group ones. var stackParent = ce.GetFirstAncestorOfType <StackNode>(); if (stackParent != null) { stackParent.OnStartDragging(ce); } if (groupElementsDraggedOut != null) { var groupParent = ce.GetContainingScope() as Group; if (groupParent != null) { if (!groupElementsDraggedOut.ContainsKey(groupParent)) { groupElementsDraggedOut[groupParent] = new List <GraphElement>(); } groupElementsDraggedOut[groupParent].Add(ce); } } v.Value.dragStarted = true; } MoveElement(ce, v.Value.pos); } // Needed to ensure nodes can be dragged out of multiple groups all at once. if (groupElementsDraggedOut != null) { foreach (KeyValuePair <Group, List <GraphElement> > kvp in groupElementsDraggedOut) { kvp.Key.OnStartDragging(e, kvp.Value); } } List <ISelectable> selection = m_GraphView.selection; // TODO: Replace with a temp drawing or something...maybe manipulator could fake position // all this to let operation know which element sits under cursor...or is there another way to draw stuff that is being dragged? IDropTarget dropTarget = GetDropTargetAt(e.mousePosition, selection.OfType <VisualElement>()); if (m_PrevDropTarget != dropTarget) { if (m_PrevDropTarget != null) { using (DragLeaveEvent eexit = DragLeaveEvent.GetPooled(e)) { SendDragAndDropEvent(eexit, selection, m_PrevDropTarget, m_GraphView); } } using (DragEnterEvent eenter = DragEnterEvent.GetPooled(e)) { SendDragAndDropEvent(eenter, selection, dropTarget, m_GraphView); } } using (DragUpdatedEvent eupdated = DragUpdatedEvent.GetPooled(e)) { SendDragAndDropEvent(eupdated, selection, dropTarget, m_GraphView); } m_PrevDropTarget = dropTarget; selectedElement = null; e.StopPropagation(); }
protected new void OnMouseDown(MouseDownEvent e) { if (m_Active) { e.StopImmediatePropagation(); return; } if (CanStartManipulation(e)) { m_GraphView = target as GraphView; if (m_GraphView == null) { return; } selectedElement = null; // avoid starting a manipulation on a non movable object clickedElement = e.target as GraphElement; if (clickedElement == null) { var ve = e.target as VisualElement; clickedElement = ve.GetFirstAncestorOfType <GraphElement>(); if (clickedElement == null) { return; } } // Only start manipulating if the clicked element is movable, selected and that the mouse is in its clickable region (it must be deselected otherwise). if (!clickedElement.IsMovable() || !clickedElement.HitTest(clickedElement.WorldToLocal(e.mousePosition))) { return; } // If we hit this, this likely because the element has just been unselected // It is important for this manipulator to receive the event so the previous one did not stop it // but we shouldn't let it propagate to other manipulators to avoid a re-selection if (!m_GraphView.selection.Contains(clickedElement)) { e.StopImmediatePropagation(); return; } selectedElement = clickedElement; m_OriginalPos = new Dictionary <GraphElement, OriginalPos>(); foreach (ISelectable s in m_GraphView.selection) { GraphElement ce = s as GraphElement; if (ce == null || !ce.IsMovable()) { continue; } StackNode stackNode = null; if (ce.parent is StackNode) { stackNode = ce.parent as StackNode; if (stackNode.IsSelected(m_GraphView)) { continue; } } Rect geometry = ce.GetPosition(); Rect geometryInContentViewSpace = ce.shadow.parent.ChangeCoordinatesTo(m_GraphView.contentViewContainer, geometry); m_OriginalPos[ce] = new OriginalPos { pos = geometryInContentViewSpace, scope = ce.GetContainingScope(), stack = stackNode, stackIndex = stackNode != null?stackNode.IndexOf(ce) : -1 }; } m_originalMouse = e.mousePosition; m_ItemPanDiff = Vector3.zero; if (m_PanSchedule == null) { m_PanSchedule = m_GraphView.schedule.Execute(Pan).Every(k_PanInterval).StartingIn(k_PanInterval); m_PanSchedule.Pause(); } m_Active = true; target.CaptureMouse(); // We want to receive events even when mouse is not over ourself. e.StopImmediatePropagation(); } }