mirror of
https://github.com/Siccity/xNode.git
synced 2025-12-21 17:56:06 +08:00
Merge branch 'reorderable-instanceportlist'
This commit is contained in:
commit
9845a7db0c
@ -1,14 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEditorInternal;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace XNodeEditor {
|
namespace XNodeEditor {
|
||||||
/// <summary> xNode-specific version of <see cref="EditorGUILayout"/> </summary>
|
/// <summary> xNode-specific version of <see cref="EditorGUILayout"/> </summary>
|
||||||
public static class NodeEditorGUILayout {
|
public static class NodeEditorGUILayout {
|
||||||
|
|
||||||
|
private static readonly Dictionary<UnityEngine.Object, Dictionary<string, ReorderableList>> reorderableListCache = new Dictionary<UnityEngine.Object, Dictionary<string, ReorderableList>>();
|
||||||
|
private static int reorderableListIndex = -1;
|
||||||
/// <summary> Make a field for a serialized property. Automatically displays relevant node port. </summary>
|
/// <summary> Make a field for a serialized property. Automatically displays relevant node port. </summary>
|
||||||
public static void PropertyField(SerializedProperty property, bool includeChildren = true, params GUILayoutOption[] options) {
|
public static void PropertyField(SerializedProperty property, bool includeChildren = true, params GUILayoutOption[] options) {
|
||||||
PropertyField(property, (GUIContent) null, includeChildren, options);
|
PropertyField(property, (GUIContent) null, includeChildren, options);
|
||||||
@ -50,7 +54,6 @@ namespace XNodeEditor {
|
|||||||
if (instancePortList) {
|
if (instancePortList) {
|
||||||
Type type = GetType(property);
|
Type type = GetType(property);
|
||||||
XNode.Node.ConnectionType connectionType = inputAttribute != null ? inputAttribute.connectionType : XNode.Node.ConnectionType.Multiple;
|
XNode.Node.ConnectionType connectionType = inputAttribute != null ? inputAttribute.connectionType : XNode.Node.ConnectionType.Multiple;
|
||||||
EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName));
|
|
||||||
InstancePortList(property.name, type, property.serializedObject, port.direction, connectionType);
|
InstancePortList(property.name, type, property.serializedObject, port.direction, connectionType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -87,7 +90,6 @@ namespace XNodeEditor {
|
|||||||
if (instancePortList) {
|
if (instancePortList) {
|
||||||
Type type = GetType(property);
|
Type type = GetType(property);
|
||||||
XNode.Node.ConnectionType connectionType = outputAttribute != null ? outputAttribute.connectionType : XNode.Node.ConnectionType.Multiple;
|
XNode.Node.ConnectionType connectionType = outputAttribute != null ? outputAttribute.connectionType : XNode.Node.ConnectionType.Multiple;
|
||||||
EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName));
|
|
||||||
InstancePortList(property.name, type, property.serializedObject, port.direction, connectionType);
|
InstancePortList(property.name, type, property.serializedObject, port.direction, connectionType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -142,7 +144,7 @@ namespace XNodeEditor {
|
|||||||
public static void PortField(GUIContent label, XNode.NodePort port, params GUILayoutOption[] options) {
|
public static void PortField(GUIContent label, XNode.NodePort port, params GUILayoutOption[] options) {
|
||||||
if (port == null) return;
|
if (port == null) return;
|
||||||
if (options == null) options = new GUILayoutOption[] { GUILayout.MinWidth(30) };
|
if (options == null) options = new GUILayoutOption[] { GUILayout.MinWidth(30) };
|
||||||
Rect rect = new Rect();
|
Vector2 position = Vector3.zero;
|
||||||
GUIContent content = label != null ? label : new GUIContent(ObjectNames.NicifyVariableName(port.fieldName));
|
GUIContent content = label != null ? label : new GUIContent(ObjectNames.NicifyVariableName(port.fieldName));
|
||||||
|
|
||||||
// If property is an input, display a regular property field and put a port handle on the left side
|
// If property is an input, display a regular property field and put a port handle on the left side
|
||||||
@ -150,18 +152,26 @@ namespace XNodeEditor {
|
|||||||
// Display a label
|
// Display a label
|
||||||
EditorGUILayout.LabelField(content, options);
|
EditorGUILayout.LabelField(content, options);
|
||||||
|
|
||||||
rect = GUILayoutUtility.GetLastRect();
|
Rect rect = GUILayoutUtility.GetLastRect();
|
||||||
rect.position = rect.position - new Vector2(16, 0);
|
position = rect.position - new Vector2(16, 0);
|
||||||
|
|
||||||
|
}
|
||||||
// If property is an output, display a text label and put a port handle on the right side
|
// If property is an output, display a text label and put a port handle on the right side
|
||||||
} else if (port.direction == XNode.NodePort.IO.Output) {
|
else if (port.direction == XNode.NodePort.IO.Output) {
|
||||||
// Display a label
|
// Display a label
|
||||||
EditorGUILayout.LabelField(content, NodeEditorResources.OutputPort, options);
|
EditorGUILayout.LabelField(content, NodeEditorResources.OutputPort, options);
|
||||||
|
|
||||||
rect = GUILayoutUtility.GetLastRect();
|
Rect rect = GUILayoutUtility.GetLastRect();
|
||||||
rect.position = rect.position + new Vector2(rect.width, 0);
|
position = rect.position + new Vector2(rect.width, 0);
|
||||||
|
}
|
||||||
|
PortField(position, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
rect.size = new Vector2(16, 16);
|
/// <summary> Make a simple port field. </summary>
|
||||||
|
public static void PortField(Vector2 position, XNode.NodePort port) {
|
||||||
|
if (port == null) return;
|
||||||
|
|
||||||
|
Rect rect = new Rect(position, new Vector2(16, 16));
|
||||||
|
|
||||||
Color backgroundColor = new Color32(90, 97, 105, 255);
|
Color backgroundColor = new Color32(90, 97, 105, 255);
|
||||||
Color tint;
|
Color tint;
|
||||||
@ -234,8 +244,6 @@ namespace XNodeEditor {
|
|||||||
public static void InstancePortList(string fieldName, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple) {
|
public static void InstancePortList(string fieldName, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple) {
|
||||||
XNode.Node node = serializedObject.targetObject as XNode.Node;
|
XNode.Node node = serializedObject.targetObject as XNode.Node;
|
||||||
SerializedProperty arrayData = serializedObject.FindProperty(fieldName);
|
SerializedProperty arrayData = serializedObject.FindProperty(fieldName);
|
||||||
bool hasArrayData = arrayData != null && arrayData.isArray;
|
|
||||||
int arraySize = hasArrayData ? arrayData.arraySize : 0;
|
|
||||||
|
|
||||||
Predicate<string> isMatchingInstancePort =
|
Predicate<string> isMatchingInstancePort =
|
||||||
x => {
|
x => {
|
||||||
@ -245,14 +253,112 @@ namespace XNodeEditor {
|
|||||||
};
|
};
|
||||||
List<XNode.NodePort> instancePorts = node.InstancePorts.Where(x => isMatchingInstancePort(x.fieldName)).OrderBy(x => x.fieldName).ToList();
|
List<XNode.NodePort> instancePorts = node.InstancePorts.Where(x => isMatchingInstancePort(x.fieldName)).OrderBy(x => x.fieldName).ToList();
|
||||||
|
|
||||||
for (int i = 0; i < instancePorts.Count(); i++) {
|
ReorderableList list = null;
|
||||||
GUILayout.BeginHorizontal();
|
Dictionary<string, ReorderableList> rlc;
|
||||||
// 'Remove' button
|
if (reorderableListCache.TryGetValue(serializedObject.targetObject, out rlc)) {
|
||||||
if (GUILayout.Button("-", EditorStyles.miniButton, GUILayout.ExpandWidth(false))) {
|
if (!rlc.TryGetValue(fieldName, out list)) list = null;
|
||||||
|
}
|
||||||
|
// If a ReorderableList isn't cached for this array, do so.
|
||||||
|
if (list == null) {
|
||||||
|
string label = serializedObject.FindProperty(fieldName).displayName;
|
||||||
|
list = CreateReorderableList(instancePorts, arrayData, type, serializedObject, io, label, connectionType);
|
||||||
|
if (reorderableListCache.TryGetValue(serializedObject.targetObject, out rlc)) rlc.Add(fieldName, list);
|
||||||
|
else reorderableListCache.Add(serializedObject.targetObject, new Dictionary<string, ReorderableList>() { { fieldName, list } });
|
||||||
|
}
|
||||||
|
list.list = instancePorts;
|
||||||
|
list.DoLayoutList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReorderableList CreateReorderableList(List<XNode.NodePort> instancePorts, SerializedProperty arrayData, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, string label, XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple) {
|
||||||
|
bool hasArrayData = arrayData != null && arrayData.isArray;
|
||||||
|
int arraySize = hasArrayData ? arrayData.arraySize : 0;
|
||||||
|
XNode.Node node = serializedObject.targetObject as XNode.Node;
|
||||||
|
ReorderableList list = new ReorderableList(instancePorts, null, true, true, true, true);
|
||||||
|
|
||||||
|
list.drawElementCallback =
|
||||||
|
(Rect rect, int index, bool isActive, bool isFocused) => {
|
||||||
|
XNode.NodePort port = node.GetPort(arrayData.name + " " + index);
|
||||||
|
if (hasArrayData) {
|
||||||
|
SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index);
|
||||||
|
EditorGUI.PropertyField(rect, itemData);
|
||||||
|
} else EditorGUI.LabelField(rect, port.fieldName);
|
||||||
|
Vector2 pos = rect.position + (port.IsOutput?new Vector2(rect.width + 6, 0) : new Vector2(-36, 0));
|
||||||
|
NodeEditorGUILayout.PortField(pos, port);
|
||||||
|
};
|
||||||
|
list.drawHeaderCallback =
|
||||||
|
(Rect rect) => {
|
||||||
|
EditorGUI.LabelField(rect, label);
|
||||||
|
};
|
||||||
|
list.onSelectCallback =
|
||||||
|
(ReorderableList rl) => {
|
||||||
|
reorderableListIndex = rl.index;
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply changes
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
serializedObject.Update();
|
||||||
|
NodeEditorWindow.current.Repaint();
|
||||||
|
EditorApplication.delayCall += NodeEditorWindow.current.Repaint;
|
||||||
|
};
|
||||||
|
list.onAddCallback =
|
||||||
|
(ReorderableList rl) => {
|
||||||
|
// Add instance port postfixed with an index number
|
||||||
|
string newName = arrayData.name + " 0";
|
||||||
|
int i = 0;
|
||||||
|
while (node.HasPort(newName)) newName = arrayData.name + " " + (++i);
|
||||||
|
|
||||||
|
if (io == XNode.NodePort.IO.Output) node.AddInstanceOutput(type, connectionType, newName);
|
||||||
|
else node.AddInstanceInput(type, connectionType, newName);
|
||||||
|
serializedObject.Update();
|
||||||
|
EditorUtility.SetDirty(node);
|
||||||
|
if (hasArrayData) arrayData.InsertArrayElementAtIndex(arraySize);
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
};
|
||||||
|
list.onRemoveCallback =
|
||||||
|
(ReorderableList rl) => {
|
||||||
|
int index = rl.index;
|
||||||
// Clear the removed ports connections
|
// Clear the removed ports connections
|
||||||
instancePorts[i].ClearConnections();
|
instancePorts[index].ClearConnections();
|
||||||
// Move following connections one step up to replace the missing connection
|
// Move following connections one step up to replace the missing connection
|
||||||
for (int k = i + 1; k < instancePorts.Count(); k++) {
|
for (int k = index + 1; k < instancePorts.Count(); k++) {
|
||||||
for (int j = 0; j < instancePorts[k].ConnectionCount; j++) {
|
for (int j = 0; j < instancePorts[k].ConnectionCount; j++) {
|
||||||
XNode.NodePort other = instancePorts[k].GetConnection(j);
|
XNode.NodePort other = instancePorts[k].GetConnection(j);
|
||||||
instancePorts[k].Disconnect(other);
|
instancePorts[k].Disconnect(other);
|
||||||
@ -264,7 +370,7 @@ namespace XNodeEditor {
|
|||||||
serializedObject.Update();
|
serializedObject.Update();
|
||||||
EditorUtility.SetDirty(node);
|
EditorUtility.SetDirty(node);
|
||||||
if (hasArrayData) {
|
if (hasArrayData) {
|
||||||
arrayData.DeleteArrayElementAtIndex(i);
|
arrayData.DeleteArrayElementAtIndex(index);
|
||||||
arraySize--;
|
arraySize--;
|
||||||
// Error handling. If the following happens too often, file a bug report at https://github.com/Siccity/xNode/issues
|
// Error handling. If the following happens too often, file a bug report at https://github.com/Siccity/xNode/issues
|
||||||
if (instancePorts.Count <= arraySize) {
|
if (instancePorts.Count <= arraySize) {
|
||||||
@ -276,42 +382,29 @@ namespace XNodeEditor {
|
|||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
serializedObject.Update();
|
serializedObject.Update();
|
||||||
}
|
}
|
||||||
i--;
|
|
||||||
GUILayout.EndHorizontal();
|
};
|
||||||
} else {
|
|
||||||
if (hasArrayData) {
|
if (hasArrayData) {
|
||||||
if (i < arraySize) {
|
int instancePortCount = instancePorts.Count;
|
||||||
SerializedProperty itemData = arrayData.GetArrayElementAtIndex(i);
|
while (instancePortCount < arraySize) {
|
||||||
if (itemData != null) EditorGUILayout.PropertyField(itemData, new GUIContent(ObjectNames.NicifyVariableName(fieldName) + " " + i), true);
|
// Add instance port postfixed with an index number
|
||||||
else EditorGUILayout.LabelField("[Missing array data]");
|
string newName = arrayData.name + " 0";
|
||||||
} else EditorGUILayout.LabelField("[Out of bounds]");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
EditorGUILayout.LabelField(ObjectNames.NicifyVariableName(instancePorts[i].fieldName));
|
|
||||||
}
|
|
||||||
|
|
||||||
GUILayout.EndHorizontal();
|
|
||||||
NodeEditorGUILayout.AddPortField(node.GetPort(instancePorts[i].fieldName));
|
|
||||||
}
|
|
||||||
// GUILayout.EndHorizontal();
|
|
||||||
}
|
|
||||||
GUILayout.BeginHorizontal();
|
|
||||||
GUILayout.FlexibleSpace();
|
|
||||||
// 'Add' button
|
|
||||||
if (GUILayout.Button("+", EditorStyles.miniButton, GUILayout.ExpandWidth(false))) {
|
|
||||||
|
|
||||||
string newName = fieldName + " 0";
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (node.HasPort(newName)) newName = fieldName + " " + (++i);
|
while (node.HasPort(newName)) newName = arrayData.name + " " + (++i);
|
||||||
|
|
||||||
if (io == XNode.NodePort.IO.Output) node.AddInstanceOutput(type, connectionType, newName);
|
if (io == XNode.NodePort.IO.Output) node.AddInstanceOutput(type, connectionType, newName);
|
||||||
else node.AddInstanceInput(type, connectionType, newName);
|
else node.AddInstanceInput(type, connectionType, newName);
|
||||||
serializedObject.Update();
|
|
||||||
EditorUtility.SetDirty(node);
|
EditorUtility.SetDirty(node);
|
||||||
if (hasArrayData) arrayData.InsertArrayElementAtIndex(arraySize);
|
instancePortCount++;
|
||||||
serializedObject.ApplyModifiedProperties();
|
|
||||||
}
|
}
|
||||||
GUILayout.EndHorizontal();
|
while (arraySize < instancePortCount) {
|
||||||
|
arrayData.InsertArrayElementAtIndex(arraySize);
|
||||||
|
arraySize++;
|
||||||
|
}
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
serializedObject.Update();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,24 +79,21 @@ namespace XNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Instance Ports
|
#region Instance Ports
|
||||||
/// <summary> Convenience function.
|
/// <summary> Convenience function. </summary>
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="AddInstancePort"/>
|
/// <seealso cref="AddInstancePort"/>
|
||||||
/// <seealso cref="AddInstanceOutput"/>
|
/// <seealso cref="AddInstanceOutput"/>
|
||||||
public NodePort AddInstanceInput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
public NodePort AddInstanceInput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
||||||
return AddInstancePort(type, NodePort.IO.Input, connectionType, fieldName);
|
return AddInstancePort(type, NodePort.IO.Input, connectionType, fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Convenience function.
|
/// <summary> Convenience function. </summary>
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="AddInstancePort"/>
|
/// <seealso cref="AddInstancePort"/>
|
||||||
/// <seealso cref="AddInstanceInput"/>
|
/// <seealso cref="AddInstanceInput"/>
|
||||||
public NodePort AddInstanceOutput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
public NodePort AddInstanceOutput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
||||||
return AddInstancePort(type, NodePort.IO.Output, connectionType, fieldName);
|
return AddInstancePort(type, NodePort.IO.Output, connectionType, fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Add a dynamic, serialized port to this node.
|
/// <summary> Add a dynamic, serialized port to this node. </summary>
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="AddInstanceInput"/>
|
/// <seealso cref="AddInstanceInput"/>
|
||||||
/// <seealso cref="AddInstanceOutput"/>
|
/// <seealso cref="AddInstanceOutput"/>
|
||||||
private NodePort AddInstancePort(Type type, NodePort.IO direction, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
private NodePort AddInstancePort(Type type, NodePort.IO direction, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
||||||
|
|||||||
@ -202,6 +202,15 @@ namespace XNode {
|
|||||||
port.node.OnCreateConnection(this, port);
|
port.node.OnCreateConnection(this, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<NodePort> GetConnections() {
|
||||||
|
List<NodePort> result = new List<NodePort>();
|
||||||
|
for (int i = 0; i < connections.Count; i++) {
|
||||||
|
NodePort port = GetConnection(i);
|
||||||
|
if (port != null) result.Add(port);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public NodePort GetConnection(int i) {
|
public NodePort GetConnection(int i) {
|
||||||
//If the connection is broken for some reason, remove it.
|
//If the connection is broken for some reason, remove it.
|
||||||
if (connections[i].node == null || string.IsNullOrEmpty(connections[i].fieldName)) {
|
if (connections[i].node == null || string.IsNullOrEmpty(connections[i].fieldName)) {
|
||||||
@ -252,6 +261,25 @@ namespace XNode {
|
|||||||
if (port != null) port.node.OnRemoveConnection(port);
|
if (port != null) port.node.OnRemoveConnection(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Disconnect this port from another port </summary>
|
||||||
|
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() {
|
public void ClearConnections() {
|
||||||
while (connections.Count > 0) {
|
while (connections.Count > 0) {
|
||||||
Disconnect(connections[0].Port);
|
Disconnect(connections[0].Port);
|
||||||
@ -263,6 +291,59 @@ namespace XNode {
|
|||||||
return connections[index].reroutePoints;
|
return connections[index].reroutePoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Swap connections with another node </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Copy all connections pointing to a node and add them to this one </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Move all connections pointing to this node, to another node </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Swap connected nodes from the old list with nodes from the new list </summary>
|
/// <summary> Swap connected nodes from the old list with nodes from the new list </summary>
|
||||||
public void Redirect(List<Node> oldNodes, List<Node> newNodes) {
|
public void Redirect(List<Node> oldNodes, List<Node> newNodes) {
|
||||||
foreach (PortConnection connection in connections) {
|
foreach (PortConnection connection in connections) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user