コード例 #1
0
        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();
            }
        }
コード例 #3
0
        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;
            }
        }