diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs index b8fdd50..4720950 100644 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ b/Scripts/Editor/NodeEditorGUILayout.cs @@ -295,39 +295,43 @@ namespace XNodeEditor { }; list.onReorderCallback = (ReorderableList rl) => { + + // Move up + if (rl.index > reorderableListIndex) { + for (int i = reorderableListIndex; i < rl.index; ++i) { + XNode.NodePort port = node.GetPort(arrayData.name + " " + i); + XNode.NodePort nextPort = node.GetPort(arrayData.name + " " + (i + 1)); + port.SwapConnections(nextPort); + + // Swap cached positions to mitigate twitching + Rect rect = NodeEditorWindow.current.portConnectionPoints[port]; + NodeEditorWindow.current.portConnectionPoints[port] = NodeEditorWindow.current.portConnectionPoints[nextPort]; + NodeEditorWindow.current.portConnectionPoints[nextPort] = rect; + } + } + // Move down + else { + for (int i = reorderableListIndex; i > rl.index; --i) { + XNode.NodePort port = node.GetPort(arrayData.name + " " + i); + XNode.NodePort nextPort = node.GetPort(arrayData.name + " " + (i - 1)); + port.SwapConnections(nextPort); + + // Swap cached positions to mitigate twitching + Rect rect = NodeEditorWindow.current.portConnectionPoints[port]; + NodeEditorWindow.current.portConnectionPoints[port] = NodeEditorWindow.current.portConnectionPoints[nextPort]; + NodeEditorWindow.current.portConnectionPoints[nextPort] = rect; + } + } + // Apply changes + serializedObject.ApplyModifiedProperties(); + serializedObject.Update(); + // Move array data if there is any if (hasArrayData) { SerializedProperty arrayDataOriginal = arrayData.Copy(); arrayData.MoveArrayElement(reorderableListIndex, rl.index); } - XNode.NodePort fromPort = node.GetPort(arrayData.name + " " + reorderableListIndex); - // Move connections - List fromConnections = fromPort.GetConnections(); - for (int i = 0; i < rl.list.Count - 1; ++i) { - if (i >= reorderableListIndex) { - XNode.NodePort port = node.GetPort(arrayData.name + " " + i); - XNode.NodePort targetPort = node.GetPort(arrayData.name + " " + (i + 1)); - port.ClearConnections(); - Debug.Log("Move " + targetPort.fieldName + " to " + port.fieldName); - List newConnections = targetPort.GetConnections(); - foreach (var c in newConnections) port.Connect(c); - } - } - for (int i = rl.list.Count - 1; i > 0; --i) { - if (i > rl.index) { - XNode.NodePort port = node.GetPort(arrayData.name + " " + i); - XNode.NodePort targetPort = node.GetPort(arrayData.name + " " + (i - 1)); - port.ClearConnections(); - Debug.Log("Move " + targetPort.fieldName + " to " + port.fieldName); - List newConnections = targetPort.GetConnections(); - foreach (var c in newConnections) port.Connect(c); - } - } - XNode.NodePort toPort = node.GetPort(arrayData.name + " " + rl.index); - toPort.ClearConnections(); - foreach (var c in fromConnections) toPort.Connect(c); - // Apply changes serializedObject.ApplyModifiedProperties(); serializedObject.Update(); diff --git a/Scripts/NodePort.cs b/Scripts/NodePort.cs index bd0217c..35ba41f 100644 --- a/Scripts/NodePort.cs +++ b/Scripts/NodePort.cs @@ -261,23 +261,89 @@ namespace XNode { if (port != null) port.node.OnRemoveConnection(port); } + /// Disconnect this port from another port + public void Disconnect(int i) { + // Remove the other ports connection to this port + NodePort otherPort = connections[i].Port; + if (otherPort != null) { + for (int k = 0; k < otherPort.connections.Count; k++) { + if (otherPort.connections[k].Port == this) { + otherPort.connections.RemoveAt(i); + } + } + } + // Remove this ports connection to the other + connections.RemoveAt(i); + + // Trigger OnRemoveConnection + node.OnRemoveConnection(this); + if (otherPort != null) otherPort.node.OnRemoveConnection(otherPort); + } + public void ClearConnections() { while (connections.Count > 0) { Disconnect(connections[0].Port); } } - /// Potentially dangerous. Use only with instance ports - /// - public void Rename(string fieldName) { - _fieldName = fieldName; - } - /// Get reroute points for a given connection. This is used for organization public List GetReroutePoints(int index) { return connections[index].reroutePoints; } + /// Swap connections with another node + public void SwapConnections(NodePort targetPort) { + int aConnectionCount = connections.Count; + int bConnectionCount = targetPort.connections.Count; + + // Add target port connections to this one + for (int i = 0; i < aConnectionCount; i++) { + PortConnection connection = connections[i]; + NodePort otherPort = connection.Port; + targetPort.Connect(otherPort); + } + + // Add connections to target port + for (int i = 0; i < bConnectionCount; i++) { + PortConnection connection = targetPort.connections[i]; + NodePort otherPort = connection.Port; + Connect(otherPort); + } + + // Remove starting connections on this port + for (int i = aConnectionCount - 1; i >= 0; i--) { + Disconnect(i); + } + + // Remove starting connections on target port + for (int i = bConnectionCount - 1; i >= 0; i--) { + targetPort.Disconnect(i); + } + } + + /// Copy all connections pointing to a node and add them to this one + public void AddConnections(NodePort targetPort) { + int connectionCount = targetPort.ConnectionCount; + for (int i = 0; i < connectionCount; i++) { + PortConnection connection = targetPort.connections[i]; + NodePort otherPort = connection.Port; + Connect(otherPort); + } + } + + /// Move all connections pointing to this node, to another node + public void MoveConnections(NodePort targetPort) { + int connectionCount = connections.Count; + + // Add connections to target port + for (int i = 0; i < connectionCount; i++) { + PortConnection connection = targetPort.connections[i]; + NodePort otherPort = connection.Port; + Connect(otherPort); + } + ClearConnections(); + } + /// Swap connected nodes from the old list with nodes from the new list public void Redirect(List oldNodes, List newNodes) { foreach (PortConnection connection in connections) {