diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs index 8a629e8..d7a4871 100644 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ b/Scripts/Editor/NodeEditorGUILayout.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; @@ -132,9 +134,75 @@ namespace XNodeEditor { Color col = GUI.color; GUI.color = backgroundColor; GUI.DrawTexture(rect, NodeEditorResources.dotOuter); - GUI.color = typeColor; + GUI.color = typeColor; GUI.DrawTexture(rect, NodeEditorResources.dot); GUI.color = col; } + + /// Draw an editable list of instance ports. Port names are named as "[fieldName] [index]" + /// Supply a list for editable values + /// Value type of added instance ports + /// The serializedObject of the node + /// Connection type of added instance ports + public static void InstancePortList(string fieldName, Type type, SerializedObject serializedObject, XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple) { + XNode.Node node = serializedObject.targetObject as XNode.Node; + SerializedProperty arrayData = serializedObject.FindProperty(fieldName); + bool hasArrayData = arrayData != null && arrayData.isArray; + int arraySize = hasArrayData ? arrayData.arraySize : 0; + + List instancePorts = node.InstancePorts.Where(x => x.fieldName.StartsWith(fieldName)).OrderBy(x => x.fieldName).ToList(); + + for (int i = 0; i < instancePorts.Count(); i++) { + GUILayout.BeginHorizontal(); + if (GUILayout.Button("-", GUILayout.Width(30))) { + // Clear the removed ports connections + instancePorts[i].ClearConnections(); + // Move following connections one step up to replace the missing connection + for (int k = i + 1; k < instancePorts.Count(); k++) { + for (int j = 0; j < instancePorts[k].ConnectionCount; j++) { + XNode.NodePort other = instancePorts[k].GetConnection(j); + instancePorts[k].Disconnect(other); + instancePorts[k - 1].Connect(other); + } + } + // Remove the last instance port, to avoid messing up the indexing + node.RemoveInstancePort(instancePorts[instancePorts.Count() - 1].fieldName); + serializedObject.Update(); + EditorUtility.SetDirty(node); + if (hasArrayData) { + arrayData.DeleteArrayElementAtIndex(i); + arraySize--; + } + i--; + } else { + if (hasArrayData) { + if (i < arraySize) { + SerializedProperty itemData = arrayData.GetArrayElementAtIndex(i); + if (itemData != null) EditorGUILayout.PropertyField(itemData, new GUIContent(ObjectNames.NicifyVariableName(fieldName) + " " + i)); + else EditorGUILayout.LabelField("[Missing array data]"); + } else EditorGUILayout.LabelField("[Out of bounds]"); + + } else { + EditorGUILayout.LabelField(instancePorts[i].fieldName); + } + NodeEditorGUILayout.PortField(new GUIContent(), node.GetPort(instancePorts[i].fieldName), GUILayout.Width(-4)); + } + GUILayout.EndHorizontal(); + } + GUILayout.BeginHorizontal(); + EditorGUILayout.Space(); + if (GUILayout.Button("+", GUILayout.Width(30))) { + + string newName = fieldName + " 0"; + int i = 0; + while (node.HasPort(newName)) newName = fieldName + " " + (++i); + + instancePorts.Add(node.AddInstanceOutput(type, connectionType, newName)); + serializedObject.Update(); + EditorUtility.SetDirty(node); + if (hasArrayData) arrayData.InsertArrayElementAtIndex(arraySize); + } + GUILayout.EndHorizontal(); + } } } \ No newline at end of file