DropTarget GetDropTargetAt(Vector2 mousePosition, IReadOnlyList <VisualElement> exclusionList) { Vector2 pickPoint = mousePosition; m_DropTargetPickList.Clear(); target.panel.PickAll(pickPoint, m_DropTargetPickList); DropTarget dropTarget = null; for (int i = 0; i < m_DropTargetPickList.Count; i++) { if (m_DropTargetPickList[i] == target && target != m_GraphView) { continue; } VisualElement picked = m_DropTargetPickList[i]; dropTarget = picked as DropTarget; if (dropTarget != null) { foreach (var element in exclusionList) { if (element == picked || element.FindCommonAncestor(picked) == element) { dropTarget = null; break; } } if (dropTarget != null) { break; } } } return(dropTarget); }
/// <summary> /// Callback for the MouseCaptureOut event. /// </summary> /// <param name="e">The event.</param> protected void OnMouseCaptureOutEvent(MouseCaptureOutEvent e) { if (m_Active) { if (m_CurrentDropTarget != null && m_GraphView != null) { using (DragExitedEvent eExit = DragExitedEvent.GetPooled()) { eExit.target = m_CurrentDropTarget; m_GraphView.SendEvent(eExit); } } // Stop processing the event sequence if the target has lost focus, then. m_SelectedElement = null; m_CurrentDropTarget = null; m_Active = false; if (m_GraphView?.GetSelection().Any() ?? false) { m_Snapper.EndSnap(); } } }
/// <summary> /// Callback for the MouseUp event. /// </summary> /// <param name="evt">The event.</param> protected void OnMouseUp(MouseUpEvent evt) { if (m_GraphView == null) { if (m_Active) { target.ReleaseMouse(); m_SelectedElement = null; m_Active = false; m_Dragging = false; m_CurrentDropTarget = null; } return; } var selectedModels = m_GraphView.GetSelection(); if (CanStopManipulation(evt)) { if (m_Active) { if (m_Dragging || m_SelectedElement == null) { if (target is GraphView graphView) { graphView.StopSelectionDragger(); graphView.PositionDependenciesManager.StopNotifyMove(); } // if we stop dragging on something else than a DropTarget, just move elements if (m_GraphView != null && (m_CurrentDropTarget == null || !m_CurrentDropTarget.CanAcceptDrop(selectedModels))) { var movedElements = new HashSet <GraphElement>(m_OriginalPos.Keys); movedElements.AddRangeInternal(m_EdgesToUpdate); KeyValuePair <GraphElement, OriginalPos> firstPos = m_OriginalPos.First(); var delta = firstPos.Key.GetPosition().position - firstPos.Value.pos.position; var models = movedElements // PF remove this Where clause. It comes from VseGraphView.OnGraphViewChanged. .Where(e => !(e.Model is INodeModel) || e.IsMovable()) .Select(e => e.Model) .OfType <IMovable>(); m_GraphView.CommandDispatcher.Dispatch( new MoveElementsCommand(delta, models.ToList())); } } foreach (var edge in m_EdgesToUpdate) { edge.EdgeControl.ControlPointOffset = Vector2.zero; } m_EdgesToUpdate.Clear(); m_PanSchedule.Pause(); if (m_ItemPanDiff != Vector3.zero) { Vector3 p = m_GraphView.ContentViewContainer.transform.position; Vector3 s = m_GraphView.ContentViewContainer.transform.scale; m_GraphView.CommandDispatcher.Dispatch(new ReframeGraphViewCommand(p, s)); } if (selectedModels.Count > 0 && m_CurrentDropTarget != null) { if (m_CurrentDropTarget.CanAcceptDrop(selectedModels)) { using (DragPerformEvent ePerform = DragPerformEvent.GetPooled(evt)) { ePerform.target = m_CurrentDropTarget; m_GraphView.SendEvent(ePerform); } } else { using (DragExitedEvent eExit = DragExitedEvent.GetPooled(evt)) { eExit.target = m_CurrentDropTarget; m_GraphView.SendEvent(eExit); } } } if (selectedModels.Any()) { m_Snapper.EndSnap(); } target.ReleaseMouse(); evt.StopPropagation(); } m_SelectedElement = null; m_Active = false; m_CurrentDropTarget = null; m_Dragging = false; m_CurrentDropTarget = null; } }
/// <summary> /// Callback for the MouseMove event. /// </summary> /// <param name="e">The event.</param> protected 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; if (m_SelectedElement.parent != null) { // Handle the selected element Rect selectedElementGeom = GetSelectedElementGeom(); ComputeSnappedRect(ref selectedElementGeom, m_SelectedElement); 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.hierarchy.parent == null) { continue; } if (!v.Value.dragStarted) { v.Value.dragStarted = true; } SnapOrMoveElement(v.Key, v.Value.pos, selectedElementGeom); } foreach (var edge in m_EdgesToUpdate) { SnapOrMoveEdge(edge, selectedElementGeom); } } var selection = m_GraphView.GetSelection(); var selectedUI = selection.Select(m => m.GetUI(m_GraphView)); // 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? var previousDropTarget = m_CurrentDropTarget; m_CurrentDropTarget = GetDropTargetAt(e.mousePosition, selectedUI.OfType <VisualElement>().ToList()); if (m_CurrentDropTarget != previousDropTarget) { if (previousDropTarget != null) { using (DragLeaveEvent eLeave = DragLeaveEvent.GetPooled(e)) { eLeave.target = previousDropTarget; m_GraphView.SendEvent(eLeave); } } if (m_CurrentDropTarget != null) { using (DragEnterEvent eEnter = DragEnterEvent.GetPooled(e)) { eEnter.target = m_CurrentDropTarget; m_GraphView.SendEvent(eEnter); } } } if (m_CurrentDropTarget != null) { using (DragUpdatedEvent eUpdated = DragUpdatedEvent.GetPooled(e)) { eUpdated.target = m_CurrentDropTarget; m_GraphView.SendEvent(eUpdated); } } m_Dragging = true; e.StopPropagation(); }