public void ParseString()
        {
            var parsedLocalPropertyId = new LocalPropertyId("0xff001000.Output");

            Assert.AreEqual(new LocalId(0xff001000), parsedLocalPropertyId.TargetIdentifier);
            Assert.AreEqual(1, parsedLocalPropertyId.PropertyPath.Length, "Property path should have one element");
            Assert.AreEqual("Output", parsedLocalPropertyId.PropertyPath[0], "Property path element should be \"Output\"");

            Assert.AreEqual(new LocalPropertyId(new LocalId(0xff001000), "Output"), parsedLocalPropertyId);
        }
Example #2
0
        public void DrawConnections()
        {
            if (View.Session == null)
            {
                return;
            }

            if (currentEvent.type != EventType.Repaint &&
                currentEvent.type != EventType.MouseDown &&
                currentEvent.type != EventType.MouseUp)
            {
                return;
            }

            var graphEditorNodesField = View.EditorObject.Fields["Nodes"];
            var graphEditorNodes      = graphEditorNodesField.Value as EditorDictionary;

            // Foreach output
            foreach (var nodeField in graphEditorNodes.KeyValuePairs)
            {
                var node = nodeField.Value.Value as EditorObject;

                var nodeEditor         = node.Fields["Editor"].Value as EditorObject;
                var nodeType           = node.Fields["Type"].Value as EditorValue;
                var nodeData           = node.Fields["Data"].Value as EditorObject;
                var nodeEditorPosition = nodeEditor.Fields["Position"].Value as EditorObject;

                float nodePositionX = (nodeEditorPosition.Fields["x"].Value as EditorValue).GetValue <int>() + View.PanPosition.x;
                float nodePositionY = (nodeEditorPosition.Fields["y"].Value as EditorValue).GetValue <int>() + View.PanPosition.y;

                // Foreach Output
                var nodeInfo = (NodeInformation)nodeData.Type;
                if (nodeInfo?.Outputs != null)
                {
                    var outputSocketRect = new Rect(nodePositionX + 220, nodePositionY + 6, 20, 20);
                    foreach (var output in nodeInfo.Outputs)
                    {
                        if (currentEvent.type == EventType.Repaint)
                        {
                            if (!StyleLookup.TryGetValue(output.Value.Type, out var connectionStyle))
                            {
                                connectionStyle = StyleLookup["Error"];
                                Debug.LogWarning($"Couldn't find a style for connections of type \"{output.Value.Type}\".");
                            }

                            var originalColor = GUI.color;
                            GUI.color = connectionStyle.SocketColor;
                            GUI.DrawTexture(outputSocketRect, BehaviourGraphResources.Instance.OutputSocket);
                            GUI.color = originalColor;
                        }
                        else if (currentEvent.type == EventType.MouseDown && outputSocketRect.Contains(currentEvent.mousePosition))
                        {
                            var outputId = new LocalPropertyId(new LocalId(nodeField.Key), output.Key);
                            View.BeginConnectionFromOutput(outputId);

                            GUI.UnfocusWindow();
                            GUI.FocusControl("");

                            currentEvent.Use();
                        }
                        else if (currentEvent.type == EventType.MouseUp && outputSocketRect.Contains(currentEvent.mousePosition))
                        {
                            if (View.CurrentMode == BehaviourEditorView.ControlMode.CreatingConnection)
                            {
                                if (!View.IsOutputSocket)
                                {
                                    var thisOutputSocket = new LocalPropertyId(new LocalId(nodeField.Key), output.Key);

                                    (View.ConnectionInput.Value as EditorValue).SetValue(thisOutputSocket);
                                    (View.ConnectionInput.Value as EditorValue).ApplyModifiedProperties();
                                    View.CurrentMode = BehaviourEditorView.ControlMode.None;

                                    GUI.UnfocusWindow();
                                    GUI.FocusControl("");

                                    currentEvent.Use();
                                }
                            }
                        }

                        outputSocketRect.y += outputSocketRect.height + 4;
                    }
                }

                IEnumerable <EditorField> InputSocketFields(EditorObject nodeDataContainer)
                {
                    foreach (var childField in nodeDataContainer.Fields.Values)
                    {
                        if (childField.Field.Type != "InputSocket")
                        {
                            continue;
                        }

                        /*
                         * if (childField.Field.Format == FieldFormat.List)
                         * {
                         *      foreach (var listElement in childField)
                         *      {
                         *              yield return listElement;
                         *      }
                         * }
                         */
                        else if (childField.Field.Wrapper == null)
                        {
                            yield return(childField);
                        }
                        else
                        {
                            Debug.LogError($"Unknown InputSocket format. InputSockets cannot be wrapped.");
                        }
                    }
                }

                // Foreach Input
                foreach (var childField in InputSocketFields(nodeData))
                {
                    var childFieldValue   = childField.Value as EditorValue;
                    var inputFieldFeature = childField.GetOrCreateFeature <FieldFeature>();

                    inputFieldFeature.GlobalRenderedPosition = new Rect(
                        inputFieldFeature.LocalRenderedPosition.x + nodePositionX - 4,
                        inputFieldFeature.LocalRenderedPosition.y + nodePositionY,
                        inputFieldFeature.LocalRenderedPosition.width,
                        inputFieldFeature.LocalRenderedPosition.height);

                    var inputSocketRect = inputFieldFeature.InputSocketPosition;

                    if (currentEvent.type == EventType.MouseDown && inputSocketRect.Contains(currentEvent.mousePosition))
                    {
                        View.BeginConnectionFromInput(childField, nodeField.Key);

                        GUI.UnfocusWindow();
                        GUI.FocusControl("");

                        currentEvent.Use();
                    }
                    else if (currentEvent.type == EventType.MouseUp && inputSocketRect.Contains(currentEvent.mousePosition))
                    {
                        if (View.CurrentMode == BehaviourEditorView.ControlMode.CreatingConnection)
                        {
                            if (View.IsOutputSocket)
                            {
                                childFieldValue.SetValue(View.ConnectionOutput);
                                childFieldValue.ApplyModifiedProperties();
                                View.CurrentMode = BehaviourEditorView.ControlMode.None;

                                GUI.UnfocusWindow();
                                GUI.FocusControl("");

                                currentEvent.Use();
                            }
                        }
                    }
                    else if (currentEvent.type == EventType.Repaint)
                    {
                        if (!StyleLookup.TryGetValue("Error", out var inputStyle))
                        {
                            inputStyle = StyleLookup["Error"];
                            Debug.LogWarning($"Couldn't find a style for connections of type \"Error\".");
                        }

                        var originalColor = GUI.color;
                        GUI.color = inputStyle.SocketColor;
                        GUI.DrawTexture(inputSocketRect, BehaviourGraphResources.Instance.InputSocket);
                        GUI.color = originalColor;

                        var thisInputConnectedTo = childFieldValue.GetValue <LocalPropertyId>();
                        if (thisInputConnectedTo != LocalPropertyId.None)
                        {
                            bool isFound = false;
                            Rect otherOutputSocketRect = default;
                            SocketInformation outputSocketInformation = default;

                            foreach (var otherNodeField in graphEditorNodes.KeyValuePairs)
                            {
                                var otherNode = otherNodeField.Value.Value as EditorObject;

                                var otherNodeEditor = otherNode.Fields["Editor"];
                                var otherNodeEditorPositionField = (otherNodeEditor.Value as EditorObject).Fields["Position"];
                                var otherNodeEditorPosition      = otherNodeEditorPositionField.Value as EditorObject;

                                float otherNodePositionX = (otherNodeEditorPosition.Fields["x"].Value as EditorValue).GetValue <int>() + View.PanPosition.x;
                                float otherNodePositionY = (otherNodeEditorPosition.Fields["y"].Value as EditorValue).GetValue <int>() + View.PanPosition.y;

                                var otherNodeKvp  = node.Fields["Data"];
                                var otherNodeData = otherNodeKvp.Value as EditorObject;

                                // Foreach Output
                                otherOutputSocketRect = new Rect(otherNodePositionX + 220, otherNodePositionY + 6, 20, 20);
                                var otherNodeInfo = (NodeInformation)otherNodeData.Type;
                                if (otherNodeInfo.Outputs != null)
                                {
                                    foreach (var output in otherNodeInfo.Outputs)
                                    {
                                        var otherOutputId = new LocalPropertyId(new LocalId(otherNodeField.Key), output.Key);

                                        if (otherOutputId == thisInputConnectedTo)
                                        {
                                            isFound = true;
                                            outputSocketInformation = output.Value;
                                            break;
                                        }

                                        otherOutputSocketRect.y += otherOutputSocketRect.height + 4;
                                    }
                                }
                                else
                                {
                                    Debug.Log("There are no outputs on this node");
                                }
                                if (isFound)
                                {
                                    break;
                                }
                            }
                            if (isFound)
                            {
                                var start    = new Vector3(otherOutputSocketRect.x, otherOutputSocketRect.center.y);
                                var end      = new Vector3(inputFieldFeature.GlobalRenderedPosition.x, inputFieldFeature.GlobalRenderedPosition.center.y);
                                var startDir = new Vector3(1, 0);
                                var endDir   = new Vector3(-1, 0);

                                if (!StyleLookup.TryGetValue(outputSocketInformation.Type, out var connectionStyle))
                                {
                                    connectionStyle = StyleLookup["Error"];
                                    Debug.LogWarning($"Couldn't find a style for connections of type \"{outputSocketInformation.Type}\".");
                                }

                                DrawConnection(start, end, startDir, endDir, connectionStyle.ConnectionColor);
                            }
                        }
                    }
                }
            }

            // Draw active connection
            if (View.CurrentMode == BehaviourEditorView.ControlMode.CreatingConnection)
            {
                if (View.IsOutputSocket)
                {
                    // Draw Nodes
                    bool isFound    = false;
                    Rect outputRect = default;
                    SocketInformation outputSocketInformation = default;

                    foreach (var nodeField in graphEditorNodes.KeyValuePairs)
                    {
                        var node = nodeField.Value.Value as EditorObject;

                        var nodeEditor         = node.Fields["Editor"].Value as EditorObject;
                        var nodeType           = node.Fields["Type"].Value as EditorValue;
                        var nodeData           = node.Fields["Data"].Value as EditorObject;
                        var nodeEditorPosition = nodeEditor.Fields["Position"].Value as EditorObject;

                        float nodePositionX = (nodeEditorPosition.Fields["x"].Value as EditorValue).GetValue <int>() + View.PanPosition.x;
                        float nodePositionY = (nodeEditorPosition.Fields["y"].Value as EditorValue).GetValue <int>() + View.PanPosition.y;

                        // Foreach Output
                        var nodeInfo = (NodeInformation)nodeData.Type;
                        outputRect = new Rect(nodePositionX + 220, nodePositionY + 6, 20, 20);
                        foreach (var output in nodeInfo.Outputs)
                        {
                            var otherOutputId = new LocalPropertyId(new LocalId(nodeField.Key), output.Key);

                            if (otherOutputId == View.ConnectionOutput)
                            {
                                isFound = true;
                                outputSocketInformation = output.Value;
                                break;
                            }

                            outputRect.y += outputRect.height + 4;
                        }
                        if (isFound)
                        {
                            break;
                        }
                    }

                    if (isFound)
                    {
                        var start    = new Vector3(outputRect.x, outputRect.center.y);
                        var end      = new Vector3(currentEvent.mousePosition.x, currentEvent.mousePosition.y);
                        var startDir = new Vector3(1, 0);
                        var endDir   = new Vector3(-1, 0);

                        if (!StyleLookup.TryGetValue(outputSocketInformation.Type, out var connectionStyle))
                        {
                            connectionStyle = StyleLookup["Error"];
                            Debug.LogWarning($"Couldn't find a style for connections of type \"{outputSocketInformation.Type}\".");
                        }

                        DrawConnection(start, end, startDir, endDir, connectionStyle.ConnectionColor);
                    }
                }
                else
                {
                    if (!StyleLookup.TryGetValue("Error", out var inputStyle))
                    {
                        inputStyle = StyleLookup["Error"];
                        Debug.LogWarning($"Couldn't find a style for connections of type \"Error\".");
                    }

                    var startFieldFeature = View.ConnectionInput.GetOrCreateFeature <FieldFeature>();

                    var inputSocketRect = startFieldFeature.InputSocketPosition;

                    var start    = new Vector3(currentEvent.mousePosition.x, currentEvent.mousePosition.y);
                    var end      = new Vector3(inputSocketRect.xMax, inputSocketRect.center.y);
                    var startDir = new Vector3(1, 0);
                    var endDir   = new Vector3(-1, 0);

                    DrawConnection(start, end, startDir, endDir, inputStyle.ConnectionColor);
                }
            }
        }
 public void BeginConnectionFromOutput(LocalPropertyId connectionStart)
 {
     currentMode      = ControlMode.CreatingConnection;
     connectionOutput = connectionStart;
     isOutputSocket   = true;
 }
Example #4
0
        public void DrawConnections()
        {
            if (View.Session == null)
            {
                return;
            }

            if (CurrentEvent.type != EventType.Repaint &&
                CurrentEvent.type != EventType.MouseDown &&
                CurrentEvent.type != EventType.MouseUp)
            {
                return;
            }

            var graphEditorNodes = View.GraphField["Nodes"];

            // Foreach output
            foreach (var node in graphEditorNodes)
            {
                var nodeEditor         = node["Editor"];
                var nodeEditorPosition = nodeEditor["Position"];

                float nodePositionX = nodeEditorPosition["x"].GetValue <int>() + View.PanPosition.x;
                float nodePositionY = nodeEditorPosition["y"].GetValue <int>() + View.PanPosition.y;

                var nodeData = node["Data"];

                // Foreach Output
                var nodeInfo = (NodeInformation)nodeData.Type;
                if (nodeInfo?.Outputs != null)
                {
                    var outputSocketRect = new Rect(nodePositionX + 220, nodePositionY + 6, 20, 20);
                    foreach (var output in nodeInfo.Outputs)
                    {
                        if (CurrentEvent.type == EventType.Repaint)
                        {
                            if (!StyleLookup.TryGetValue(output.Value.Type, out var connectionStyle))
                            {
                                connectionStyle = StyleLookup["Error"];
                                Debug.LogWarning($"Couldn't find a style for connections of type \"{output.Value.Type}\".");
                            }

                            var originalColor = GUI.color;
                            GUI.color = connectionStyle.SocketColor;
                            GUI.DrawTexture(outputSocketRect, BehaviourGraphResources.Instance.OutputSocket);
                            GUI.color = originalColor;
                        }
                        else if (CurrentEvent.type == EventType.MouseDown && outputSocketRect.Contains(CurrentEvent.mousePosition))
                        {
                            var outputId = new LocalPropertyId(new LocalId(node.Name), output.Key);
                            View.BeginConnectionFromOutput(outputId);

                            GUI.UnfocusWindow();
                            GUI.FocusControl("");

                            CurrentEvent.Use();
                        }
                        else if (CurrentEvent.type == EventType.MouseUp && outputSocketRect.Contains(CurrentEvent.mousePosition))
                        {
                            if (View.CurrentMode == BehaviourEditorView.ControlMode.CreatingConnection)
                            {
                                if (!View.IsOutputSocket)
                                {
                                    var thisOutputSocket = new LocalPropertyId(new LocalId(node.Name), output.Key);

                                    View.ConnectionInput.SetValue(thisOutputSocket);
                                    View.ConnectionInput.ApplyModifiedProperties();
                                    View.CurrentMode = BehaviourEditorView.ControlMode.None;

                                    GUI.UnfocusWindow();
                                    GUI.FocusControl("");

                                    CurrentEvent.Use();
                                }
                            }
                        }

                        outputSocketRect.y += outputSocketRect.height + 4;
                    }
                }

                // Foreach Input
                foreach (var childField in nodeData)
                {
                    if (childField.Field.Type != "InputSocket")
                    {
                        continue;
                    }
                    var inputFieldFeature = childField.GetOrCreateFeature <FieldFeature>();

                    inputFieldFeature.GlobalRenderedPosition = new Rect(
                        inputFieldFeature.LocalRenderedPosition.x + nodePositionX - 4,
                        inputFieldFeature.LocalRenderedPosition.y + nodePositionY,
                        inputFieldFeature.LocalRenderedPosition.width,
                        inputFieldFeature.LocalRenderedPosition.height);

                    var inputSocketRect = inputFieldFeature.InputSocketPosition;

                    if (CurrentEvent.type == EventType.MouseDown && inputSocketRect.Contains(CurrentEvent.mousePosition))
                    {
                        View.BeginConnectionFromInput(childField, node.Name);

                        GUI.UnfocusWindow();
                        GUI.FocusControl("");

                        CurrentEvent.Use();
                    }
                    else if (CurrentEvent.type == EventType.MouseUp && inputSocketRect.Contains(CurrentEvent.mousePosition))
                    {
                        if (View.CurrentMode == BehaviourEditorView.ControlMode.CreatingConnection)
                        {
                            if (View.IsOutputSocket)
                            {
                                childField.SetValue(View.ConnectionOutput);
                                childField.ApplyModifiedProperties();
                                View.CurrentMode = BehaviourEditorView.ControlMode.None;

                                GUI.UnfocusWindow();
                                GUI.FocusControl("");

                                CurrentEvent.Use();
                            }
                        }
                    }
                    else if (CurrentEvent.type == EventType.Repaint)
                    {
                        if (!StyleLookup.TryGetValue("Error", out var inputStyle))
                        {
                            inputStyle = StyleLookup["Error"];
                            Debug.LogWarning($"Couldn't find a style for connections of type \"Error\".");
                        }

                        var originalColor = GUI.color;
                        GUI.color = inputStyle.SocketColor;
                        GUI.DrawTexture(inputSocketRect, BehaviourGraphResources.Instance.InputSocket);
                        GUI.color = originalColor;

                        var thisInputConnectedTo = childField.GetValue <LocalPropertyId>();
                        if (thisInputConnectedTo != LocalPropertyId.None)
                        {
                            bool isFound = false;
                            Rect otherOutputSocketRect = default;
                            SocketInformation outputSocketInformation = default;

                            foreach (var otherNode in graphEditorNodes)
                            {
                                var otherNodeEditor         = otherNode["Editor"];
                                var otherNodeEditorPosition = otherNodeEditor["Position"];

                                float otherNodePositionX = otherNodeEditorPosition["x"].GetValue <int>() + View.PanPosition.x;
                                float otherNodePositionY = otherNodeEditorPosition["y"].GetValue <int>() + View.PanPosition.y;

                                var otherNodeData = otherNode["Data"];

                                // Foreach Output
                                otherOutputSocketRect = new Rect(otherNodePositionX + 220, otherNodePositionY + 6, 20, 20);
                                var otherNodeInfo = (NodeInformation)otherNodeData.Type;
                                foreach (var output in otherNodeInfo.Outputs)
                                {
                                    var otherOutputId = new LocalPropertyId(new LocalId(otherNode.Name), output.Key);

                                    if (otherOutputId == thisInputConnectedTo)
                                    {
                                        isFound = true;
                                        outputSocketInformation = output.Value;
                                        break;
                                    }

                                    otherOutputSocketRect.y += otherOutputSocketRect.height + 4;
                                }
                                if (isFound)
                                {
                                    break;
                                }
                            }
                            if (isFound)
                            {
                                var start    = new Vector3(otherOutputSocketRect.x, otherOutputSocketRect.center.y);
                                var end      = new Vector3(inputFieldFeature.GlobalRenderedPosition.x, inputFieldFeature.GlobalRenderedPosition.center.y);
                                var startDir = new Vector3(1, 0);
                                var endDir   = new Vector3(-1, 0);

                                if (!StyleLookup.TryGetValue(outputSocketInformation.Type, out var connectionStyle))
                                {
                                    connectionStyle = StyleLookup["Error"];
                                    Debug.LogWarning($"Couldn't find a style for connections of type \"{outputSocketInformation.Type}\".");
                                }

                                DrawConnection(start, end, startDir, endDir, connectionStyle.ConnectionColor);
                            }
                        }
                    }
                }
            }

            // Draw active connection
            if (View.CurrentMode == BehaviourEditorView.ControlMode.CreatingConnection)
            {
                if (View.IsOutputSocket)
                {
                    // Draw Nodes
                    bool isFound    = false;
                    Rect outputRect = default;
                    SocketInformation outputSocketInformation = default;

                    foreach (var node in graphEditorNodes)
                    {
                        var nodeEditor         = node["Editor"];
                        var nodeEditorPosition = nodeEditor["Position"];

                        float nodePositionX = nodeEditorPosition["x"].GetValue <int>() + View.PanPosition.x;
                        float nodePositionY = nodeEditorPosition["y"].GetValue <int>() + View.PanPosition.y;

                        var nodeData = node["Data"];

                        // Foreach Output
                        var nodeInfo = (NodeInformation)nodeData.Type;
                        outputRect = new Rect(nodePositionX + 220, nodePositionY + 6, 20, 20);
                        foreach (var output in nodeInfo.Outputs)
                        {
                            var otherOutputId = new LocalPropertyId(new LocalId(node.Name), output.Key);

                            if (otherOutputId == View.ConnectionOutput)
                            {
                                isFound = true;
                                outputSocketInformation = output.Value;
                                break;
                            }

                            outputRect.y += outputRect.height + 4;
                        }
                        if (isFound)
                        {
                            break;
                        }
                    }

                    if (isFound)
                    {
                        var start    = new Vector3(outputRect.x, outputRect.center.y);
                        var end      = new Vector3(CurrentEvent.mousePosition.x, CurrentEvent.mousePosition.y);
                        var startDir = new Vector3(1, 0);
                        var endDir   = new Vector3(-1, 0);

                        if (!StyleLookup.TryGetValue(outputSocketInformation.Type, out var connectionStyle))
                        {
                            connectionStyle = StyleLookup["Error"];
                            Debug.LogWarning($"Couldn't find a style for connections of type \"{outputSocketInformation.Type}\".");
                        }

                        DrawConnection(start, end, startDir, endDir, connectionStyle.ConnectionColor);
                    }
                }
                else
                {
                    if (!StyleLookup.TryGetValue("Error", out var inputStyle))
                    {
                        inputStyle = StyleLookup["Error"];
                        Debug.LogWarning($"Couldn't find a style for connections of type \"Error\".");
                    }

                    var startFieldFeature = View.ConnectionInput.GetOrCreateFeature <FieldFeature>();

                    var inputSocketRect = startFieldFeature.InputSocketPosition;

                    var start    = new Vector3(CurrentEvent.mousePosition.x, CurrentEvent.mousePosition.y);
                    var end      = new Vector3(inputSocketRect.xMax, inputSocketRect.center.y);
                    var startDir = new Vector3(1, 0);
                    var endDir   = new Vector3(-1, 0);

                    DrawConnection(start, end, startDir, endDir, inputStyle.ConnectionColor);
                }
            }
        }
Example #5
0
        public void DrawConnections()
        {
            if (View.Session != null)
            {
                var graphEditorNodes = View.Session.Root["Nodes"];

                // Foreach output
                foreach (var node in graphEditorNodes)
                {
                    var nodeEditor         = node["Editor"];
                    var nodeEditorPosition = nodeEditor["Position"];

                    float nodePositionX = nodeEditorPosition["x"].GetValue <int> () + View.PanPosition.x;
                    float nodePositionY = nodeEditorPosition["y"].GetValue <int> () + View.PanPosition.y;

                    var nodeData = node["Data"];

                    // Foreach Output
                    var outputRect = new Rect(nodePositionX + 202, nodePositionY + 6, 20, 20);
                    var nodeInfo   = (NodeInformation)nodeData.Type;
                    foreach (var output in nodeInfo.Outputs)
                    {
                        if (CurrentEvent.type == EventType.Repaint)
                        {
                            EditorStyles.helpBox.Draw(outputRect, false, false, false, false);
                        }
                        else if (CurrentEvent.type == EventType.MouseDown && outputRect.Contains(CurrentEvent.mousePosition))
                        {
                            var outputId = new LocalPropertyId(new LocalId(node.Name), output.Key);
                            View.BeginConnectionFromOutput(outputId);

                            GUI.UnfocusWindow();
                            GUI.FocusControl("");

                            CurrentEvent.Use();
                        }
                        else if (CurrentEvent.type == EventType.MouseUp && outputRect.Contains(CurrentEvent.mousePosition))
                        {
                            if (View.CurrentMode == BehaviourEditorView.Mode.CreatingConnection)
                            {
                                if (!View.IsOutputSocket)
                                {
                                    var thisOutputSocket = new LocalPropertyId(new LocalId(node.Name), output.Key);

                                    View.ConnectionInput.SetValue(thisOutputSocket);
                                    View.ConnectionInput.ApplyModifiedProperties();
                                    View.CurrentMode = BehaviourEditorView.Mode.None;

                                    GUI.UnfocusWindow();
                                    GUI.FocusControl("");

                                    CurrentEvent.Use();
                                }
                            }
                        }

                        outputRect.y += outputRect.height + 4;
                    }

                    // Foreach Input
                    foreach (var childField in nodeData)
                    {
                        if (childField.Field.Type == "InputSocket")
                        {
                            var fieldFeature = childField.GetOrCreateFeature <FieldFeature> ();

                            fieldFeature.GlobalRenderedPosition = new Rect(
                                fieldFeature.LocalRenderedPosition.x + nodePositionX,
                                fieldFeature.LocalRenderedPosition.y + nodePositionY,
                                fieldFeature.LocalRenderedPosition.width,
                                fieldFeature.LocalRenderedPosition.height);

                            var socketRect = fieldFeature.InputSocketPosition;

                            if (CurrentEvent.type == EventType.Repaint)
                            {
                                EditorStyles.helpBox.Draw(socketRect, false, false, false, false);
                            }
                            else if (CurrentEvent.type == EventType.MouseDown && socketRect.Contains(CurrentEvent.mousePosition))
                            {
                                var thisInputId = new LocalPropertyId(new LocalId(node.Name), childField.Name);

                                View.BeginConnectionFromInput(childField, node.Name);

                                GUI.UnfocusWindow();
                                GUI.FocusControl("");

                                CurrentEvent.Use();
                            }
                            else if (CurrentEvent.type == EventType.MouseUp && socketRect.Contains(CurrentEvent.mousePosition))
                            {
                                if (View.CurrentMode == BehaviourEditorView.Mode.CreatingConnection)
                                {
                                    if (View.IsOutputSocket)
                                    {
                                        childField.SetValue(View.ConnectionOutput);
                                        childField.ApplyModifiedProperties();
                                        View.CurrentMode = BehaviourEditorView.Mode.None;

                                        GUI.UnfocusWindow();
                                        GUI.FocusControl("");

                                        CurrentEvent.Use();
                                    }
                                }
                            }

                            var thisInputConnectedTo = childField.GetValue <LocalPropertyId> ();
                            if (thisInputConnectedTo != LocalPropertyId.None)
                            {
                                bool foundNode       = false;
                                var  otherOutputRect = new Rect();
                                foreach (var otherNode in graphEditorNodes)
                                {
                                    var otherNodeEditor         = otherNode["Editor"];
                                    var otherNodeEditorPosition = otherNodeEditor["Position"];

                                    float otherNodePositionX = otherNodeEditorPosition["x"].GetValue <int> () + View.PanPosition.x;
                                    float otherNodePositionY = otherNodeEditorPosition["y"].GetValue <int> () + View.PanPosition.y;

                                    var otherNodeData = otherNode["Data"];

                                    // Foreach Output
                                    otherOutputRect = new Rect(otherNodePositionX + 202, otherNodePositionY + 6, 20, 20);
                                    var otherNodeInfo = (NodeInformation)otherNodeData.Type;
                                    foreach (var output in otherNodeInfo.Outputs)
                                    {
                                        var otherOutputId = new LocalPropertyId(new LocalId(otherNode.Name), output.Key);

                                        if (otherOutputId == thisInputConnectedTo)
                                        {
                                            foundNode = true;
                                            break;
                                        }

                                        otherOutputRect.y += otherOutputRect.height + 4;
                                    }
                                    if (foundNode)
                                    {
                                        break;
                                    }
                                }
                                if (foundNode)
                                {
                                    var start    = new Vector3(otherOutputRect.x, otherOutputRect.center.y);
                                    var end      = new Vector3(fieldFeature.GlobalRenderedPosition.x, fieldFeature.GlobalRenderedPosition.center.y);
                                    var startDir = new Vector3(1, 0);
                                    var endDir   = new Vector3(-1, 0);

                                    DrawConnection(start, end, startDir, endDir);
                                }
                            }
                        }
                    }
                }

                // Draw active connection
                if (View.CurrentMode == BehaviourEditorView.Mode.CreatingConnection)
                {
                    if (View.IsOutputSocket)
                    {
                        // Draw Nodes
                        bool isFound    = false;
                        var  outputRect = new Rect();
                        foreach (var node in graphEditorNodes)
                        {
                            var nodeEditor         = node["Editor"];
                            var nodeEditorPosition = nodeEditor["Position"];

                            float nodePositionX = nodeEditorPosition["x"].GetValue <int> () + View.PanPosition.x;
                            float nodePositionY = nodeEditorPosition["y"].GetValue <int> () + View.PanPosition.y;

                            var nodeData = node["Data"];

                            // Foreach Output
                            var nodeInfo = (NodeInformation)nodeData.Type;
                            outputRect = new Rect(nodePositionX + 202, nodePositionY + 6, 20, 20);
                            foreach (var output in nodeInfo.Outputs)
                            {
                                var otherOutputId = new LocalPropertyId(new LocalId(node.Name), output.Key);

                                if (otherOutputId == View.ConnectionOutput)
                                {
                                    isFound = true;
                                    break;
                                }

                                outputRect.y += outputRect.height + 4;
                            }
                            if (isFound)
                            {
                                break;
                            }
                        }

                        if (isFound)
                        {
                            var start    = new Vector3(outputRect.x, outputRect.center.y);
                            var end      = new Vector3(CurrentEvent.mousePosition.x, CurrentEvent.mousePosition.y);
                            var startDir = new Vector3(1, 0);
                            var endDir   = new Vector3(-1, 0);

                            DrawConnection(start, end, startDir, endDir);
                        }
                    }
                    else
                    {
                        var startFieldFeature = View.ConnectionInput.GetOrCreateFeature <FieldFeature> ();

                        var inputNode          = graphEditorNodes[View.ConnectionInputNodeId.ToString()];
                        var nodeEditor         = inputNode["Editor"];
                        var nodeEditorPosition = nodeEditor["Position"];

                        float nodePositionX = nodeEditorPosition["x"].GetValue <int> () + View.PanPosition.x;
                        float nodePositionY = nodeEditorPosition["y"].GetValue <int> () + View.PanPosition.y;

                        var nodeData = inputNode["Data"];

                        var socketRect = startFieldFeature.InputSocketPosition;

                        var start    = new Vector3(CurrentEvent.mousePosition.x, CurrentEvent.mousePosition.y);
                        var end      = new Vector3(socketRect.xMax, socketRect.center.y);
                        var startDir = new Vector3(1, 0);
                        var endDir   = new Vector3(-1, 0);

                        DrawConnection(start, end, startDir, endDir);
                    }
                }
            }
        }