public override sealed void DrawNodeConnections(Vector2 canvasMousePos, float zoomFactor)
        {
            var e = Event.current;

            if (maxOutConnections == 0){

                if (clickedPort != null && e.type == EventType.MouseUp){
                    dragDropMisses ++;
                    if (dragDropMisses == graph.allNodes.Count){
                        clickedPort = null;
                    }
                }

                return;
            }

            var portRectLeft = new Rect(0,0,20,20);
            var portRectRight = new Rect(0,0,20,20);
            var portRectBottom = new Rect(0,0,20,20);

            portRectLeft.center = new Vector2(nodeRect.x - 11, nodeRect.yMax - 10);
            portRectRight.center = new Vector2(nodeRect.xMax + 11, nodeRect.yMax - 10);
            portRectBottom.center = new Vector2(nodeRect.center.x, nodeRect.yMax + 11);

            EditorGUIUtility.AddCursorRect(portRectLeft, MouseCursor.ArrowPlus);
            EditorGUIUtility.AddCursorRect(portRectRight, MouseCursor.ArrowPlus);
            EditorGUIUtility.AddCursorRect(portRectBottom, MouseCursor.ArrowPlus);

            GUI.color = new Color(1,1,1,0.3f);
            GUI.Box(portRectLeft, "", "arrowLeft");
            GUI.Box(portRectRight, "", "arrowRight");
            if (maxInConnections == 0)
                GUI.Box(portRectBottom, "", "arrowBottom");
            GUI.color = Color.white;

            if (e.type == EventType.MouseDown && e.button == 0){

                if (portRectLeft.Contains(e.mousePosition)){
                    clickedPort = new GUIPort(this, portRectLeft.center);
                    dragDropMisses = 0;
                    e.Use();
                }

                if (portRectRight.Contains(e.mousePosition)){
                    clickedPort = new GUIPort(this, portRectRight.center);
                    dragDropMisses = 0;
                    e.Use();
                }

                if (maxInConnections == 0 && portRectBottom.Contains(e.mousePosition)){
                    clickedPort = new GUIPort(this, portRectBottom.center);
                    dragDropMisses = 0;
                    e.Use();
                }
            }

            if (clickedPort != null && clickedPort.parent == this)
                Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos, e.mousePosition, new Color(0.5f,0.5f,0.8f,0.8f), null, 2);

            if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0){

                if (nodeRect.Contains(e.mousePosition)){
                    foreach(FSMConnection connection in inConnections){
                        if (connection.sourceNode == clickedPort.parent){
                            Debug.LogWarning("State is already connected to target state. Consider using a 'ConditionList' on the existing transition if you want to check multiple conditions");
                            clickedPort = null;
                            e.Use();
                            return;
                        }
                    }

                    graph.ConnectNodes(clickedPort.parent, this);
                    clickedPort = null;
                    e.Use();

                } else {

                    dragDropMisses ++;

                    if (dragDropMisses == graph.allNodes.Count && clickedPort != null){
                        var source = clickedPort.parent;
                        var pos = Event.current.mousePosition;
                        var menu = new GenericMenu();
                        clickedPort = null;

                        menu.AddItem(new GUIContent("Add Action State"), false, ()=> {
                            var newState = graph.AddNode<ActionState>(pos);
                            graph.ConnectNodes(source, newState);
                        });

                        //PostGUI cause of zoom factors
                        Graph.PostGUI += ()=> { menu.ShowAsContext(); };
                        Event.current.Use();
                        e.Use();
                    }
                }
            }

            for (var i = 0; i < outConnections.Count; i++){

                var connection = outConnections[i] as FSMConnection;
                var targetState = connection.targetNode as FSMState;
                if (targetState == null){ //In case of MissingNode type
                    continue;
                }
                var targetPos = targetState.GetConnectedInPortPosition(connection);
                var sourcePos = Vector2.zero;

                if (nodeRect.center.x <= targetPos.x)
                    sourcePos = portRectRight.center;

                if (nodeRect.center.x > targetPos.x)
                    sourcePos = portRectLeft.center;

                if (maxInConnections == 0 && nodeRect.center.y < targetPos.y - 50 && Mathf.Abs(nodeRect.center.x - targetPos.x) < 200 )
                    sourcePos = portRectBottom.center;

                connection.DrawConnectionGUI(sourcePos, targetPos);
            }
        }
Esempio n. 2
0
        //Draw the connections line from this node, to all of its children. This is the default hierarchical style. Override in each system's base node class.
        virtual public void DrawNodeConnections(Vector2 canvasMousePos, float zoomFactor)
        {
            if (isHidden)
            {
                return;
            }

            var e = Event.current;

            //Receive connections first
            if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0)
            {
                if (nodeRect.Contains(e.mousePosition))
                {
                    graph.ConnectNodes(clickedPort.parent, this, clickedPort.portIndex);
                    clickedPort = null;
                    e.Use();
                }
                else
                {
                    dragDropMisses++;

                    if (dragDropMisses == graph.allNodes.Count && clickedPort != null)
                    {
                        var source = clickedPort.parent;
                        var index  = clickedPort.portIndex;
                        var pos    = e.mousePosition;
                        clickedPort = null;

                        System.Action <System.Type> Selected = delegate(System.Type type){
                            var newNode = graph.AddNode(type, pos);
                            graph.ConnectNodes(source, newNode, index);
                            newNode.SortConnectionsByPositionX();
                            Graph.currentSelection = newNode;
                        };

                        var menu = EditorUtils.GetTypeSelectionMenu(graph.baseNodeType, Selected);
                        if (zoomFactor == 1 && NCPrefs.useBrowser)
                        {
                            menu.ShowAsBrowser(string.Format("Add {0} Node", graph.GetType().Name), graph.baseNodeType);
                        }
                        else
                        {
                            Graph.PostGUI += () => { menu.ShowAsContext(); };
                        }
                        e.Use();
                    }
                }
            }



            if (maxOutConnections == 0)
            {
                return;
            }

            var nodeOutputBox = new Rect(nodeRect.x, nodeRect.yMax - 4, nodeRect.width, 12);

            GUI.Box(nodeOutputBox, "", (GUIStyle)"nodePortContainer");

            //draw the ports
            if (outConnections.Count < maxOutConnections || maxOutConnections == -1)
            {
                for (var i = 0; i < outConnections.Count + 1; i++)
                {
                    var portRect = new Rect(0, 0, 10, 10);
                    portRect.center = new Vector2(((nodeRect.width / (outConnections.Count + 1)) * (i + 0.5f)) + nodeRect.xMin, nodeRect.yMax + 6);
                    GUI.Box(portRect, "", (GUIStyle)"nodePortEmpty");

                    if (collapsed)
                    {
                        continue;
                    }

                    //start a connection by clicking a port
                    EditorGUIUtility.AddCursorRect(portRect, MouseCursor.ArrowPlus);
                    if (e.type == EventType.MouseDown && e.button == 0 && portRect.Contains(e.mousePosition))
                    {
                        dragDropMisses = 0;
                        clickedPort    = new GUIPort(i, this, portRect.center);
                        e.Use();
                    }
                }
            }

            //draw the new drag&drop connection line
            if (clickedPort != null && clickedPort.parent == this)
            {
                var yDiff = (clickedPort.pos.y - e.mousePosition.y) * 0.5f;
                yDiff = e.mousePosition.y > clickedPort.pos.y? -yDiff : yDiff;
                var tangA = new Vector2(0, yDiff);
                var tangB = tangA * -1;
                Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos + tangA, e.mousePosition + tangB, new Color(0.5f, 0.5f, 0.8f, 0.8f), null, 3);
            }

            //draw all connected lines
            for (var connectionIndex = 0; connectionIndex < outConnections.Count; connectionIndex++)
            {
                var connection = outConnections[connectionIndex];
                if (connection != null)
                {
                    var sourcePos = new Vector2(((nodeRect.width / (outConnections.Count + 1)) * (connectionIndex + 1)) + nodeRect.xMin, nodeRect.yMax + 6);
                    var targetPos = new Vector2(connection.targetNode.nodeRect.center.x, connection.targetNode.nodeRect.y);

                    var sourcePortRect = new Rect(0, 0, 12, 12);
                    sourcePortRect.center = sourcePos;
                    GUI.Box(sourcePortRect, "", (GUIStyle)"nodePortConnected");

                    if (collapsed || connection.targetNode.isHidden)
                    {
                        continue;
                    }

                    connection.DrawConnectionGUI(sourcePos, targetPos);

                    //On right click disconnect connection from the source.
                    if (e.type == EventType.ContextClick && sourcePortRect.Contains(e.mousePosition))
                    {
                        graph.RemoveConnection(connection);
                        e.Use();
                        return;
                    }

                    //On right click disconnect connection from the target.
                    var targetPortRect = new Rect(0, 0, 15, 15);
                    targetPortRect.center = targetPos;
                    if (e.type == EventType.ContextClick && targetPortRect.Contains(e.mousePosition))
                    {
                        graph.RemoveConnection(connection);
                        e.Use();
                        return;
                    }
                }
            }
        }
Esempio n. 3
0
        sealed public override void DrawNodeConnections(Vector2 canvasMousePos, float zoomFactor)
        {
            var e = Event.current;

            if (maxOutConnections == 0)
            {
                if (clickedPort != null && e.type == EventType.MouseUp)
                {
                    dragDropMisses++;
                    if (dragDropMisses == graph.allNodes.Count)
                    {
                        clickedPort = null;
                    }
                }

                return;
            }

            var portRectLeft   = new Rect(0, 0, 20, 20);
            var portRectRight  = new Rect(0, 0, 20, 20);
            var portRectBottom = new Rect(0, 0, 20, 20);

            portRectLeft.center   = new Vector2(nodeRect.x - 11, nodeRect.yMax - 10);
            portRectRight.center  = new Vector2(nodeRect.xMax + 11, nodeRect.yMax - 10);
            portRectBottom.center = new Vector2(nodeRect.center.x, nodeRect.yMax + 11);

            EditorGUIUtility.AddCursorRect(portRectLeft, MouseCursor.ArrowPlus);
            EditorGUIUtility.AddCursorRect(portRectRight, MouseCursor.ArrowPlus);
            EditorGUIUtility.AddCursorRect(portRectBottom, MouseCursor.ArrowPlus);

            GUI.color = new Color(1, 1, 1, 0.3f);
            GUI.Box(portRectLeft, "", "arrowLeft");
            GUI.Box(portRectRight, "", "arrowRight");
            if (maxInConnections == 0)
            {
                GUI.Box(portRectBottom, "", "arrowBottom");
            }
            GUI.color = Color.white;

            if (e.type == EventType.MouseDown && e.button == 0)
            {
                if (portRectLeft.Contains(e.mousePosition))
                {
                    clickedPort    = new GUIPort(this, portRectLeft.center);
                    dragDropMisses = 0;
                    e.Use();
                }

                if (portRectRight.Contains(e.mousePosition))
                {
                    clickedPort    = new GUIPort(this, portRectRight.center);
                    dragDropMisses = 0;
                    e.Use();
                }

                if (maxInConnections == 0 && portRectBottom.Contains(e.mousePosition))
                {
                    clickedPort    = new GUIPort(this, portRectBottom.center);
                    dragDropMisses = 0;
                    e.Use();
                }
            }

            if (clickedPort != null && clickedPort.parent == this)
            {
                Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos, e.mousePosition, new Color(0.5f, 0.5f, 0.8f, 0.8f), null, 2);
            }

            if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0)
            {
                if (nodeRect.Contains(e.mousePosition))
                {
                    foreach (FSMConnection connection in inConnections)
                    {
                        if (connection.sourceNode == clickedPort.parent)
                        {
                            Debug.LogWarning("State is already connected to target state. Consider using a 'ConditionList' on the existing transition if you want to check multiple conditions");
                            clickedPort = null;
                            e.Use();
                            return;
                        }
                    }

                    graph.ConnectNodes(clickedPort.parent, this);
                    clickedPort = null;
                    e.Use();
                }
                else
                {
                    dragDropMisses++;

                    if (dragDropMisses == graph.allNodes.Count && clickedPort != null)
                    {
                        var source = clickedPort.parent;
                        var pos    = Event.current.mousePosition;
                        var menu   = new GenericMenu();
                        clickedPort = null;

                        menu.AddItem(new GUIContent("Add Action State"), false, () => {
                            var newState = graph.AddNode <ActionState>(pos);
                            graph.ConnectNodes(source, newState);
                        });

                        //PostGUI cause of zoom factors
                        Graph.PostGUI += () => { menu.ShowAsContext(); };
                        Event.current.Use();
                        e.Use();
                    }
                }
            }

            for (var i = 0; i < outConnections.Count; i++)
            {
                var connection  = outConnections[i] as FSMConnection;
                var targetState = connection.targetNode as FSMState;
                if (targetState == null)                  //In case of MissingNode type
                {
                    continue;
                }
                var targetPos = targetState.GetConnectedInPortPosition(connection);
                var sourcePos = Vector2.zero;

                if (nodeRect.center.x <= targetPos.x)
                {
                    sourcePos = portRectRight.center;
                }

                if (nodeRect.center.x > targetPos.x)
                {
                    sourcePos = portRectLeft.center;
                }

                if (maxInConnections == 0 && nodeRect.center.y < targetPos.y - 50 && Mathf.Abs(nodeRect.center.x - targetPos.x) < 200)
                {
                    sourcePos = portRectBottom.center;
                }

                connection.DrawConnectionGUI(sourcePos, targetPos);
            }
        }
        ///Editor. Draw the connections line from this node, to all of its children. This is the default hierarchical tree style. Override in each system's base node class.
        virtual protected void DrawNodeConnections(Rect drawCanvas, bool fullDrawPass, Vector2 canvasMousePos, float zoomFactor) {

            var e = Event.current;

            //Receive connections first
            if ( clickedPort != null && e.type == EventType.MouseUp && e.button == 0 ) {

                if ( rect.Contains(e.mousePosition) ) {
                    graph.ConnectNodes(clickedPort.parent, this, clickedPort.portIndex);
                    clickedPort = null;
                    e.Use();

                } else {

                    dragDropMisses++;

                    if ( dragDropMisses == graph.allNodes.Count && clickedPort != null ) {

                        var source = clickedPort.parent;
                        var index = clickedPort.portIndex;
                        var pos = e.mousePosition;
                        clickedPort = null;

                        System.Action<System.Type> Selected = delegate (System.Type type)
                        {
                            var newNode = graph.AddNode(type, pos);
                            graph.ConnectNodes(source, newNode, index);
                            GraphEditorUtility.activeElement = newNode;
                        };

                        var menu = EditorUtils.GetTypeSelectionMenu(graph.baseNodeType, Selected);
                        if ( zoomFactor == 1 ) {
                            menu.ShowAsBrowser(string.Format("Add {0} Node", graph.GetType().Name), graph.baseNodeType);
                        } else {
                            GraphEditorUtility.PostGUI += () => { menu.ShowAsContext(); };
                        }
                        e.Use();
                    }
                }
            }

            if ( maxOutConnections == 0 ) {
                return;
            }

            if ( fullDrawPass || drawCanvas.Overlaps(rect) ) {

                var nodeOutputBox = new Rect(rect.x, rect.yMax - 4, rect.width, 12);
                GUI.Box(nodeOutputBox, string.Empty, StyleSheet.nodePortContainer);

                //draw the ports
                if ( outConnections.Count < maxOutConnections || maxOutConnections == -1 ) {
                    for ( var i = 0; i < outConnections.Count + 1; i++ ) {
                        var portRect = new Rect(0, 0, 10, 10);
                        portRect.center = new Vector2(( ( rect.width / ( outConnections.Count + 1 ) ) * ( i + 0.5f ) ) + rect.xMin, rect.yMax + 6);
                        GUI.Box(portRect, string.Empty, StyleSheet.nodePortEmpty);

                        if ( collapsed ) {
                            continue;
                        }

                        if ( GraphEditorUtility.allowClick ) {
                            //start a connection by clicking a port
                            EditorGUIUtility.AddCursorRect(portRect, MouseCursor.ArrowPlus);
                            if ( e.type == EventType.MouseDown && e.button == 0 && portRect.Contains(e.mousePosition) ) {
                                dragDropMisses = 0;
                                clickedPort = new GUIPort(i, this, portRect.center);
                                e.Use();
                            }
                        }
                    }
                }
            }


            //draw the new drag&drop connection line
            if ( clickedPort != null && clickedPort.parent == this ) {
                var tangA = default(Vector2);
                var tangB = default(Vector2);
                ParadoxNotion.CurveUtils.ResolveTangents(clickedPort.pos, e.mousePosition, 0.5f, PlanarDirection.Vertical, out tangA, out tangB);
                Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos + tangA, e.mousePosition + tangB, StyleSheet.GetStatusColor(Status.Resting).WithAlpha(0.8f), null, 3);
            }


            //draw all connected lines
            for ( var i = 0; i < outConnections.Count; i++ ) {

                var connection = outConnections[i];
                if ( connection != null ) {

                    var sourcePos = new Vector2(( ( rect.width / ( outConnections.Count + 1 ) ) * ( i + 1 ) ) + rect.xMin, rect.yMax + 6);
                    var targetPos = new Vector2(connection.targetNode.rect.center.x, connection.targetNode.rect.y);

                    var sourcePortRect = new Rect(0, 0, 12, 12);
                    sourcePortRect.center = sourcePos;

                    var targetPortRect = new Rect(0, 0, 15, 15);
                    targetPortRect.center = targetPos;

                    var boundRect = RectUtils.GetBoundRect(sourcePortRect, targetPortRect);
                    if ( fullDrawPass || drawCanvas.Overlaps(boundRect) ) {

                        GUI.Box(sourcePortRect, string.Empty, StyleSheet.nodePortConnected);

                        if ( collapsed || connection.targetNode.isHidden ) {
                            continue;
                        }

                        connection.DrawConnectionGUI(sourcePos, targetPos);

                        if ( GraphEditorUtility.allowClick ) {
                            //On right click disconnect connection from the source.
                            if ( e.type == EventType.ContextClick && sourcePortRect.Contains(e.mousePosition) ) {
                                graph.RemoveConnection(connection);
                                e.Use();
                                return;
                            }

                            //On right click disconnect connection from the target.
                            if ( e.type == EventType.ContextClick && targetPortRect.Contains(e.mousePosition) ) {
                                graph.RemoveConnection(connection);
                                e.Use();
                                return;
                            }
                        }
                    }

                }
            }
        }
Esempio n. 5
0
        //Draw the ports and connections
        sealed protected override void DrawNodeConnections(Rect drawCanvas, bool fullDrawPass, Vector2 canvasMousePos, float zoomFactor)
        {
            var e = Event.current;

            //Receive connections first
            if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0)
            {
                if (rect.Contains(e.mousePosition))
                {
                    graph.ConnectNodes(clickedPort.parent, this);
                    clickedPort = null;
                    e.Use();
                }
                else
                {
                    dragDropMisses++;

                    if (dragDropMisses == graph.allNodes.Count && clickedPort != null)
                    {
                        var source = clickedPort.parent;
                        var pos    = Event.current.mousePosition;
                        var menu   = new GenericMenu();
                        clickedPort = null;

                        menu.AddItem(new GUIContent("Add Action State"), false, () =>
                        {
                            var newState = graph.AddNode <ActionState>(pos);
                            graph.ConnectNodes(source, newState);
                        });

                        //PostGUI cause of zoom factors
                        GraphEditorUtility.PostGUI += () => { menu.ShowAsContext(); };
                        Event.current.Use();
                        e.Use();
                    }
                }
            }

            var portRectLeft   = new Rect(0, 0, 20, 20);
            var portRectRight  = new Rect(0, 0, 20, 20);
            var portRectBottom = new Rect(0, 0, 20, 20);

            portRectLeft.center   = new Vector2(rect.x - 11, rect.center.y);
            portRectRight.center  = new Vector2(rect.xMax + 11, rect.center.y);
            portRectBottom.center = new Vector2(rect.center.x, rect.yMax + 11);

            if (maxOutConnections != 0)
            {
                if (fullDrawPass || drawCanvas.Overlaps(rect))
                {
                    EditorGUIUtility.AddCursorRect(portRectLeft, MouseCursor.ArrowPlus);
                    EditorGUIUtility.AddCursorRect(portRectRight, MouseCursor.ArrowPlus);
                    EditorGUIUtility.AddCursorRect(portRectBottom, MouseCursor.ArrowPlus);

                    GUI.color = new Color(1, 1, 1, 0.3f);
                    GUI.DrawTexture(portRectLeft, StyleSheet.arrowLeft);
                    GUI.DrawTexture(portRectRight, StyleSheet.arrowRight);
                    if (maxInConnections == 0)
                    {
                        GUI.DrawTexture(portRectBottom, StyleSheet.arrowBottom);
                    }
                    GUI.color = Color.white;

                    if (GraphEditorUtility.allowClick && e.type == EventType.MouseDown && e.button == 0)
                    {
                        if (portRectLeft.Contains(e.mousePosition))
                        {
                            clickedPort    = new GUIPort(this, portRectLeft.center);
                            dragDropMisses = 0;
                            e.Use();
                        }

                        if (portRectRight.Contains(e.mousePosition))
                        {
                            clickedPort    = new GUIPort(this, portRectRight.center);
                            dragDropMisses = 0;
                            e.Use();
                        }

                        if (maxInConnections == 0 && portRectBottom.Contains(e.mousePosition))
                        {
                            clickedPort    = new GUIPort(this, portRectBottom.center);
                            dragDropMisses = 0;
                            e.Use();
                        }
                    }
                }
            }

            //draw new linking
            if (clickedPort != null && clickedPort.parent == this)
            {
                Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos, e.mousePosition, new Color(0.5f, 0.5f, 0.8f, 0.8f), null, 2);
            }

            //draw out connections
            for (var i = 0; i < outConnections.Count; i++)
            {
                var connection  = outConnections[i] as FSMConnection;
                var targetState = connection.targetNode as FSMState;
                if (targetState == null)
                { //In case of MissingNode type
                    continue;
                }
                var targetPos = targetState.GetConnectedInPortPosition(connection);
                var sourcePos = Vector2.zero;

                if (rect.center.x <= targetPos.x)
                {
                    sourcePos = portRectRight.center;
                }

                if (rect.center.x > targetPos.x)
                {
                    sourcePos = portRectLeft.center;
                }

                if (maxInConnections == 0 && rect.center.y < targetPos.y - 50 && Mathf.Abs(rect.center.x - targetPos.x) < 200)
                {
                    sourcePos = portRectBottom.center;
                }

                var boundRect = RectUtils.GetBoundRect(sourcePos, targetPos);
                if (fullDrawPass || drawCanvas.Overlaps(boundRect))
                {
                    connection.DrawConnectionGUI(sourcePos, targetPos);
                }
            }
        }
Esempio n. 6
0
    /// <summary>
    /// 画出连线
    /// </summary>
    /// <param name="canvasMousePos"></param>
    /// <param name="zoomFactor"></param>
    public virtual void DrawNodeConnections(Vector2 canvasMousePos, float zoomFactor)
    {
        var e = Event.current;

        if (clickedPort != null && e.type == EventType.MouseUp && e.button == 0)
        {
            if (nodeRect.Contains(e.mousePosition))
            {
                graph.ConnectNodes(clickedPort.parent, this, clickedPort.portIndex);
                this.PostConnectionActiveEvent();
                clickedPort = null;
                e.Use();
            }
            else
            {
                dragDropMisses++;
                if (dragDropMisses == graph.allNodes.Count && clickedPort != null)
                {
                    var source = clickedPort.parent;
                    var index  = clickedPort.portIndex;
                    var pos    = e.mousePosition;
                    clickedPort = null;

                    System.Action <System.Type> Selected = delegate(System.Type type) {
                        var newNode = graph.AddNode(type, pos);
                        graph.ConnectNodes(source, newNode, index);
                        // newNode.SortConnectionsByPositionX();
                        Graph.currentSelection = newNode;
                    };
                }
            }
        }
        if (maxInConnections == 0)
        {
            return;
        }
        var nodeOutputBox = new Rect(nodeRect.x, nodeRect.yMax - 4, nodeRect.width, 12);

        GUI.Box(nodeOutputBox, "", (GUIStyle)"nodePortContainer");
        if (outConnections.Count < maxOutConnections || maxOutConnections == -1)
        {
            for (var i = 0; i < outConnections.Count + 1; i++)
            {
                var portRect = new Rect(0, 0, 10, 10);
                portRect.center = new Vector2(((nodeRect.width / (outConnections.Count + 1)) * (i + 0.5f)) + nodeRect.xMin, nodeRect.yMax + 6);
                GUI.Box(portRect, "", (GUIStyle)"nodePortEmpty");

                EditorGUIUtility.AddCursorRect(portRect, MouseCursor.ArrowPlus);
                if (e.type == EventType.MouseDown && e.button == 0 && portRect.Contains(e.mousePosition))
                {
                    dragDropMisses = 0;
                    clickedPort    = new GUIPort(i, this, portRect.center);
                    e.Use();
                }
            }
        }

        if (clickedPort != null && clickedPort.parent == this)
        {
            var yDiff = (clickedPort.pos.y - e.mousePosition.y) * 0.5f;
            yDiff = e.mousePosition.y > clickedPort.pos.y ? -yDiff : yDiff;
            var tangA = new Vector2(0, yDiff);
            var tangB = tangA * -1;
            Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos + tangA, e.mousePosition + tangB, new Color(0.5f, 0.5f, 0.8f, 0.8f), null, 3);
        }
        for (var connectionIndex = 0; connectionIndex < outConnections.Count; connectionIndex++)
        {
            var connection = outConnections[connectionIndex];
            if (connection != null)
            {
                var sourcePos = new Vector2(((nodeRect.width / (outConnections.Count + 1)) * (connectionIndex + 1)) + nodeRect.xMin, nodeRect.yMax + 6);
                var targetPos = new Vector2(connection.targetNode.nodeRect.center.x, connection.targetNode.nodeRect.y);

                var sourcePortRect = new Rect(0, 0, 12, 12);
                sourcePortRect.center = sourcePos;
                GUI.Box(sourcePortRect, "", (GUIStyle)"nodePortConnected");


                connection.DrawConnectionGUI(sourcePos, targetPos);

                //On right click disconnect connection from the source.
                if (e.type == EventType.ContextClick && sourcePortRect.Contains(e.mousePosition))
                {
                    graph.RemoveConnection(connection);
                    e.Use();
                    return;
                }

                //On right click disconnect connection from the target.
                var targetPortRect = new Rect(0, 0, 15, 15);
                targetPortRect.center = targetPos;
                if (e.type == EventType.ContextClick && targetPortRect.Contains(e.mousePosition))
                {
                    graph.RemoveConnection(connection);
                    e.Use();
                    return;
                }
            }
        }
    }