void ShowCreateNodeMenu(Vector2 nodePosition) { Vector2 position = nodePosition; if (canvas.snapNodesOnGrid) { position = canvas.ConvertToSnapPosition(position); } m_nodeMenu = new GenericMenu(); Type[] nodeTypesToAdd = ReflectionUtility.LoadClassTypes <Node, CreateNodeMenu> (); for (int i = 0; i < nodeTypesToAdd.Length; i++) { Type nodeTypeToAdd = nodeTypesToAdd[i]; CreateNodeMenu createNodeMenu = nodeTypeToAdd.GetAttribute <CreateNodeMenu> (); // Normally this cannot happen. if (createNodeMenu == null) { Debug.LogWarning("The node [" + nodeTypeToAdd.FullName + "] has no CreateNodeMenuAttribute"); } else { m_nodeMenu.AddItem(new GUIContent(createNodeMenu.path), false, () => { AIController controller = graph.controller; Node node = createNodeMenu.CreateNew(nodeTypeToAdd); node.position = position; Serializer.AddNewNodeToController(controller, node); graph.Repaint(); GraphUndo.Record("Add new node [" + node.name + "]", () => { Serializer.RemoveNodeFromController(controller, node, false); graph.Repaint(); }, () => { Serializer.RestoreNodeToController(controller, node, null); graph.Repaint(); }); }); } } }
public override void OnProcess(Event e) { // select port if (e.IsMouseDown(MouseButton.Left) && m_selectedPort == null && e.IsMouseInsideRect(canvas.unscaledRect)) { for (int i = 0; i < canvas.nodes.Length; i++) { Node currentNode = canvas.nodes[i]; if (currentNode.isHidden) { continue; } ConnectionPort[] currentNodePorts = currentNode.ports; for (int j = 0; j < currentNodePorts.Length; j++) { ConnectionPort currentNodePort = currentNodePorts[j]; if (!currentNodePort.isHidden && currentNodePort.rect.Contains(canvas.mousePosition)) { m_selectedPort = currentNodePort; canvas.selectedPort = currentNodePort; break; } } if (m_selectedPort != null) { e.Use(); break; } } } // drag port if (e.IsMouseDrag(MouseButton.Left) && m_selectedPort != null) { graph.Repaint(); e.Use(); } // connect if (e.IsMouseUp(MouseButton.Left) && m_selectedPort != null) { bool connectionExecuted = false; for (int i = 0; i < canvas.nodes.Length; i++) { Node currentNode = canvas.nodes[i]; if (currentNode.isHidden) { continue; } ConnectionPort[] currentNodePorts = currentNode.ports; for (int j = 0; j < currentNodePorts.Length; j++) { ConnectionPort currentNodePort = currentNodePorts[j]; if (!currentNodePort.isHidden && currentNodePort.rect.Contains(canvas.mousePosition)) { ConnectionPort fromPort = m_selectedPort; ConnectionPort toPort = currentNodePort; bool connectionSuccess = Serializer.ConnectPorts(fromPort, toPort); if (connectionSuccess) { GraphUndo.Record(fromPort.node.name + " connected to " + toPort.node.name, () => { Serializer.DisconnectPorts(fromPort, toPort); }, () => { Serializer.ConnectPorts(fromPort, toPort); }); } connectionExecuted = true; break; } } if (connectionExecuted) { break; } } m_selectedPort = null; canvas.selectedPort = null; e.Use(); } }
public override void OnProcess(Event e) { // Hover, select and drag start can only start if the mouse is in the canvas and drag and multi selection is not started. if (e.IsMouseInsideRect(canvas.unscaledRect) && !m_dragStarted && !m_multiSelectionStarted) { bool nodeSelected = false; bool nodeHovered = false; // if left mouse button is down, save the selection position, // all current selected nodes in the canvas and clear the current selected nodes. if (e.IsMouseDown(MouseButton.Left)) { m_selectionStartPosition = canvas.mousePosition; m_currentSelectedCanvasNodes = canvas.GetSelectedNodes(); m_selectedNodes.Clear(); } for (int i = 0; i < canvas.nodes.Length; i++) { Node node = canvas.nodes[i]; if (node.isHidden) { continue; } if (!nodeHovered && node.rect.Contains(canvas.mousePosition)) { // set the node under the mouse to the hover state. // But only if the shift key is not clicked. Or the control key is clicked. if (e.control || !e.shift) { canvas.SetHoveredNode(node); nodeHovered = true; } if (e.IsMouseDown(MouseButton.Left)) { // check if a port is under the mouse. ConnectionPort[] nodePorts = node.ports; for (int j = 0; j < nodePorts.Length; j++) { if (nodePorts[j].rect.Contains(canvas.mousePosition)) { // node drag cannot start. // select the current node and return. canvas.SetSelectedNode(node); return; } } // a node is selected. nodeSelected = true; m_currentSelectedNode = node; if (e.control) { // if the control key is down add all current selected nodes in the canvas // and add the current selected node if its not in the current selected node list. m_selectionWithControlKey = true; m_selectedNodes.AddRange(m_currentSelectedCanvasNodes); if (!m_selectedNodes.Contains(node)) { m_selectedNodes.Add(node); } } else if (e.shift) { // If the shift key is down add all current selected nodes in the canvas // and remove the current selected if it's in the list. m_selectionWithShiftKey = true; m_selectedNodes.AddRange(m_currentSelectedCanvasNodes); if (m_selectedNodes.Contains(node)) { m_selectedNodes.Remove(node); } } else { // If no other control key is down, two different // modes can be performed. If the current selected node // is already selected, the user want to drag all current selected canvas nodes // or if he don't drag the current selected node, he only want to select this node. // // If the current selected node is not on the canvas selected, the user want to // select and maybe drag only the current selected node. if (m_currentSelectedCanvasNodes.Contains(node)) { m_selectedNodes.AddRange(m_currentSelectedCanvasNodes); } else { m_selectedNodes.Add(node); } } // set all drag start positions of the current selected nodes. m_nodeDragStartPositions = new Vector2[m_selectedNodes.Count]; for (int j = 0; j < m_nodeDragStartPositions.Length; j++) { m_nodeDragStartPositions[j] = m_selectedNodes[j].position; } // select nodes visually. canvas.SetSelectedNodes(m_selectedNodes.ToArray()); // start drag if currently more than one node is selected. m_dragStarted = m_selectedNodes.Count > 0; GUI.SetNextControlName(""); GUI.FocusControl(""); e.Use(); break; } else if (e.IsMouseDown(MouseButton.Right)) { // select node for the context selection. canvas.SetSelectedNode(node); graph.Repaint(); return; } } } // If no node was selected, the user want to start a multi selection. // Or deselect all nodes. if (!nodeSelected && e.IsMouseDown(MouseButton.Left)) { m_multiSelectionStarted = true; if (e.control) { m_selectionWithControlKey = true; } else if (e.shift) { m_selectionWithShiftKey = true; } // remove hot controls GUI.SetNextControlName(""); GUI.FocusControl(""); e.Use(); } } // handle node drag. if (m_dragStarted) { // drag starts only if the user moves the mouse a short distance, while the mouse is down. if (!m_dragPerformed && Vector2.Distance(m_selectionStartPosition, canvas.mousePosition) > 5) { m_dragPerformed = true; } if (e.IsMouseDrag(MouseButton.Left) && m_dragPerformed) { m_dragPerformed = true; m_dragDelta = canvas.mousePosition - m_selectionStartPosition; if (canvas.snapNodesOnGrid) { m_dragDelta = canvas.ConvertToSnapPosition(m_dragDelta); } for (int i = 0; i < m_selectedNodes.Count; i++) { m_selectedNodes[i].position = m_nodeDragStartPositions[i] + m_dragDelta; } e.Use(); } } // handle node multi selection. if (m_multiSelectionStarted) { Vector2 currentCanvasPosition = canvas.mousePosition; // rearrange the min and max position. float xMinCanvas = Mathf.Min(m_selectionStartPosition.x, currentCanvasPosition.x); float yMinCanvas = Mathf.Min(m_selectionStartPosition.y, currentCanvasPosition.y); float xMaxCanvas = Mathf.Max(m_selectionStartPosition.x, currentCanvasPosition.x); float yMaxCanvas = Mathf.Max(m_selectionStartPosition.y, currentCanvasPosition.y); // create the current selection rect in canvas space. m_multiSelectionCanvasRect = Rect.MinMaxRect(xMinCanvas, yMinCanvas, xMaxCanvas, yMaxCanvas); // create a selection rect in screen space (for rendering) i dont want to scale the border of this rect. Vector2 min = canvas.CanvasToScreenPoint(new Vector2(xMinCanvas, yMinCanvas)); Vector2 max = canvas.CanvasToScreenPoint(new Vector2(xMaxCanvas, yMaxCanvas)); m_multiSelectionScreenRect = Rect.MinMaxRect(min.x, min.y, max.x, max.y); m_selectedNodes.Clear(); // If the user starts with control key down. // He want to add all nodes in the rect. if (m_selectionWithControlKey) { m_selectedNodes.AddRange(m_currentSelectedCanvasNodes); for (int i = 0; i < canvas.nodes.Length; i++) { Node node = canvas.nodes[i]; if (m_multiSelectionCanvasRect.Overlaps(node.rect)) { if (!m_selectedNodes.Contains(node)) { m_selectedNodes.Add(node); } } } } // If the user starts with shift key down. // he want to remove all nodes in the rect. else if (m_selectionWithShiftKey) { m_selectedNodes.AddRange(m_currentSelectedCanvasNodes); for (int i = 0; i < canvas.nodes.Length; i++) { Node node = canvas.nodes[i]; if (m_multiSelectionCanvasRect.Overlaps(node.rect)) { if (m_selectedNodes.Contains(node)) { m_selectedNodes.Remove(node); } } } } // The user want only select nodes in the rect. else { for (int i = 0; i < canvas.nodes.Length; i++) { Node node = canvas.nodes[i]; if (m_multiSelectionCanvasRect.Overlaps(node.rect)) { if (!m_selectedNodes.Contains(node)) { m_selectedNodes.Add(node); } } } } canvas.SetHoveredNodes(m_selectedNodes.ToArray()); if (e.IsMouseDrag(MouseButton.Left)) { e.Use(); } } if (e.IsMouseUp(MouseButton.Left, true)) { // remove hot controls // GUI.SetNextControlName (""); // GUI.FocusControl (""); if (m_dragStarted) { // Check if drag was performed. // If drag was performed, create a record for all dragged nodes. if (m_dragPerformed) { Node[] finalNodesToDrag = m_selectedNodes.ToArray(); Vector2[] finalNodeDragStartPositions = m_nodeDragStartPositions; Vector2 finalDragDelta = m_dragDelta; string undoName = finalNodesToDrag.Length > 1 ? "Move [" + finalNodesToDrag.Length + "] nodes" : "Move node [" + finalNodesToDrag[0].name + "]"; GraphUndo.Record(undoName, () => { for (int i = 0; i < finalNodesToDrag.Length; i++) { finalNodesToDrag[i].position = finalNodeDragStartPositions[i]; } }, () => { for (int i = 0; i < finalNodesToDrag.Length; i++) { finalNodesToDrag[i].position = finalNodeDragStartPositions[i] + finalDragDelta; } }); graph.controller.isDirty = true; e.Use(); } // If no drag was performed, check if a node was selected. // If no node was selected, clear the selected nodes. // Else check if the current selected node was selected and select only this. // Or select all current selected nodes. else { if (m_selectionWithControlKey || m_selectionWithShiftKey) { canvas.SetSelectedNodes(m_selectedNodes.ToArray()); } else if (m_currentSelectedNode != null) { bool nodeWasNodeAlreadySelected = m_currentSelectedCanvasNodes.Contains(m_currentSelectedNode); if (nodeWasNodeAlreadySelected) { canvas.SetSelectedNode(m_currentSelectedNode); } else { canvas.SetSelectedNodes(m_selectedNodes.ToArray()); } } else { canvas.ClearSelectedNodes(); } e.Use(); } } else if (m_multiSelectionStarted) { // If no node is in the multi selection rect, the user clicked in the canvas and will deselect all current selected nodes. // Otherwise select all nodes, that are in the selection rect. if (m_selectedNodes.Count > 0) { canvas.SetSelectedNodes(m_selectedNodes.ToArray()); } else { canvas.ClearSelectedNodes(); } e.Use(); } // Reset all fields. m_currentSelectedNode = null; m_dragStarted = false; m_dragPerformed = false; m_multiSelectionStarted = false; m_selectionWithControlKey = false; m_selectionWithShiftKey = false; } }