From da9af2b100d77d5bf3e5bc5f2b7f5bf96de7c1b8 Mon Sep 17 00:00:00 2001 From: MowfaqAlarbi <54871067+MowfaqAlarbi@users.noreply.github.com> Date: Sat, 10 Jul 2021 09:26:36 +0200 Subject: [PATCH] Delete Scripts directory --- Scripts/Attributes.meta | 10 - Scripts/Attributes/NodeEnum.cs | 5 - Scripts/Attributes/NodeEnum.cs.meta | 13 - Scripts/Editor.meta | 9 - Scripts/Editor/Drawers.meta | 10 - Scripts/Editor/Drawers/NodeEnumDrawer.cs | 71 --- Scripts/Editor/Drawers/NodeEnumDrawer.cs.meta | 13 - Scripts/Editor/Drawers/Odin.meta | 8 - .../Odin/InNodeEditorAttributeProcessor.cs | 48 -- .../InNodeEditorAttributeProcessor.cs.meta | 11 - .../Drawers/Odin/InputAttributeDrawer.cs | 49 -- .../Drawers/Odin/InputAttributeDrawer.cs.meta | 11 - .../Drawers/Odin/OutputAttributeDrawer.cs | 49 -- .../Odin/OutputAttributeDrawer.cs.meta | 11 - Scripts/Editor/Internal.meta | 8 - Scripts/Editor/Internal/RerouteReference.cs | 20 - .../Editor/Internal/RerouteReference.cs.meta | 11 - Scripts/Editor/NodeEditor.cs | 149 ------ Scripts/Editor/NodeEditor.cs.meta | 12 - Scripts/Editor/NodeEditorAction.cs | 506 ------------------ Scripts/Editor/NodeEditorAction.cs.meta | 12 - Scripts/Editor/NodeEditorAssetModProcessor.cs | 62 --- .../NodeEditorAssetModProcessor.cs.meta | 12 - Scripts/Editor/NodeEditorBase.cs | 91 ---- Scripts/Editor/NodeEditorBase.cs.meta | 13 - Scripts/Editor/NodeEditorGUI.cs | 428 --------------- Scripts/Editor/NodeEditorGUI.cs.meta | 11 - Scripts/Editor/NodeEditorGUILayout.cs | 490 ----------------- Scripts/Editor/NodeEditorGUILayout.cs.meta | 12 - Scripts/Editor/NodeEditorPreferences.cs | 241 --------- Scripts/Editor/NodeEditorPreferences.cs.meta | 12 - Scripts/Editor/NodeEditorReflection.cs | 180 ------- Scripts/Editor/NodeEditorReflection.cs.meta | 12 - Scripts/Editor/NodeEditorResources.cs | 87 --- Scripts/Editor/NodeEditorResources.cs.meta | 12 - Scripts/Editor/NodeEditorUtilities.cs | 243 --------- Scripts/Editor/NodeEditorUtilities.cs.meta | 12 - Scripts/Editor/NodeEditorWindow.cs | 206 ------- Scripts/Editor/NodeEditorWindow.cs.meta | 12 - Scripts/Editor/NodeGraphEditor.cs | 133 ----- Scripts/Editor/NodeGraphEditor.cs.meta | 12 - Scripts/Editor/RenamePopup.cs | 68 --- Scripts/Editor/RenamePopup.cs.meta | 13 - Scripts/Editor/Resources.meta | 9 - Scripts/Editor/Resources/ScriptTemplates.meta | 10 - .../xNode_NodeGraphTemplate.cs.txt | 9 - .../xNode_NodeGraphTemplate.cs.txt.meta | 9 - .../ScriptTemplates/xNode_NodeTemplate.cs.txt | 18 - .../xNode_NodeTemplate.cs.txt.meta | 9 - Scripts/Editor/Resources/xnode_dot.png | Bin 18297 -> 0 bytes Scripts/Editor/Resources/xnode_dot.png.meta | 98 ---- Scripts/Editor/Resources/xnode_dot_outer.png | Bin 18346 -> 0 bytes .../Editor/Resources/xnode_dot_outer.png.meta | 98 ---- Scripts/Editor/Resources/xnode_node.png | Bin 20191 -> 0 bytes Scripts/Editor/Resources/xnode_node.png.meta | 98 ---- .../Editor/Resources/xnode_node_highlight.png | Bin 20433 -> 0 bytes .../Resources/xnode_node_highlight.png.meta | 87 --- .../Editor/Resources/xnode_node_workfile.psd | Bin 33269 -> 0 bytes .../Resources/xnode_node_workfile.psd.meta | 98 ---- Scripts/Editor/XNodeEditor.asmdef | 17 - Scripts/Editor/XNodeEditor.asmdef.meta | 7 - Scripts/Node.cs | 386 ------------- Scripts/Node.cs.meta | 12 - Scripts/NodeDataCache.cs | 154 ------ Scripts/NodeDataCache.cs.meta | 12 - Scripts/NodeGraph.cs | 85 --- Scripts/NodeGraph.cs.meta | 12 - Scripts/NodePort.cs | 403 -------------- Scripts/NodePort.cs.meta | 12 - Scripts/XNode.asmdef | 13 - Scripts/XNode.asmdef.meta | 7 - 71 files changed, 5061 deletions(-) delete mode 100644 Scripts/Attributes.meta delete mode 100644 Scripts/Attributes/NodeEnum.cs delete mode 100644 Scripts/Attributes/NodeEnum.cs.meta delete mode 100644 Scripts/Editor.meta delete mode 100644 Scripts/Editor/Drawers.meta delete mode 100644 Scripts/Editor/Drawers/NodeEnumDrawer.cs delete mode 100644 Scripts/Editor/Drawers/NodeEnumDrawer.cs.meta delete mode 100644 Scripts/Editor/Drawers/Odin.meta delete mode 100644 Scripts/Editor/Drawers/Odin/InNodeEditorAttributeProcessor.cs delete mode 100644 Scripts/Editor/Drawers/Odin/InNodeEditorAttributeProcessor.cs.meta delete mode 100644 Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs delete mode 100644 Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs.meta delete mode 100644 Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs delete mode 100644 Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs.meta delete mode 100644 Scripts/Editor/Internal.meta delete mode 100644 Scripts/Editor/Internal/RerouteReference.cs delete mode 100644 Scripts/Editor/Internal/RerouteReference.cs.meta delete mode 100644 Scripts/Editor/NodeEditor.cs delete mode 100644 Scripts/Editor/NodeEditor.cs.meta delete mode 100644 Scripts/Editor/NodeEditorAction.cs delete mode 100644 Scripts/Editor/NodeEditorAction.cs.meta delete mode 100644 Scripts/Editor/NodeEditorAssetModProcessor.cs delete mode 100644 Scripts/Editor/NodeEditorAssetModProcessor.cs.meta delete mode 100644 Scripts/Editor/NodeEditorBase.cs delete mode 100644 Scripts/Editor/NodeEditorBase.cs.meta delete mode 100644 Scripts/Editor/NodeEditorGUI.cs delete mode 100644 Scripts/Editor/NodeEditorGUI.cs.meta delete mode 100644 Scripts/Editor/NodeEditorGUILayout.cs delete mode 100644 Scripts/Editor/NodeEditorGUILayout.cs.meta delete mode 100644 Scripts/Editor/NodeEditorPreferences.cs delete mode 100644 Scripts/Editor/NodeEditorPreferences.cs.meta delete mode 100644 Scripts/Editor/NodeEditorReflection.cs delete mode 100644 Scripts/Editor/NodeEditorReflection.cs.meta delete mode 100644 Scripts/Editor/NodeEditorResources.cs delete mode 100644 Scripts/Editor/NodeEditorResources.cs.meta delete mode 100644 Scripts/Editor/NodeEditorUtilities.cs delete mode 100644 Scripts/Editor/NodeEditorUtilities.cs.meta delete mode 100644 Scripts/Editor/NodeEditorWindow.cs delete mode 100644 Scripts/Editor/NodeEditorWindow.cs.meta delete mode 100644 Scripts/Editor/NodeGraphEditor.cs delete mode 100644 Scripts/Editor/NodeGraphEditor.cs.meta delete mode 100644 Scripts/Editor/RenamePopup.cs delete mode 100644 Scripts/Editor/RenamePopup.cs.meta delete mode 100644 Scripts/Editor/Resources.meta delete mode 100644 Scripts/Editor/Resources/ScriptTemplates.meta delete mode 100644 Scripts/Editor/Resources/ScriptTemplates/xNode_NodeGraphTemplate.cs.txt delete mode 100644 Scripts/Editor/Resources/ScriptTemplates/xNode_NodeGraphTemplate.cs.txt.meta delete mode 100644 Scripts/Editor/Resources/ScriptTemplates/xNode_NodeTemplate.cs.txt delete mode 100644 Scripts/Editor/Resources/ScriptTemplates/xNode_NodeTemplate.cs.txt.meta delete mode 100644 Scripts/Editor/Resources/xnode_dot.png delete mode 100644 Scripts/Editor/Resources/xnode_dot.png.meta delete mode 100644 Scripts/Editor/Resources/xnode_dot_outer.png delete mode 100644 Scripts/Editor/Resources/xnode_dot_outer.png.meta delete mode 100644 Scripts/Editor/Resources/xnode_node.png delete mode 100644 Scripts/Editor/Resources/xnode_node.png.meta delete mode 100644 Scripts/Editor/Resources/xnode_node_highlight.png delete mode 100644 Scripts/Editor/Resources/xnode_node_highlight.png.meta delete mode 100644 Scripts/Editor/Resources/xnode_node_workfile.psd delete mode 100644 Scripts/Editor/Resources/xnode_node_workfile.psd.meta delete mode 100644 Scripts/Editor/XNodeEditor.asmdef delete mode 100644 Scripts/Editor/XNodeEditor.asmdef.meta delete mode 100644 Scripts/Node.cs delete mode 100644 Scripts/Node.cs.meta delete mode 100644 Scripts/NodeDataCache.cs delete mode 100644 Scripts/NodeDataCache.cs.meta delete mode 100644 Scripts/NodeGraph.cs delete mode 100644 Scripts/NodeGraph.cs.meta delete mode 100644 Scripts/NodePort.cs delete mode 100644 Scripts/NodePort.cs.meta delete mode 100644 Scripts/XNode.asmdef delete mode 100644 Scripts/XNode.asmdef.meta diff --git a/Scripts/Attributes.meta b/Scripts/Attributes.meta deleted file mode 100644 index c0be849..0000000 --- a/Scripts/Attributes.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 5644dfc7eed151045af664a9d4fd1906 -folderAsset: yes -timeCreated: 1541633926 -licenseType: Free -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/NodeEnum.cs b/Scripts/Attributes/NodeEnum.cs deleted file mode 100644 index 9cdaef4..0000000 --- a/Scripts/Attributes/NodeEnum.cs +++ /dev/null @@ -1,5 +0,0 @@ -using UnityEngine; - -/// Draw enums correctly within nodes. Without it, enums show up at the wrong positions. -/// Enums with this attribute are not detected by EditorGui.ChangeCheck due to waiting before executing -public class NodeEnumAttribute : PropertyAttribute { } \ No newline at end of file diff --git a/Scripts/Attributes/NodeEnum.cs.meta b/Scripts/Attributes/NodeEnum.cs.meta deleted file mode 100644 index 813a80b..0000000 --- a/Scripts/Attributes/NodeEnum.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 10a8338f6c985854697b35459181af0a -timeCreated: 1541633942 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor.meta b/Scripts/Editor.meta deleted file mode 100644 index b0ba142..0000000 --- a/Scripts/Editor.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 94d4fd78d9120634ebe0e8717610c412 -folderAsset: yes -timeCreated: 1505418345 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Drawers.meta b/Scripts/Editor/Drawers.meta deleted file mode 100644 index b69e0ac..0000000 --- a/Scripts/Editor/Drawers.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 7adf21edfb51f514fa991d7556ecd0ef -folderAsset: yes -timeCreated: 1541971984 -licenseType: Free -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Drawers/NodeEnumDrawer.cs b/Scripts/Editor/Drawers/NodeEnumDrawer.cs deleted file mode 100644 index 8aa748c..0000000 --- a/Scripts/Editor/Drawers/NodeEnumDrawer.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using XNode; -using XNodeEditor; - -namespace XNodeEditor { - [CustomPropertyDrawer(typeof(NodeEnumAttribute))] - public class NodeEnumDrawer : PropertyDrawer { - public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { - EditorGUI.BeginProperty(position, label, property); - - EnumPopup(position, property, label); - - EditorGUI.EndProperty(); - } - - public static void EnumPopup(Rect position, SerializedProperty property, GUIContent label) { - // Throw error on wrong type - if (property.propertyType != SerializedPropertyType.Enum) { - throw new ArgumentException("Parameter selected must be of type System.Enum"); - } - - // Add label - position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); - - // Get current enum name - string enumName = ""; - if (property.enumValueIndex >= 0 && property.enumValueIndex < property.enumDisplayNames.Length) enumName = property.enumDisplayNames[property.enumValueIndex]; - -#if UNITY_2017_1_OR_NEWER - // Display dropdown - if (EditorGUI.DropdownButton(position, new GUIContent(enumName), FocusType.Passive)) { - // Position is all wrong if we show the dropdown during the node draw phase. - // Instead, add it to onLateGUI to display it later. - NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property); - } -#else - // Display dropdown - if (GUI.Button(position, new GUIContent(enumName), "MiniPopup")) { - // Position is all wrong if we show the dropdown during the node draw phase. - // Instead, add it to onLateGUI to display it later. - NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property); - } -#endif - } - - public static void ShowContextMenuAtMouse(SerializedProperty property) { - // Initialize menu - GenericMenu menu = new GenericMenu(); - - // Add all enum display names to menu - for (int i = 0; i < property.enumDisplayNames.Length; i++) { - int index = i; - menu.AddItem(new GUIContent(property.enumDisplayNames[i]), false, () => SetEnum(property, index)); - } - - // Display at cursor position - Rect r = new Rect(Event.current.mousePosition, new Vector2(0, 0)); - menu.DropDown(r); - } - - private static void SetEnum(SerializedProperty property, int index) { - property.enumValueIndex = index; - property.serializedObject.ApplyModifiedProperties(); - property.serializedObject.Update(); - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/Drawers/NodeEnumDrawer.cs.meta b/Scripts/Editor/Drawers/NodeEnumDrawer.cs.meta deleted file mode 100644 index beacf6b..0000000 --- a/Scripts/Editor/Drawers/NodeEnumDrawer.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 83db81f92abadca439507e25d517cabe -timeCreated: 1541633798 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Drawers/Odin.meta b/Scripts/Editor/Drawers/Odin.meta deleted file mode 100644 index c2b0ac9..0000000 --- a/Scripts/Editor/Drawers/Odin.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 327994a52f523b641898a39ff7500a02 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Drawers/Odin/InNodeEditorAttributeProcessor.cs b/Scripts/Editor/Drawers/Odin/InNodeEditorAttributeProcessor.cs deleted file mode 100644 index 84c6d8e..0000000 --- a/Scripts/Editor/Drawers/Odin/InNodeEditorAttributeProcessor.cs +++ /dev/null @@ -1,48 +0,0 @@ -#if UNITY_EDITOR && ODIN_INSPECTOR -using System; -using System.Collections.Generic; -using System.Reflection; -using Sirenix.OdinInspector.Editor; -using UnityEngine; -using XNode; - -namespace XNodeEditor { - internal class OdinNodeInGraphAttributeProcessor : OdinAttributeProcessor where T : Node { - public override bool CanProcessSelfAttributes(InspectorProperty property) { - return false; - } - - public override bool CanProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member) { - if (!NodeEditor.inNodeEditor) - return false; - - if (member.MemberType == MemberTypes.Field) { - switch (member.Name) { - case "graph": - case "position": - case "ports": - return true; - - default: - break; - } - } - - return false; - } - - public override void ProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member, List attributes) { - switch (member.Name) { - case "graph": - case "position": - case "ports": - attributes.Add(new HideInInspector()); - break; - - default: - break; - } - } - } -} -#endif \ No newline at end of file diff --git a/Scripts/Editor/Drawers/Odin/InNodeEditorAttributeProcessor.cs.meta b/Scripts/Editor/Drawers/Odin/InNodeEditorAttributeProcessor.cs.meta deleted file mode 100644 index 15f6990..0000000 --- a/Scripts/Editor/Drawers/Odin/InNodeEditorAttributeProcessor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3cf2561fbfea9a041ac81efbbb5b3e0d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs b/Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs deleted file mode 100644 index a384bdc..0000000 --- a/Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs +++ /dev/null @@ -1,49 +0,0 @@ -#if UNITY_EDITOR && ODIN_INSPECTOR -using Sirenix.OdinInspector; -using Sirenix.OdinInspector.Editor; -using Sirenix.Utilities.Editor; -using UnityEngine; -using XNode; - -namespace XNodeEditor { - public class InputAttributeDrawer : OdinAttributeDrawer { - protected override bool CanDrawAttributeProperty(InspectorProperty property) { - Node node = property.Tree.WeakTargets[0] as Node; - return node != null; - } - - protected override void DrawPropertyLayout(GUIContent label) { - Node node = Property.Tree.WeakTargets[0] as Node; - NodePort port = node.GetInputPort(Property.Name); - - if (!NodeEditor.inNodeEditor) { - if (Attribute.backingValue == XNode.Node.ShowBackingValue.Always || Attribute.backingValue == XNode.Node.ShowBackingValue.Unconnected && !port.IsConnected) - CallNextDrawer(label); - return; - } - - if (Property.Tree.WeakTargets.Count > 1) { - SirenixEditorGUI.WarningMessageBox("Cannot draw ports with multiple nodes selected"); - return; - } - - if (port != null) { - var portPropoerty = Property.Tree.GetUnityPropertyForPath(Property.UnityPropertyPath); - if (portPropoerty == null) { - SirenixEditorGUI.ErrorMessageBox("Port property missing at: " + Property.UnityPropertyPath); - return; - } else { - var labelWidth = Property.GetAttribute(); - if (labelWidth != null) - GUIHelper.PushLabelWidth(labelWidth.Width); - - NodeEditorGUILayout.PropertyField(portPropoerty, label == null ? GUIContent.none : label, true, GUILayout.MinWidth(30)); - - if (labelWidth != null) - GUIHelper.PopLabelWidth(); - } - } - } - } -} -#endif \ No newline at end of file diff --git a/Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs.meta b/Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs.meta deleted file mode 100644 index 12b7615..0000000 --- a/Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2fd590b2e9ea0bd49b6986a2ca9010ab -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs b/Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs deleted file mode 100644 index ff59615..0000000 --- a/Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs +++ /dev/null @@ -1,49 +0,0 @@ -#if UNITY_EDITOR && ODIN_INSPECTOR -using Sirenix.OdinInspector; -using Sirenix.OdinInspector.Editor; -using Sirenix.Utilities.Editor; -using UnityEngine; -using XNode; - -namespace XNodeEditor { - public class OutputAttributeDrawer : OdinAttributeDrawer { - protected override bool CanDrawAttributeProperty(InspectorProperty property) { - Node node = property.Tree.WeakTargets[0] as Node; - return node != null; - } - - protected override void DrawPropertyLayout(GUIContent label) { - Node node = Property.Tree.WeakTargets[0] as Node; - NodePort port = node.GetOutputPort(Property.Name); - - if (!NodeEditor.inNodeEditor) { - if (Attribute.backingValue == XNode.Node.ShowBackingValue.Always || Attribute.backingValue == XNode.Node.ShowBackingValue.Unconnected && !port.IsConnected) - CallNextDrawer(label); - return; - } - - if (Property.Tree.WeakTargets.Count > 1) { - SirenixEditorGUI.WarningMessageBox("Cannot draw ports with multiple nodes selected"); - return; - } - - if (port != null) { - var portPropoerty = Property.Tree.GetUnityPropertyForPath(Property.UnityPropertyPath); - if (portPropoerty == null) { - SirenixEditorGUI.ErrorMessageBox("Port property missing at: " + Property.UnityPropertyPath); - return; - } else { - var labelWidth = Property.GetAttribute(); - if (labelWidth != null) - GUIHelper.PushLabelWidth(labelWidth.Width); - - NodeEditorGUILayout.PropertyField(portPropoerty, label == null ? GUIContent.none : label, true, GUILayout.MinWidth(30)); - - if (labelWidth != null) - GUIHelper.PopLabelWidth(); - } - } - } - } -} -#endif \ No newline at end of file diff --git a/Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs.meta b/Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs.meta deleted file mode 100644 index aa22218..0000000 --- a/Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e7ebd8f2b42e2384aa109551dc46af88 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Internal.meta b/Scripts/Editor/Internal.meta deleted file mode 100644 index 600ad29..0000000 --- a/Scripts/Editor/Internal.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a6a1bbc054e282346a02e7bbddde3206 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Internal/RerouteReference.cs b/Scripts/Editor/Internal/RerouteReference.cs deleted file mode 100644 index 4e21130..0000000 --- a/Scripts/Editor/Internal/RerouteReference.cs +++ /dev/null @@ -1,20 +0,0 @@ -using UnityEngine; - -namespace XNodeEditor.Internal { - public struct RerouteReference { - public XNode.NodePort port; - public int connectionIndex; - public int pointIndex; - - public RerouteReference(XNode.NodePort port, int connectionIndex, int pointIndex) { - this.port = port; - this.connectionIndex = connectionIndex; - this.pointIndex = pointIndex; - } - - public void InsertPoint(Vector2 pos) { port.GetReroutePoints(connectionIndex).Insert(pointIndex, pos); } - public void SetPoint(Vector2 pos) { port.GetReroutePoints(connectionIndex) [pointIndex] = pos; } - public void RemovePoint() { port.GetReroutePoints(connectionIndex).RemoveAt(pointIndex); } - public Vector2 GetPoint() { return port.GetReroutePoints(connectionIndex) [pointIndex]; } - } -} \ No newline at end of file diff --git a/Scripts/Editor/Internal/RerouteReference.cs.meta b/Scripts/Editor/Internal/RerouteReference.cs.meta deleted file mode 100644 index 9a2f9cb..0000000 --- a/Scripts/Editor/Internal/RerouteReference.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 399f3c5fb717b2c458c3e9746f8959a3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs deleted file mode 100644 index 8d293ab..0000000 --- a/Scripts/Editor/NodeEditor.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -#if ODIN_INSPECTOR -using Sirenix.OdinInspector.Editor; -using Sirenix.Utilities; -using Sirenix.Utilities.Editor; -#endif - -namespace XNodeEditor { - /// Base class to derive custom Node editors from. Use this to create your own custom inspectors and editors for your nodes. - [CustomNodeEditor(typeof(XNode.Node))] - public class NodeEditor : XNodeEditor.Internal.NodeEditorBase { - - private readonly Color DEFAULTCOLOR = new Color32(90, 97, 105, 255); - - /// Fires every whenever a node was modified through the editor - public static Action onUpdateNode; - public readonly static Dictionary portPositions = new Dictionary(); - -#if ODIN_INSPECTOR - internal static bool inNodeEditor = false; -#endif - - public virtual void OnHeaderGUI() { - GUILayout.Label(target.name, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30)); - } - - /// Draws standard field editors for all public fields - public virtual void OnBodyGUI() { -#if ODIN_INSPECTOR - inNodeEditor = true; -#endif - - // Unity specifically requires this to save/update any serial object. - // serializedObject.Update(); must go at the start of an inspector gui, and - // serializedObject.ApplyModifiedProperties(); goes at the end. - serializedObject.Update(); - string[] excludes = { "m_Script", "graph", "position", "ports" }; - -#if ODIN_INSPECTOR - InspectorUtilities.BeginDrawPropertyTree(objectTree, true); - GUIHelper.PushLabelWidth(84); - objectTree.Draw(true); - InspectorUtilities.EndDrawPropertyTree(objectTree); - GUIHelper.PopLabelWidth(); -#else - - // Iterate through serialized properties and draw them like the Inspector (But with ports) - SerializedProperty iterator = serializedObject.GetIterator(); - bool enterChildren = true; - EditorGUIUtility.labelWidth = 84; - while (iterator.NextVisible(enterChildren)) { - enterChildren = false; - if (excludes.Contains(iterator.name)) continue; - NodeEditorGUILayout.PropertyField(iterator, true); - } -#endif - - // Iterate through dynamic ports and draw them in the order in which they are serialized - foreach (XNode.NodePort dynamicPort in target.DynamicPorts) { - if (NodeEditorGUILayout.IsDynamicPortListPort(dynamicPort)) continue; - NodeEditorGUILayout.PortField(dynamicPort); - } - - serializedObject.ApplyModifiedProperties(); - -#if ODIN_INSPECTOR - // Call repaint so that the graph window elements respond properly to layout changes coming from Odin - if (GUIHelper.RepaintRequested) { - GUIHelper.ClearRepaintRequest(); - window.Repaint(); - } -#else - window.Repaint(); -#endif - -#if ODIN_INSPECTOR - inNodeEditor = false; -#endif - } - - public virtual int GetWidth() { - Type type = target.GetType(); - int width; - if (type.TryGetAttributeWidth(out width)) return width; - else return 208; - } - - /// Returns color for target node - public virtual Color GetTint() { - // Try get color from [NodeTint] attribute - Type type = target.GetType(); - Color color; - if (type.TryGetAttributeTint(out color)) return color; - // Return default color (grey) - else return DEFAULTCOLOR; - } - - public virtual GUIStyle GetBodyStyle() { - return NodeEditorResources.styles.nodeBody; - } - - /// Add items for the context menu when right-clicking this node. Override to add custom menu items. - public virtual void AddContextMenuItems(GenericMenu menu) { - // Actions if only one node is selected - if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) { - XNode.Node node = Selection.activeObject as XNode.Node; - menu.AddItem(new GUIContent("Move To Top"), false, () => NodeEditorWindow.current.MoveNodeToTop(node)); - menu.AddItem(new GUIContent("Rename"), false, NodeEditorWindow.current.RenameSelectedNode); - } - - // Add actions to any number of selected nodes - menu.AddItem(new GUIContent("Copy"), false, NodeEditorWindow.current.CopySelectedNodes); - menu.AddItem(new GUIContent("Duplicate"), false, NodeEditorWindow.current.DuplicateSelectedNodes); - menu.AddItem(new GUIContent("Remove"), false, NodeEditorWindow.current.RemoveSelectedNodes); - - // Custom sctions if only one node is selected - if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) { - XNode.Node node = Selection.activeObject as XNode.Node; - menu.AddCustomContextMenuItems(node); - } - } - - /// Rename the node asset. This will trigger a reimport of the node. - public void Rename(string newName) { - if (newName == null || newName.Trim() == "") newName = NodeEditorUtilities.NodeDefaultName(target.GetType()); - target.name = newName; - AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target)); - } - - [AttributeUsage(AttributeTargets.Class)] - public class CustomNodeEditorAttribute : Attribute, - XNodeEditor.Internal.NodeEditorBase.INodeEditorAttrib { - private Type inspectedType; - /// Tells a NodeEditor which Node type it is an editor for - /// Type that this editor can edit - public CustomNodeEditorAttribute(Type inspectedType) { - this.inspectedType = inspectedType; - } - - public Type GetInspectedType() { - return inspectedType; - } - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditor.cs.meta b/Scripts/Editor/NodeEditor.cs.meta deleted file mode 100644 index db8651d..0000000 --- a/Scripts/Editor/NodeEditor.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 712c3fc5d9eeb4c45b1e23918df6018f -timeCreated: 1505462176 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs deleted file mode 100644 index 2099d9c..0000000 --- a/Scripts/Editor/NodeEditorAction.cs +++ /dev/null @@ -1,506 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -using XNodeEditor.Internal; - -namespace XNodeEditor { - public partial class NodeEditorWindow { - public enum NodeActivity { Idle, HoldNode, DragNode, HoldGrid, DragGrid } - public static NodeActivity currentActivity = NodeActivity.Idle; - public static bool isPanning { get; private set; } - public static Vector2[] dragOffset; - - public static XNode.Node[] copyBuffer = null; - - private bool IsDraggingPort { get { return draggedOutput != null; } } - private bool IsHoveringPort { get { return hoveredPort != null; } } - private bool IsHoveringNode { get { return hoveredNode != null; } } - private bool IsHoveringReroute { get { return hoveredReroute.port != null; } } - private XNode.Node hoveredNode = null; - [NonSerialized] private XNode.NodePort hoveredPort = null; - [NonSerialized] private XNode.NodePort draggedOutput = null; - [NonSerialized] private XNode.NodePort draggedOutputTarget = null; - [NonSerialized] private List draggedOutputReroutes = new List(); - private RerouteReference hoveredReroute = new RerouteReference(); - private List selectedReroutes = new List(); - private Vector2 dragBoxStart; - private UnityEngine.Object[] preBoxSelection; - private RerouteReference[] preBoxSelectionReroute; - private Rect selectionBox; - private bool isDoubleClick = false; - private Vector2 lastMousePosition; - - public void Controls() { - wantsMouseMove = true; - Event e = Event.current; - switch (e.type) { - case EventType.DragUpdated: - case EventType.DragPerform: - DragAndDrop.visualMode = DragAndDropVisualMode.Generic; - if (e.type == EventType.DragPerform) { - DragAndDrop.AcceptDrag(); - graphEditor.OnDropObjects(DragAndDrop.objectReferences); - } - break; - case EventType.MouseMove: - //Keyboard commands will not get correct mouse position from Event - lastMousePosition = e.mousePosition; - break; - case EventType.ScrollWheel: - float oldZoom = zoom; - if (e.delta.y > 0) zoom += 0.1f * zoom; - else zoom -= 0.1f * zoom; - if (NodeEditorPreferences.GetSettings().zoomToMouse) panOffset += (1 - oldZoom / zoom) * (WindowToGridPosition(e.mousePosition) + panOffset); - break; - case EventType.MouseDrag: - if (e.button == 0) { - if (IsDraggingPort) { - if (IsHoveringPort && hoveredPort.IsInput && draggedOutput.CanConnectTo(hoveredPort)) { - if (!draggedOutput.IsConnectedTo(hoveredPort)) { - draggedOutputTarget = hoveredPort; - } - } else { - draggedOutputTarget = null; - } - Repaint(); - } else if (currentActivity == NodeActivity.HoldNode) { - RecalculateDragOffsets(e); - currentActivity = NodeActivity.DragNode; - Repaint(); - } - if (currentActivity == NodeActivity.DragNode) { - // Holding ctrl inverts grid snap - bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap; - if (e.control) gridSnap = !gridSnap; - - Vector2 mousePos = WindowToGridPosition(e.mousePosition); - // Move selected nodes with offset - for (int i = 0; i < Selection.objects.Length; i++) { - if (Selection.objects[i] is XNode.Node) { - XNode.Node node = Selection.objects[i] as XNode.Node; - Vector2 initial = node.position; - node.position = mousePos + dragOffset[i]; - if (gridSnap) { - node.position.x = (Mathf.Round((node.position.x + 8) / 16) * 16) - 8; - node.position.y = (Mathf.Round((node.position.y + 8) / 16) * 16) - 8; - } - - // Offset portConnectionPoints instantly if a node is dragged so they aren't delayed by a frame. - Vector2 offset = node.position - initial; - if (offset.sqrMagnitude > 0) { - foreach (XNode.NodePort output in node.Outputs) { - Rect rect; - if (portConnectionPoints.TryGetValue(output, out rect)) { - rect.position += offset; - portConnectionPoints[output] = rect; - } - } - - foreach (XNode.NodePort input in node.Inputs) { - Rect rect; - if (portConnectionPoints.TryGetValue(input, out rect)) { - rect.position += offset; - portConnectionPoints[input] = rect; - } - } - } - } - } - // Move selected reroutes with offset - for (int i = 0; i < selectedReroutes.Count; i++) { - Vector2 pos = mousePos + dragOffset[Selection.objects.Length + i]; - if (gridSnap) { - pos.x = (Mathf.Round(pos.x / 16) * 16); - pos.y = (Mathf.Round(pos.y / 16) * 16); - } - selectedReroutes[i].SetPoint(pos); - } - Repaint(); - } else if (currentActivity == NodeActivity.HoldGrid) { - currentActivity = NodeActivity.DragGrid; - preBoxSelection = Selection.objects; - preBoxSelectionReroute = selectedReroutes.ToArray(); - dragBoxStart = WindowToGridPosition(e.mousePosition); - Repaint(); - } else if (currentActivity == NodeActivity.DragGrid) { - Vector2 boxStartPos = GridToWindowPosition(dragBoxStart); - Vector2 boxSize = e.mousePosition - boxStartPos; - if (boxSize.x < 0) { boxStartPos.x += boxSize.x; boxSize.x = Mathf.Abs(boxSize.x); } - if (boxSize.y < 0) { boxStartPos.y += boxSize.y; boxSize.y = Mathf.Abs(boxSize.y); } - selectionBox = new Rect(boxStartPos, boxSize); - Repaint(); - } - } else if (e.button == 1 || e.button == 2) { - panOffset += e.delta * zoom; - isPanning = true; - } - break; - case EventType.MouseDown: - Repaint(); - if (e.button == 0) { - draggedOutputReroutes.Clear(); - - if (IsHoveringPort) { - if (hoveredPort.IsOutput) { - draggedOutput = hoveredPort; - } else { - hoveredPort.VerifyConnections(); - if (hoveredPort.IsConnected) { - XNode.Node node = hoveredPort.node; - XNode.NodePort output = hoveredPort.Connection; - int outputConnectionIndex = output.GetConnectionIndex(hoveredPort); - draggedOutputReroutes = output.GetReroutePoints(outputConnectionIndex); - hoveredPort.Disconnect(output); - draggedOutput = output; - draggedOutputTarget = hoveredPort; - if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node); - } - } - } else if (IsHoveringNode && IsHoveringTitle(hoveredNode)) { - // If mousedown on node header, select or deselect - if (!Selection.Contains(hoveredNode)) { - SelectNode(hoveredNode, e.control || e.shift); - if (!e.control && !e.shift) selectedReroutes.Clear(); - } else if (e.control || e.shift) DeselectNode(hoveredNode); - - // Cache double click state, but only act on it in MouseUp - Except ClickCount only works in mouseDown. - isDoubleClick = (e.clickCount == 2); - - e.Use(); - currentActivity = NodeActivity.HoldNode; - } else if (IsHoveringReroute) { - // If reroute isn't selected - if (!selectedReroutes.Contains(hoveredReroute)) { - // Add it - if (e.control || e.shift) selectedReroutes.Add(hoveredReroute); - // Select it - else { - selectedReroutes = new List() { hoveredReroute }; - Selection.activeObject = null; - } - - } - // Deselect - else if (e.control || e.shift) selectedReroutes.Remove(hoveredReroute); - e.Use(); - currentActivity = NodeActivity.HoldNode; - } - // If mousedown on grid background, deselect all - else if (!IsHoveringNode) { - currentActivity = NodeActivity.HoldGrid; - if (!e.control && !e.shift) { - selectedReroutes.Clear(); - Selection.activeObject = null; - } - } - } - break; - case EventType.MouseUp: - if (e.button == 0) { - //Port drag release - if (IsDraggingPort) { - //If connection is valid, save it - if (draggedOutputTarget != null) { - XNode.Node node = draggedOutputTarget.node; - if (graph.nodes.Count != 0) draggedOutput.Connect(draggedOutputTarget); - - // ConnectionIndex can be -1 if the connection is removed instantly after creation - int connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget); - if (connectionIndex != -1) { - draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes); - if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node); - EditorUtility.SetDirty(graph); - } - } - //Release dragged connection - draggedOutput = null; - draggedOutputTarget = null; - EditorUtility.SetDirty(graph); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } else if (currentActivity == NodeActivity.DragNode) { - IEnumerable nodes = Selection.objects.Where(x => x is XNode.Node).Select(x => x as XNode.Node); - foreach (XNode.Node node in nodes) EditorUtility.SetDirty(node); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } else if (!IsHoveringNode) { - // If click outside node, release field focus - if (!isPanning) { - EditorGUI.FocusTextInControl(null); - EditorGUIUtility.editingTextField = false; - } - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } - - // If click node header, select it. - if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift)) { - selectedReroutes.Clear(); - SelectNode(hoveredNode, false); - - // Double click to center node - if (isDoubleClick) { - Vector2 nodeDimension = nodeSizes.ContainsKey(hoveredNode) ? nodeSizes[hoveredNode] / 2 : Vector2.zero; - panOffset = -hoveredNode.position - nodeDimension; - } - } - - // If click reroute, select it. - if (IsHoveringReroute && !(e.control || e.shift)) { - selectedReroutes = new List() { hoveredReroute }; - Selection.activeObject = null; - } - - Repaint(); - currentActivity = NodeActivity.Idle; - } else if (e.button == 1 || e.button == 2) { - if (!isPanning) { - if (IsDraggingPort) { - draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition)); - } else if (currentActivity == NodeActivity.DragNode && Selection.activeObject == null && selectedReroutes.Count == 1) { - selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint()); - selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port, selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1); - } else if (IsHoveringReroute) { - ShowRerouteContextMenu(hoveredReroute); - } else if (IsHoveringPort) { - ShowPortContextMenu(hoveredPort); - } else if (IsHoveringNode && IsHoveringTitle(hoveredNode)) { - if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode, false); - GenericMenu menu = new GenericMenu(); - NodeEditor.GetEditor(hoveredNode, this).AddContextMenuItems(menu); - menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero)); - e.Use(); // Fixes copy/paste context menu appearing in Unity 5.6.6f2 - doesn't occur in 2018.3.2f1 Probably needs to be used in other places. - } else if (!IsHoveringNode) { - GenericMenu menu = new GenericMenu(); - graphEditor.AddContextMenuItems(menu); - menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero)); - } - } - isPanning = false; - } - // Reset DoubleClick - isDoubleClick = false; - break; - case EventType.KeyDown: - if (EditorGUIUtility.editingTextField) break; - else if (e.keyCode == KeyCode.F) Home(); - if (NodeEditorUtilities.IsMac()) { - if (e.keyCode == KeyCode.Return) RenameSelectedNode(); - } else { - if (e.keyCode == KeyCode.F2) RenameSelectedNode(); - } - if (e.keyCode == KeyCode.A) { - if (Selection.objects.Any(x => graph.nodes.Contains(x))) { - foreach (XNode.Node node in graph.nodes) { - DeselectNode(node); - } - } else { - foreach (XNode.Node node in graph.nodes) { - SelectNode(node, true); - } - } - } - break; - case EventType.ValidateCommand: - case EventType.ExecuteCommand: - if (e.commandName == "SoftDelete") { - if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes(); - e.Use(); - } else if (NodeEditorUtilities.IsMac() && e.commandName == "Delete") { - if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes(); - e.Use(); - } else if (e.commandName == "Duplicate") { - if (e.type == EventType.ExecuteCommand) DuplicateSelectedNodes(); - e.Use(); - } else if (e.commandName == "Copy") { - if (e.type == EventType.ExecuteCommand) CopySelectedNodes(); - e.Use(); - } else if (e.commandName == "Paste") { - if (e.type == EventType.ExecuteCommand) PasteNodes(WindowToGridPosition(lastMousePosition)); - e.Use(); - } - Repaint(); - break; - case EventType.Ignore: - // If release mouse outside window - if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid) { - Repaint(); - currentActivity = NodeActivity.Idle; - } - break; - } - } - - private void RecalculateDragOffsets(Event current) { - dragOffset = new Vector2[Selection.objects.Length + selectedReroutes.Count]; - // Selected nodes - for (int i = 0; i < Selection.objects.Length; i++) { - if (Selection.objects[i] is XNode.Node) { - XNode.Node node = Selection.objects[i] as XNode.Node; - dragOffset[i] = node.position - WindowToGridPosition(current.mousePosition); - } - } - - // Selected reroutes - for (int i = 0; i < selectedReroutes.Count; i++) { - dragOffset[Selection.objects.Length + i] = selectedReroutes[i].GetPoint() - WindowToGridPosition(current.mousePosition); - } - } - - /// Puts all selected nodes in focus. If no nodes are present, resets view and zoom to to origin - public void Home() { - var nodes = Selection.objects.Where(o => o is XNode.Node).Cast().ToList(); - if (nodes.Count > 0) { - Vector2 minPos = nodes.Select(x => x.position).Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y))); - Vector2 maxPos = nodes.Select(x => x.position + (nodeSizes.ContainsKey(x) ? nodeSizes[x] : Vector2.zero)).Aggregate((x, y) => new Vector2(Mathf.Max(x.x, y.x), Mathf.Max(x.y, y.y))); - panOffset = -(minPos + (maxPos - minPos) / 2f); - } else { - zoom = 2; - panOffset = Vector2.zero; - } - } - - /// Remove nodes in the graph in Selection.objects - public void RemoveSelectedNodes() { - // We need to delete reroutes starting at the highest point index to avoid shifting indices - selectedReroutes = selectedReroutes.OrderByDescending(x => x.pointIndex).ToList(); - for (int i = 0; i < selectedReroutes.Count; i++) { - selectedReroutes[i].RemovePoint(); - } - selectedReroutes.Clear(); - foreach (UnityEngine.Object item in Selection.objects) { - if (item is XNode.Node) { - XNode.Node node = item as XNode.Node; - graphEditor.RemoveNode(node); - } - } - } - - /// Initiate a rename on the currently selected node - public void RenameSelectedNode() { - if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) { - XNode.Node node = Selection.activeObject as XNode.Node; - Vector2 size; - if (nodeSizes.TryGetValue(node, out size)) { - RenamePopup.Show(Selection.activeObject, size.x); - } else { - RenamePopup.Show(Selection.activeObject); - } - } - } - - /// Draw this node on top of other nodes by placing it last in the graph.nodes list - public void MoveNodeToTop(XNode.Node node) { - int index; - while ((index = graph.nodes.IndexOf(node)) != graph.nodes.Count - 1) { - graph.nodes[index] = graph.nodes[index + 1]; - graph.nodes[index + 1] = node; - } - } - - /// Duplicate selected nodes and select the duplicates - public void DuplicateSelectedNodes() { - // Get selected nodes which are part of this graph - XNode.Node[] selectedNodes = Selection.objects.Select(x => x as XNode.Node).Where(x => x != null && x.graph == graph).ToArray(); - // Get top left node position - Vector2 topLeftNode = selectedNodes.Select(x => x.position).Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y))); - InsertDuplicateNodes(selectedNodes, topLeftNode + new Vector2(30, 30)); - } - - public void CopySelectedNodes() { - copyBuffer = Selection.objects.Select(x => x as XNode.Node).Where(x => x != null && x.graph == graph).ToArray(); - } - - public void PasteNodes(Vector2 pos) { - InsertDuplicateNodes(copyBuffer, pos); - } - - private void InsertDuplicateNodes(XNode.Node[] nodes, Vector2 topLeft) { - if (nodes == null || nodes.Length == 0) return; - - // Get top-left node - Vector2 topLeftNode = nodes.Select(x => x.position).Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y))); - Vector2 offset = topLeft - topLeftNode; - - UnityEngine.Object[] newNodes = new UnityEngine.Object[nodes.Length]; - Dictionary substitutes = new Dictionary(); - for (int i = 0; i < nodes.Length; i++) { - XNode.Node srcNode = nodes[i]; - if (srcNode == null) continue; - XNode.Node newNode = graphEditor.CopyNode(srcNode); - substitutes.Add(srcNode, newNode); - newNode.position = srcNode.position + offset; - newNodes[i] = newNode; - } - - // Walk through the selected nodes again, recreate connections, using the new nodes - for (int i = 0; i < nodes.Length; i++) { - XNode.Node srcNode = nodes[i]; - if (srcNode == null) continue; - foreach (XNode.NodePort port in srcNode.Ports) { - for (int c = 0; c < port.ConnectionCount; c++) { - XNode.NodePort inputPort = port.direction == XNode.NodePort.IO.Input ? port : port.GetConnection(c); - XNode.NodePort outputPort = port.direction == XNode.NodePort.IO.Output ? port : port.GetConnection(c); - - XNode.Node newNodeIn, newNodeOut; - if (substitutes.TryGetValue(inputPort.node, out newNodeIn) && substitutes.TryGetValue(outputPort.node, out newNodeOut)) { - newNodeIn.UpdateStaticPorts(); - newNodeOut.UpdateStaticPorts(); - inputPort = newNodeIn.GetInputPort(inputPort.fieldName); - outputPort = newNodeOut.GetOutputPort(outputPort.fieldName); - } - if (!inputPort.IsConnectedTo(outputPort)) inputPort.Connect(outputPort); - } - } - } - // Select the new nodes - Selection.objects = newNodes; - } - - /// Draw a connection as we are dragging it - public void DrawDraggedConnection() { - if (IsDraggingPort) { - Color col = NodeEditorPreferences.GetTypeColor(draggedOutput.ValueType); - col.a = draggedOutputTarget != null ? 1.0f : 0.6f; - - Rect fromRect; - if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return; - List gridPoints = new List(); - gridPoints.Add(fromRect.center); - for (int i = 0; i < draggedOutputReroutes.Count; i++) { - gridPoints.Add(draggedOutputReroutes[i]); - } - if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center); - else gridPoints.Add(WindowToGridPosition(Event.current.mousePosition)); - - DrawNoodle(col, gridPoints); - - Color bgcol = Color.black; - Color frcol = col; - bgcol.a = 0.6f; - frcol.a = 0.6f; - - // Loop through reroute points again and draw the points - for (int i = 0; i < draggedOutputReroutes.Count; i++) { - // Draw reroute point at position - Rect rect = new Rect(draggedOutputReroutes[i], new Vector2(16, 16)); - rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8); - rect = GridToWindowRect(rect); - - NodeEditorGUILayout.DrawPortHandle(rect, bgcol, frcol); - } - } - } - - bool IsHoveringTitle(XNode.Node node) { - Vector2 mousePos = Event.current.mousePosition; - //Get node position - Vector2 nodePos = GridToWindowPosition(node.position); - float width; - Vector2 size; - if (nodeSizes.TryGetValue(node, out size)) width = size.x; - else width = 200; - Rect windowRect = new Rect(nodePos, new Vector2(width / zoom, 30 / zoom)); - return windowRect.Contains(mousePos); - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorAction.cs.meta b/Scripts/Editor/NodeEditorAction.cs.meta deleted file mode 100644 index a081bf7..0000000 --- a/Scripts/Editor/NodeEditorAction.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: aa7d4286bf0ad2e4086252f2893d2cf5 -timeCreated: 1505426655 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorAssetModProcessor.cs b/Scripts/Editor/NodeEditorAssetModProcessor.cs deleted file mode 100644 index edaebaa..0000000 --- a/Scripts/Editor/NodeEditorAssetModProcessor.cs +++ /dev/null @@ -1,62 +0,0 @@ -using UnityEditor; -using UnityEngine; - -namespace XNodeEditor { - /// Deals with modified assets - class NodeEditorAssetModProcessor : UnityEditor.AssetModificationProcessor { - - /// Automatically delete Node sub-assets before deleting their script. - /// This is important to do, because you can't delete null sub assets. - /// For another workaround, see: https://gitlab.com/RotaryHeart-UnityShare/subassetmissingscriptdelete - private static AssetDeleteResult OnWillDeleteAsset (string path, RemoveAssetOptions options) { - // Get the object that is requested for deletion - UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath (path); - - // If we aren't deleting a script, return - if (!(obj is UnityEditor.MonoScript)) return AssetDeleteResult.DidNotDelete; - - // Check script type. Return if deleting a non-node script - UnityEditor.MonoScript script = obj as UnityEditor.MonoScript; - System.Type scriptType = script.GetClass (); - if (scriptType == null || (scriptType != typeof (XNode.Node) && !scriptType.IsSubclassOf (typeof (XNode.Node)))) return AssetDeleteResult.DidNotDelete; - - // Find all ScriptableObjects using this script - string[] guids = AssetDatabase.FindAssets ("t:" + scriptType); - for (int i = 0; i < guids.Length; i++) { - string assetpath = AssetDatabase.GUIDToAssetPath (guids[i]); - Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath (assetpath); - for (int k = 0; k < objs.Length; k++) { - XNode.Node node = objs[k] as XNode.Node; - if (node.GetType () == scriptType) { - if (node != null && node.graph != null) { - // Delete the node and notify the user - Debug.LogWarning (node.name + " of " + node.graph + " depended on deleted script and has been removed automatically.", node.graph); - node.graph.RemoveNode (node); - } - } - } - } - // We didn't actually delete the script. Tell the internal system to carry on with normal deletion procedure - return AssetDeleteResult.DidNotDelete; - } - - /// Automatically re-add loose node assets to the Graph node list - [InitializeOnLoadMethod] - private static void OnReloadEditor () { - // Find all NodeGraph assets - string[] guids = AssetDatabase.FindAssets ("t:" + typeof (XNode.NodeGraph)); - for (int i = 0; i < guids.Length; i++) { - string assetpath = AssetDatabase.GUIDToAssetPath (guids[i]); - XNode.NodeGraph graph = AssetDatabase.LoadAssetAtPath (assetpath, typeof (XNode.NodeGraph)) as XNode.NodeGraph; - graph.nodes.RemoveAll(x => x == null); //Remove null items - Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath (assetpath); - // Ensure that all sub node assets are present in the graph node list - for (int u = 0; u < objs.Length; u++) { - // Ignore null sub assets - if (objs[u] == null) continue; - if (!graph.nodes.Contains (objs[u] as XNode.Node)) graph.nodes.Add(objs[u] as XNode.Node); - } - } - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorAssetModProcessor.cs.meta b/Scripts/Editor/NodeEditorAssetModProcessor.cs.meta deleted file mode 100644 index 057198b..0000000 --- a/Scripts/Editor/NodeEditorAssetModProcessor.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: e515e86efe8160243a68b7c06d730c9c -timeCreated: 1507982232 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorBase.cs b/Scripts/Editor/NodeEditorBase.cs deleted file mode 100644 index 1fc28c7..0000000 --- a/Scripts/Editor/NodeEditorBase.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using UnityEditor; -using UnityEngine; -#if ODIN_INSPECTOR -using Sirenix.OdinInspector.Editor; -#endif - -namespace XNodeEditor.Internal { - /// Handles caching of custom editor classes and their target types. Accessible with GetEditor(Type type) - /// Editor Type. Should be the type of the deriving script itself (eg. NodeEditor) - /// Attribute Type. The attribute used to connect with the runtime type (eg. CustomNodeEditorAttribute) - /// Runtime Type. The ScriptableObject this can be an editor for (eg. Node) - public abstract class NodeEditorBase where A : Attribute, NodeEditorBase.INodeEditorAttrib where T : NodeEditorBase where K : ScriptableObject { - /// Custom editors defined with [CustomNodeEditor] - private static Dictionary editorTypes; - private static Dictionary editors = new Dictionary(); - public NodeEditorWindow window; - public K target; - public SerializedObject serializedObject; -#if ODIN_INSPECTOR - private PropertyTree _objectTree; - public PropertyTree objectTree { - get { - if (this._objectTree == null) { - try { - bool wasInEditor = NodeEditor.inNodeEditor; - NodeEditor.inNodeEditor = true; - this._objectTree = PropertyTree.Create(this.serializedObject); - NodeEditor.inNodeEditor = wasInEditor; - } catch (ArgumentException ex) { - Debug.Log(ex); - } - } - return this._objectTree; - } - } -#endif - - public static T GetEditor(K target, NodeEditorWindow window) { - if (target == null) return null; - T editor; - if (!editors.TryGetValue(target, out editor)) { - Type type = target.GetType(); - Type editorType = GetEditorType(type); - editor = Activator.CreateInstance(editorType) as T; - editor.target = target; - editor.serializedObject = new SerializedObject(target); - editor.window = window; - editor.OnCreate(); - editors.Add(target, editor); - } - if (editor.target == null) editor.target = target; - if (editor.window != window) editor.window = window; - if (editor.serializedObject == null) editor.serializedObject = new SerializedObject(target); - return editor; - } - - private static Type GetEditorType(Type type) { - if (type == null) return null; - if (editorTypes == null) CacheCustomEditors(); - Type result; - if (editorTypes.TryGetValue(type, out result)) return result; - //If type isn't found, try base type - return GetEditorType(type.BaseType); - } - - private static void CacheCustomEditors() { - editorTypes = new Dictionary(); - - //Get all classes deriving from NodeEditor via reflection - Type[] nodeEditors = typeof(T).GetDerivedTypes(); - for (int i = 0; i < nodeEditors.Length; i++) { - if (nodeEditors[i].IsAbstract) continue; - var attribs = nodeEditors[i].GetCustomAttributes(typeof(A), false); - if (attribs == null || attribs.Length == 0) continue; - A attrib = attribs[0] as A; - editorTypes.Add(attrib.GetInspectedType(), nodeEditors[i]); - } - } - - /// Called on creation, after references have been set - public virtual void OnCreate() { } - - public interface INodeEditorAttrib { - Type GetInspectedType(); - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorBase.cs.meta b/Scripts/Editor/NodeEditorBase.cs.meta deleted file mode 100644 index 4ded02a..0000000 --- a/Scripts/Editor/NodeEditorBase.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: e85122ded59aceb4eb4b1bd9d9202642 -timeCreated: 1511353946 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs deleted file mode 100644 index 9954325..0000000 --- a/Scripts/Editor/NodeEditorGUI.cs +++ /dev/null @@ -1,428 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -using XNodeEditor.Internal; - -namespace XNodeEditor { - /// Contains GUI methods - public partial class NodeEditorWindow { - public NodeGraphEditor graphEditor; - private List selectionCache; - private List culledNodes; - /// 19 if docked, 22 if not - private int topPadding { get { return isDocked() ? 19 : 22; } } - /// Executed after all other window GUI. Useful if Zoom is ruining your day. Automatically resets after being run. - public event Action onLateGUI; - - private void OnGUI() { - Event e = Event.current; - Matrix4x4 m = GUI.matrix; - if (graph == null) return; - ValidateGraphEditor(); - Controls(); - - DrawGrid(position, zoom, panOffset); - DrawConnections(); - DrawDraggedConnection(); - DrawNodes(); - DrawSelectionBox(); - DrawTooltip(); - graphEditor.OnGUI(); - - // Run and reset onLateGUI - if (onLateGUI != null) { - onLateGUI(); - onLateGUI = null; - } - - GUI.matrix = m; - } - - public static void BeginZoomed(Rect rect, float zoom, float topPadding) { - GUI.EndClip(); - - GUIUtility.ScaleAroundPivot(Vector2.one / zoom, rect.size * 0.5f); - Vector4 padding = new Vector4(0, topPadding, 0, 0); - padding *= zoom; - GUI.BeginClip(new Rect(-((rect.width * zoom) - rect.width) * 0.5f, -(((rect.height * zoom) - rect.height) * 0.5f) + (topPadding * zoom), - rect.width * zoom, - rect.height * zoom)); - } - - public static void EndZoomed(Rect rect, float zoom, float topPadding) { - GUIUtility.ScaleAroundPivot(Vector2.one * zoom, rect.size * 0.5f); - Vector3 offset = new Vector3( - (((rect.width * zoom) - rect.width) * 0.5f), - (((rect.height * zoom) - rect.height) * 0.5f) + (-topPadding * zoom) + topPadding, - 0); - GUI.matrix = Matrix4x4.TRS(offset, Quaternion.identity, Vector3.one); - } - - public void DrawGrid(Rect rect, float zoom, Vector2 panOffset) { - - rect.position = Vector2.zero; - - Vector2 center = rect.size / 2f; - Texture2D gridTex = graphEditor.GetGridTexture(); - Texture2D crossTex = graphEditor.GetSecondaryGridTexture(); - - // Offset from origin in tile units - float xOffset = -(center.x * zoom + panOffset.x) / gridTex.width; - float yOffset = ((center.y - rect.size.y) * zoom + panOffset.y) / gridTex.height; - - Vector2 tileOffset = new Vector2(xOffset, yOffset); - - // Amount of tiles - float tileAmountX = Mathf.Round(rect.size.x * zoom) / gridTex.width; - float tileAmountY = Mathf.Round(rect.size.y * zoom) / gridTex.height; - - Vector2 tileAmount = new Vector2(tileAmountX, tileAmountY); - - // Draw tiled background - GUI.DrawTextureWithTexCoords(rect, gridTex, new Rect(tileOffset, tileAmount)); - GUI.DrawTextureWithTexCoords(rect, crossTex, new Rect(tileOffset + new Vector2(0.5f, 0.5f), tileAmount)); - } - - public void DrawSelectionBox() { - if (currentActivity == NodeActivity.DragGrid) { - Vector2 curPos = WindowToGridPosition(Event.current.mousePosition); - Vector2 size = curPos - dragBoxStart; - Rect r = new Rect(dragBoxStart, size); - r.position = GridToWindowPosition(r.position); - r.size /= zoom; - Handles.DrawSolidRectangleWithOutline(r, new Color(0, 0, 0, 0.1f), new Color(1, 1, 1, 0.6f)); - } - } - - public static bool DropdownButton(string name, float width) { - return GUILayout.Button(name, EditorStyles.toolbarDropDown, GUILayout.Width(width)); - } - - /// Show right-click context menu for hovered reroute - void ShowRerouteContextMenu(RerouteReference reroute) { - GenericMenu contextMenu = new GenericMenu(); - contextMenu.AddItem(new GUIContent("Remove"), false, () => reroute.RemovePoint()); - contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero)); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } - - /// Show right-click context menu for hovered port - void ShowPortContextMenu(XNode.NodePort hoveredPort) { - GenericMenu contextMenu = new GenericMenu(); - contextMenu.AddItem(new GUIContent("Clear Connections"), false, () => hoveredPort.ClearConnections()); - contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero)); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } - - /// Draw a bezier from output to input in grid coordinates - public void DrawNoodle(Color col, List gridPoints) { - Vector2[] windowPoints = gridPoints.Select(x => GridToWindowPosition(x)).ToArray(); - Handles.color = col; - int length = gridPoints.Count; - switch (NodeEditorPreferences.GetSettings().noodleType) { - case NodeEditorPreferences.NoodleType.Curve: - Vector2 outputTangent = Vector2.right; - for (int i = 0; i < length - 1; i++) { - Vector2 inputTangent = Vector2.left; - - if (i == 0) outputTangent = Vector2.right * Vector2.Distance(windowPoints[i], windowPoints[i + 1]) * 0.01f * zoom; - if (i < length - 2) { - Vector2 ab = (windowPoints[i + 1] - windowPoints[i]).normalized; - Vector2 cb = (windowPoints[i + 1] - windowPoints[i + 2]).normalized; - Vector2 ac = (windowPoints[i + 2] - windowPoints[i]).normalized; - Vector2 p = (ab + cb) * 0.5f; - float tangentLength = (Vector2.Distance(windowPoints[i], windowPoints[i + 1]) + Vector2.Distance(windowPoints[i + 1], windowPoints[i + 2])) * 0.005f * zoom; - float side = ((ac.x * (windowPoints[i + 1].y - windowPoints[i].y)) - (ac.y * (windowPoints[i + 1].x - windowPoints[i].x))); - - p = new Vector2(-p.y, p.x) * Mathf.Sign(side) * tangentLength; - inputTangent = p; - } - else { - inputTangent = Vector2.left * Vector2.Distance(windowPoints[i], windowPoints[i + 1]) * 0.01f * zoom; - } - - Handles.DrawBezier(windowPoints[i], windowPoints[i + 1], windowPoints[i] + ((outputTangent * 50) / zoom), windowPoints[i + 1] + ((inputTangent * 50) / zoom), col, null, 4); - outputTangent = -inputTangent; - } - break; - case NodeEditorPreferences.NoodleType.Line: - for (int i = 0; i < length - 1; i++) { - Handles.DrawAAPolyLine(5, windowPoints[i], windowPoints[i + 1]); - } - break; - case NodeEditorPreferences.NoodleType.Angled: - for (int i = 0; i < length - 1; i++) { - if (i == length - 1) continue; // Skip last index - if (windowPoints[i].x <= windowPoints[i + 1].x - (50 / zoom)) { - float midpoint = (windowPoints[i].x + windowPoints[i + 1].x) * 0.5f; - Vector2 start_1 = windowPoints[i]; - Vector2 end_1 = windowPoints[i + 1]; - start_1.x = midpoint; - end_1.x = midpoint; - Handles.DrawAAPolyLine(5, windowPoints[i], start_1); - Handles.DrawAAPolyLine(5, start_1, end_1); - Handles.DrawAAPolyLine(5, end_1, windowPoints[i + 1]); - } else { - float midpoint = (windowPoints[i].y + windowPoints[i + 1].y) * 0.5f; - Vector2 start_1 = windowPoints[i]; - Vector2 end_1 = windowPoints[i + 1]; - start_1.x += 25 / zoom; - end_1.x -= 25 / zoom; - Vector2 start_2 = start_1; - Vector2 end_2 = end_1; - start_2.y = midpoint; - end_2.y = midpoint; - Handles.DrawAAPolyLine(5, windowPoints[i], start_1); - Handles.DrawAAPolyLine(5, start_1, start_2); - Handles.DrawAAPolyLine(5, start_2, end_2); - Handles.DrawAAPolyLine(5, end_2, end_1); - Handles.DrawAAPolyLine(5, end_1, windowPoints[i + 1]); - } - } - break; - } - } - - /// Draws all connections - public void DrawConnections() { - Vector2 mousePos = Event.current.mousePosition; - List selection = preBoxSelectionReroute != null ? new List(preBoxSelectionReroute) : new List(); - hoveredReroute = new RerouteReference(); - - Color col = GUI.color; - foreach (XNode.Node node in graph.nodes) { - //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset. - if (node == null) continue; - - // Draw full connections and output > reroute - foreach (XNode.NodePort output in node.Outputs) { - //Needs cleanup. Null checks are ugly - Rect fromRect; - if (!_portConnectionPoints.TryGetValue(output, out fromRect)) continue; - - Color connectionColor = graphEditor.GetPortColor(output); - - for (int k = 0; k < output.ConnectionCount; k++) { - XNode.NodePort input = output.GetConnection(k); - - // Error handling - if (input == null) continue; //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return. - if (!input.IsConnectedTo(output)) input.Connect(output); - Rect toRect; - if (!_portConnectionPoints.TryGetValue(input, out toRect)) continue; - - List reroutePoints = output.GetReroutePoints(k); - - List gridPoints = new List(); - gridPoints.Add(fromRect.center); - gridPoints.AddRange(reroutePoints); - gridPoints.Add(toRect.center); - DrawNoodle(connectionColor, gridPoints); - - // Loop through reroute points again and draw the points - for (int i = 0; i < reroutePoints.Count; i++) { - RerouteReference rerouteRef = new RerouteReference(output, k, i); - // Draw reroute point at position - Rect rect = new Rect(reroutePoints[i], new Vector2(12, 12)); - rect.position = new Vector2(rect.position.x - 6, rect.position.y - 6); - rect = GridToWindowRect(rect); - - // Draw selected reroute points with an outline - if (selectedReroutes.Contains(rerouteRef)) { - GUI.color = NodeEditorPreferences.GetSettings().highlightColor; - GUI.DrawTexture(rect, NodeEditorResources.dotOuter); - } - - GUI.color = connectionColor; - GUI.DrawTexture(rect, NodeEditorResources.dot); - if (rect.Overlaps(selectionBox)) selection.Add(rerouteRef); - if (rect.Contains(mousePos)) hoveredReroute = rerouteRef; - - } - } - } - } - GUI.color = col; - if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid) selectedReroutes = selection; - } - - private void DrawNodes() { - Event e = Event.current; - if (e.type == EventType.Layout) { - selectionCache = new List(Selection.objects); - } - - System.Reflection.MethodInfo onValidate = null; - if (Selection.activeObject != null && Selection.activeObject is XNode.Node) { - onValidate = Selection.activeObject.GetType().GetMethod("OnValidate"); - if (onValidate != null) EditorGUI.BeginChangeCheck(); - } - - BeginZoomed(position, zoom, topPadding); - - Vector2 mousePos = Event.current.mousePosition; - - if (e.type != EventType.Layout) { - hoveredNode = null; - hoveredPort = null; - } - - List preSelection = preBoxSelection != null ? new List(preBoxSelection) : new List(); - - // Selection box stuff - Vector2 boxStartPos = GridToWindowPositionNoClipped(dragBoxStart); - Vector2 boxSize = mousePos - boxStartPos; - if (boxSize.x < 0) { boxStartPos.x += boxSize.x; boxSize.x = Mathf.Abs(boxSize.x); } - if (boxSize.y < 0) { boxStartPos.y += boxSize.y; boxSize.y = Mathf.Abs(boxSize.y); } - Rect selectionBox = new Rect(boxStartPos, boxSize); - - //Save guiColor so we can revert it - Color guiColor = GUI.color; - - if (e.type == EventType.Layout) culledNodes = new List(); - for (int n = 0; n < graph.nodes.Count; n++) { - // Skip null nodes. The user could be in the process of renaming scripts, so removing them at this point is not advisable. - if (graph.nodes[n] == null) continue; - if (n >= graph.nodes.Count) return; - XNode.Node node = graph.nodes[n]; - - // Culling - if (e.type == EventType.Layout) { - // Cull unselected nodes outside view - if (!Selection.Contains(node) && ShouldBeCulled(node)) { - culledNodes.Add(node); - continue; - } - } else if (culledNodes.Contains(node)) continue; - - if (e.type == EventType.Repaint) { - _portConnectionPoints = _portConnectionPoints.Where(x => x.Key.node != node).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - } - - NodeEditor nodeEditor = NodeEditor.GetEditor(node, this); - - NodeEditor.portPositions.Clear(); - - //Get node position - Vector2 nodePos = GridToWindowPositionNoClipped(node.position); - - GUILayout.BeginArea(new Rect(nodePos, new Vector2(nodeEditor.GetWidth(), 4000))); - - bool selected = selectionCache.Contains(graph.nodes[n]); - - if (selected) { - GUIStyle style = new GUIStyle(nodeEditor.GetBodyStyle()); - GUIStyle highlightStyle = new GUIStyle(NodeEditorResources.styles.nodeHighlight); - highlightStyle.padding = style.padding; - style.padding = new RectOffset(); - GUI.color = nodeEditor.GetTint(); - GUILayout.BeginVertical(style); - GUI.color = NodeEditorPreferences.GetSettings().highlightColor; - GUILayout.BeginVertical(new GUIStyle(highlightStyle)); - } else { - GUIStyle style = new GUIStyle(nodeEditor.GetBodyStyle()); - GUI.color = nodeEditor.GetTint(); - GUILayout.BeginVertical(style); - } - - GUI.color = guiColor; - EditorGUI.BeginChangeCheck(); - - //Draw node contents - nodeEditor.OnHeaderGUI(); - nodeEditor.OnBodyGUI(); - - //If user changed a value, notify other scripts through onUpdateNode - if (EditorGUI.EndChangeCheck()) { - if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node); - EditorUtility.SetDirty(node); - nodeEditor.serializedObject.ApplyModifiedProperties(); - } - - GUILayout.EndVertical(); - - //Cache data about the node for next frame - if (e.type == EventType.Repaint) { - Vector2 size = GUILayoutUtility.GetLastRect().size; - if (nodeSizes.ContainsKey(node)) nodeSizes[node] = size; - else nodeSizes.Add(node, size); - - foreach (var kvp in NodeEditor.portPositions) { - Vector2 portHandlePos = kvp.Value; - portHandlePos += node.position; - Rect rect = new Rect(portHandlePos.x - 8, portHandlePos.y - 8, 16, 16); - portConnectionPoints[kvp.Key] = rect; - } - } - - if (selected) GUILayout.EndVertical(); - - if (e.type != EventType.Layout) { - //Check if we are hovering this node - Vector2 nodeSize = GUILayoutUtility.GetLastRect().size; - Rect windowRect = new Rect(nodePos, nodeSize); - if (windowRect.Contains(mousePos)) hoveredNode = node; - - //If dragging a selection box, add nodes inside to selection - if (currentActivity == NodeActivity.DragGrid) { - if (windowRect.Overlaps(selectionBox)) preSelection.Add(node); - } - - //Check if we are hovering any of this nodes ports - //Check input ports - foreach (XNode.NodePort input in node.Inputs) { - //Check if port rect is available - if (!portConnectionPoints.ContainsKey(input)) continue; - Rect r = GridToWindowRectNoClipped(portConnectionPoints[input]); - if (r.Contains(mousePos)) hoveredPort = input; - } - //Check all output ports - foreach (XNode.NodePort output in node.Outputs) { - //Check if port rect is available - if (!portConnectionPoints.ContainsKey(output)) continue; - Rect r = GridToWindowRectNoClipped(portConnectionPoints[output]); - if (r.Contains(mousePos)) hoveredPort = output; - } - } - - GUILayout.EndArea(); - } - - if (e.type != EventType.Layout && currentActivity == NodeActivity.DragGrid) Selection.objects = preSelection.ToArray(); - EndZoomed(position, zoom, topPadding); - - //If a change in is detected in the selected node, call OnValidate method. - //This is done through reflection because OnValidate is only relevant in editor, - //and thus, the code should not be included in build. - if (onValidate != null && EditorGUI.EndChangeCheck()) onValidate.Invoke(Selection.activeObject, null); - } - - private bool ShouldBeCulled(XNode.Node node) { - - Vector2 nodePos = GridToWindowPositionNoClipped(node.position); - if (nodePos.x / _zoom > position.width) return true; // Right - else if (nodePos.y / _zoom > position.height) return true; // Bottom - else if (nodeSizes.ContainsKey(node)) { - Vector2 size = nodeSizes[node]; - if (nodePos.x + size.x < 0) return true; // Left - else if (nodePos.y + size.y < 0) return true; // Top - } - return false; - } - - private void DrawTooltip() { - if (hoveredPort != null && NodeEditorPreferences.GetSettings().portTooltips && graphEditor != null) { - string tooltip = graphEditor.GetPortTooltip(hoveredPort); - if (string.IsNullOrEmpty(tooltip)) return; - GUIContent content = new GUIContent(tooltip); - Vector2 size = NodeEditorResources.styles.tooltip.CalcSize(content); - size.x += 8; - Rect rect = new Rect(Event.current.mousePosition - (size), size); - EditorGUI.LabelField(rect, content, NodeEditorResources.styles.tooltip); - Repaint(); - } - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorGUI.cs.meta b/Scripts/Editor/NodeEditorGUI.cs.meta deleted file mode 100644 index 543878b..0000000 --- a/Scripts/Editor/NodeEditorGUI.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 756276bfe9a0c2f4da3930ba1964f58d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs deleted file mode 100644 index b8e2019..0000000 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ /dev/null @@ -1,490 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor; -using UnityEditorInternal; -using UnityEngine; - -namespace XNodeEditor { - /// xNode-specific version of - public static class NodeEditorGUILayout { - - private static readonly Dictionary> reorderableListCache = new Dictionary>(); - private static int reorderableListIndex = -1; - - /// Make a field for a serialized property. Automatically displays relevant node port. - public static void PropertyField(SerializedProperty property, bool includeChildren = true, params GUILayoutOption[] options) { - PropertyField(property, (GUIContent) null, includeChildren, options); - } - - /// Make a field for a serialized property. Automatically displays relevant node port. - public static void PropertyField(SerializedProperty property, GUIContent label, bool includeChildren = true, params GUILayoutOption[] options) { - if (property == null) throw new NullReferenceException(); - XNode.Node node = property.serializedObject.targetObject as XNode.Node; - XNode.NodePort port = node.GetPort(property.name); - PropertyField(property, label, port, includeChildren); - } - - /// Make a field for a serialized property. Manual node port override. - public static void PropertyField(SerializedProperty property, XNode.NodePort port, bool includeChildren = true, params GUILayoutOption[] options) { - PropertyField(property, null, port, includeChildren, options); - } - - /// Make a field for a serialized property. Manual node port override. - public static void PropertyField(SerializedProperty property, GUIContent label, XNode.NodePort port, bool includeChildren = true, params GUILayoutOption[] options) { - if (property == null) throw new NullReferenceException(); - - // If property is not a port, display a regular property field - if (port == null) EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30)); - else { - Rect rect = new Rect(); - - float spacePadding = 0; - SpaceAttribute spaceAttribute; - if (NodeEditorUtilities.GetCachedAttrib(port.node.GetType(), property.name, out spaceAttribute)) spacePadding = spaceAttribute.height; - - // If property is an input, display a regular property field and put a port handle on the left side - if (port.direction == XNode.NodePort.IO.Input) { - // Get data from [Input] attribute - XNode.Node.ShowBackingValue showBacking = XNode.Node.ShowBackingValue.Unconnected; - XNode.Node.InputAttribute inputAttribute; - bool dynamicPortList = false; - if (NodeEditorUtilities.GetCachedAttrib(port.node.GetType(), property.name, out inputAttribute)) { - dynamicPortList = inputAttribute.dynamicPortList; - showBacking = inputAttribute.backingValue; - } - - //Call GUILayout.Space if Space attribute is set and we are NOT drawing a PropertyField - bool useLayoutSpace = dynamicPortList || - showBacking == XNode.Node.ShowBackingValue.Never || - (showBacking == XNode.Node.ShowBackingValue.Unconnected && port.IsConnected); - if (spacePadding > 0 && useLayoutSpace) { - GUILayout.Space(spacePadding); - spacePadding = 0; - } - - if (dynamicPortList) { - Type type = GetType(property); - XNode.Node.ConnectionType connectionType = inputAttribute != null ? inputAttribute.connectionType : XNode.Node.ConnectionType.Multiple; - DynamicPortList(property.name, type, property.serializedObject, port.direction, connectionType); - return; - } - switch (showBacking) { - case XNode.Node.ShowBackingValue.Unconnected: - // Display a label if port is connected - if (port.IsConnected) EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName)); - // Display an editable property field if port is not connected - else EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30)); - break; - case XNode.Node.ShowBackingValue.Never: - // Display a label - EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName)); - break; - case XNode.Node.ShowBackingValue.Always: - // Display an editable property field - EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30)); - break; - } - - rect = GUILayoutUtility.GetLastRect(); - rect.position = rect.position - new Vector2(16, -spacePadding); - // 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) { - // Get data from [Output] attribute - XNode.Node.ShowBackingValue showBacking = XNode.Node.ShowBackingValue.Unconnected; - XNode.Node.OutputAttribute outputAttribute; - bool dynamicPortList = false; - if (NodeEditorUtilities.GetCachedAttrib(port.node.GetType(), property.name, out outputAttribute)) { - dynamicPortList = outputAttribute.dynamicPortList; - showBacking = outputAttribute.backingValue; - } - - //Call GUILayout.Space if Space attribute is set and we are NOT drawing a PropertyField - bool useLayoutSpace = dynamicPortList || - showBacking == XNode.Node.ShowBackingValue.Never || - (showBacking == XNode.Node.ShowBackingValue.Unconnected && port.IsConnected); - if (spacePadding > 0 && useLayoutSpace) { - GUILayout.Space(spacePadding); - spacePadding = 0; - } - - if (dynamicPortList) { - Type type = GetType(property); - XNode.Node.ConnectionType connectionType = outputAttribute != null ? outputAttribute.connectionType : XNode.Node.ConnectionType.Multiple; - DynamicPortList(property.name, type, property.serializedObject, port.direction, connectionType); - return; - } - switch (showBacking) { - case XNode.Node.ShowBackingValue.Unconnected: - // Display a label if port is connected - if (port.IsConnected) EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.OutputPort, GUILayout.MinWidth(30)); - // Display an editable property field if port is not connected - else EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30)); - break; - case XNode.Node.ShowBackingValue.Never: - // Display a label - EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.OutputPort, GUILayout.MinWidth(30)); - break; - case XNode.Node.ShowBackingValue.Always: - // Display an editable property field - EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30)); - break; - } - - rect = GUILayoutUtility.GetLastRect(); - rect.position = rect.position + new Vector2(rect.width, spacePadding); - } - - rect.size = new Vector2(16, 16); - - NodeEditor editor = NodeEditor.GetEditor(port.node, NodeEditorWindow.current); - Color backgroundColor = editor.GetTint(); - Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port); - DrawPortHandle(rect, backgroundColor, col); - - // Register the handle position - Vector2 portPos = rect.center; - NodeEditor.portPositions[port] = portPos; - } - } - - private static System.Type GetType(SerializedProperty property) { - System.Type parentType = property.serializedObject.targetObject.GetType(); - System.Reflection.FieldInfo fi = parentType.GetFieldInfo(property.name); - return fi.FieldType; - } - - /// Make a simple port field. - public static void PortField(XNode.NodePort port, params GUILayoutOption[] options) { - PortField(null, port, options); - } - - /// Make a simple port field. - public static void PortField(GUIContent label, XNode.NodePort port, params GUILayoutOption[] options) { - if (port == null) return; - if (options == null) options = new GUILayoutOption[] { GUILayout.MinWidth(30) }; - Vector2 position = Vector3.zero; - 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 (port.direction == XNode.NodePort.IO.Input) { - // Display a label - EditorGUILayout.LabelField(content, options); - - Rect rect = GUILayoutUtility.GetLastRect(); - 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 - else if (port.direction == XNode.NodePort.IO.Output) { - // Display a label - EditorGUILayout.LabelField(content, NodeEditorResources.OutputPort, options); - - Rect rect = GUILayoutUtility.GetLastRect(); - position = rect.position + new Vector2(rect.width, 0); - } - PortField(position, port); - } - - /// Make a simple port field. - public static void PortField(Vector2 position, XNode.NodePort port) { - if (port == null) return; - - Rect rect = new Rect(position, new Vector2(16, 16)); - - NodeEditor editor = NodeEditor.GetEditor(port.node, NodeEditorWindow.current); - Color backgroundColor = editor.GetTint(); - Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port); - DrawPortHandle(rect, backgroundColor, col); - - // Register the handle position - Vector2 portPos = rect.center; - NodeEditor.portPositions[port] = portPos; - } - - /// Add a port field to previous layout element. - public static void AddPortField(XNode.NodePort port) { - if (port == null) return; - Rect rect = new Rect(); - - // If property is an input, display a regular property field and put a port handle on the left side - if (port.direction == XNode.NodePort.IO.Input) { - rect = GUILayoutUtility.GetLastRect(); - rect.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 - } else if (port.direction == XNode.NodePort.IO.Output) { - rect = GUILayoutUtility.GetLastRect(); - rect.position = rect.position + new Vector2(rect.width, 0); - } - - rect.size = new Vector2(16, 16); - - NodeEditor editor = NodeEditor.GetEditor(port.node, NodeEditorWindow.current); - Color backgroundColor = editor.GetTint(); - Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port); - DrawPortHandle(rect, backgroundColor, col); - - // Register the handle position - Vector2 portPos = rect.center; - NodeEditor.portPositions[port] = portPos; - } - - /// Draws an input and an output port on the same line - public static void PortPair(XNode.NodePort input, XNode.NodePort output) { - GUILayout.BeginHorizontal(); - NodeEditorGUILayout.PortField(input, GUILayout.MinWidth(0)); - NodeEditorGUILayout.PortField(output, GUILayout.MinWidth(0)); - GUILayout.EndHorizontal(); - } - - public static void DrawPortHandle(Rect rect, Color backgroundColor, Color typeColor) { - Color col = GUI.color; - GUI.color = backgroundColor; - GUI.DrawTexture(rect, NodeEditorResources.dotOuter); - GUI.color = typeColor; - GUI.DrawTexture(rect, NodeEditorResources.dot); - GUI.color = col; - } - -#region Obsolete - [Obsolete("Use IsDynamicPortListPort instead")] - public static bool IsInstancePortListPort(XNode.NodePort port) { - return IsDynamicPortListPort(port); - } - - [Obsolete("Use DynamicPortList instead")] - public static void InstancePortList(string fieldName, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple, XNode.Node.TypeConstraint typeConstraint = XNode.Node.TypeConstraint.None, Action onCreation = null) { - DynamicPortList(fieldName, type, serializedObject, io, connectionType, typeConstraint, onCreation); - } -#endregion - - /// Is this port part of a DynamicPortList? - public static bool IsDynamicPortListPort(XNode.NodePort port) { - string[] parts = port.fieldName.Split(' '); - if (parts.Length != 2) return false; - Dictionary cache; - if (reorderableListCache.TryGetValue(port.node, out cache)) { - ReorderableList list; - if (cache.TryGetValue(parts[0], out list)) return true; - } - return false; - } - - /// Draw an editable list of dynamic ports. Port names are named as "[fieldName] [index]" - /// Supply a list for editable values - /// Value type of added dynamic ports - /// The serializedObject of the node - /// Connection type of added dynamic ports - /// Called on the list on creation. Use this if you want to customize the created ReorderableList - public static void DynamicPortList(string fieldName, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple, XNode.Node.TypeConstraint typeConstraint = XNode.Node.TypeConstraint.None, Action onCreation = null) { - XNode.Node node = serializedObject.targetObject as XNode.Node; - - var indexedPorts = node.DynamicPorts.Select(x => { - string[] split = x.fieldName.Split(' '); - if (split != null && split.Length == 2 && split[0] == fieldName) { - int i = -1; - if (int.TryParse(split[1], out i)) { - return new { index = i, port = x }; - } - } - return new { index = -1, port = (XNode.NodePort) null }; - }).Where(x => x.port != null); - List dynamicPorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList(); - - ReorderableList list = null; - Dictionary rlc; - if (reorderableListCache.TryGetValue(serializedObject.targetObject, out rlc)) { - if (!rlc.TryGetValue(fieldName, out list)) list = null; - } - // If a ReorderableList isn't cached for this array, do so. - if (list == null) { - SerializedProperty arrayData = serializedObject.FindProperty(fieldName); - list = CreateReorderableList(fieldName, dynamicPorts, arrayData, type, serializedObject, io, connectionType, typeConstraint, onCreation); - if (reorderableListCache.TryGetValue(serializedObject.targetObject, out rlc)) rlc.Add(fieldName, list); - else reorderableListCache.Add(serializedObject.targetObject, new Dictionary() { { fieldName, list } }); - } - list.list = dynamicPorts; - list.DoLayoutList(); - } - - private static ReorderableList CreateReorderableList(string fieldName, List dynamicPorts, SerializedProperty arrayData, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, XNode.Node.ConnectionType connectionType, XNode.Node.TypeConstraint typeConstraint, Action onCreation) { - bool hasArrayData = arrayData != null && arrayData.isArray; - XNode.Node node = serializedObject.targetObject as XNode.Node; - ReorderableList list = new ReorderableList(dynamicPorts, null, true, true, true, true); - string label = arrayData != null ? arrayData.displayName : ObjectNames.NicifyVariableName(fieldName); - - list.drawElementCallback = - (Rect rect, int index, bool isActive, bool isFocused) => { - XNode.NodePort port = node.GetPort(fieldName + " " + index); - if (hasArrayData) { - if (arrayData.arraySize <= index) { - string portInfo = port != null ? port.fieldName : ""; - EditorGUI.LabelField(rect, "Array[" + index + "] data out of range"); - return; - } - SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index); - EditorGUI.PropertyField(rect, itemData, true); - } else EditorGUI.LabelField(rect, port != null ? port.fieldName : ""); - if (port != null) { - Vector2 pos = rect.position + (port.IsOutput?new Vector2(rect.width + 6, 0) : new Vector2(-36, 0)); - NodeEditorGUILayout.PortField(pos, port); - } - }; - list.elementHeightCallback = - (int index) => { - if (hasArrayData) { - if (arrayData.arraySize <= index) return EditorGUIUtility.singleLineHeight; - SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index); - return EditorGUI.GetPropertyHeight(itemData); - } else return EditorGUIUtility.singleLineHeight; - }; - 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(fieldName + " " + i); - XNode.NodePort nextPort = node.GetPort(fieldName + " " + (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(fieldName + " " + i); - XNode.NodePort nextPort = node.GetPort(fieldName + " " + (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) { - arrayData.MoveArrayElement(reorderableListIndex, rl.index); - } - - // Apply changes - serializedObject.ApplyModifiedProperties(); - serializedObject.Update(); - NodeEditorWindow.current.Repaint(); - EditorApplication.delayCall += NodeEditorWindow.current.Repaint; - }; - list.onAddCallback = - (ReorderableList rl) => { - // Add dynamic port postfixed with an index number - string newName = fieldName + " 0"; - int i = 0; - while (node.HasPort(newName)) newName = fieldName + " " + (++i); - - if (io == XNode.NodePort.IO.Output) node.AddDynamicOutput(type, connectionType, XNode.Node.TypeConstraint.None, newName); - else node.AddDynamicInput(type, connectionType, typeConstraint, newName); - serializedObject.Update(); - EditorUtility.SetDirty(node); - if (hasArrayData) { - arrayData.InsertArrayElementAtIndex(arrayData.arraySize); - } - serializedObject.ApplyModifiedProperties(); - }; - list.onRemoveCallback = - (ReorderableList rl) => { - - var indexedPorts = node.DynamicPorts.Select(x => { - string[] split = x.fieldName.Split(' '); - if (split != null && split.Length == 2 && split[0] == fieldName) { - int i = -1; - if (int.TryParse(split[1], out i)) { - return new { index = i, port = x }; - } - } - return new { index = -1, port = (XNode.NodePort) null }; - }).Where(x => x.port != null); - dynamicPorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList(); - - int index = rl.index; - - if (dynamicPorts[index] == null) { - Debug.LogWarning("No port found at index " + index + " - Skipped"); - } else if (dynamicPorts.Count <= index) { - Debug.LogWarning("DynamicPorts[" + index + "] out of range. Length was " + dynamicPorts.Count + " - Skipped"); - } else { - - // Clear the removed ports connections - dynamicPorts[index].ClearConnections(); - // Move following connections one step up to replace the missing connection - for (int k = index + 1; k < dynamicPorts.Count(); k++) { - for (int j = 0; j < dynamicPorts[k].ConnectionCount; j++) { - XNode.NodePort other = dynamicPorts[k].GetConnection(j); - dynamicPorts[k].Disconnect(other); - dynamicPorts[k - 1].Connect(other); - } - } - // Remove the last dynamic port, to avoid messing up the indexing - node.RemoveDynamicPort(dynamicPorts[dynamicPorts.Count() - 1].fieldName); - serializedObject.Update(); - EditorUtility.SetDirty(node); - } - - if (hasArrayData) { - if (arrayData.arraySize <= index) { - Debug.LogWarning("Attempted to remove array index " + index + " where only " + arrayData.arraySize + " exist - Skipped"); - Debug.Log(rl.list[0]); - return; - } - arrayData.DeleteArrayElementAtIndex(index); - // Error handling. If the following happens too often, file a bug report at https://github.com/Siccity/xNode/issues - if (dynamicPorts.Count <= arrayData.arraySize) { - while (dynamicPorts.Count <= arrayData.arraySize) { - arrayData.DeleteArrayElementAtIndex(arrayData.arraySize - 1); - } - UnityEngine.Debug.LogWarning("Array size exceeded dynamic ports size. Excess items removed."); - } - serializedObject.ApplyModifiedProperties(); - serializedObject.Update(); - } - }; - - if (hasArrayData) { - int dynamicPortCount = dynamicPorts.Count; - while (dynamicPortCount < arrayData.arraySize) { - // Add dynamic 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.AddDynamicOutput(type, connectionType, typeConstraint, newName); - else node.AddDynamicInput(type, connectionType, typeConstraint, newName); - EditorUtility.SetDirty(node); - dynamicPortCount++; - } - while (arrayData.arraySize < dynamicPortCount) { - arrayData.InsertArrayElementAtIndex(arrayData.arraySize); - } - serializedObject.ApplyModifiedProperties(); - serializedObject.Update(); - } - if (onCreation != null) onCreation(list); - return list; - } - } -} diff --git a/Scripts/Editor/NodeEditorGUILayout.cs.meta b/Scripts/Editor/NodeEditorGUILayout.cs.meta deleted file mode 100644 index 89596e2..0000000 --- a/Scripts/Editor/NodeEditorGUILayout.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 1d6c2d118d1c77948a23f2f4a34d1f64 -timeCreated: 1507966608 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorPreferences.cs b/Scripts/Editor/NodeEditorPreferences.cs deleted file mode 100644 index c28c064..0000000 --- a/Scripts/Editor/NodeEditorPreferences.cs +++ /dev/null @@ -1,241 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; - -namespace XNodeEditor { - public static class NodeEditorPreferences { - public enum NoodleType { Curve, Line, Angled } - - /// The last editor we checked. This should be the one we modify - private static XNodeEditor.NodeGraphEditor lastEditor; - /// The last key we checked. This should be the one we modify - private static string lastKey = "xNode.Settings"; - - private static Dictionary typeColors = new Dictionary(); - private static Dictionary settings = new Dictionary(); - - [System.Serializable] - public class Settings : ISerializationCallbackReceiver { - [SerializeField] private Color32 _gridLineColor = new Color(0.45f, 0.45f, 0.45f); - public Color32 gridLineColor { get { return _gridLineColor; } set { _gridLineColor = value; _gridTexture = null; _crossTexture = null; } } - - [SerializeField] private Color32 _gridBgColor = new Color(0.18f, 0.18f, 0.18f); - public Color32 gridBgColor { get { return _gridBgColor; } set { _gridBgColor = value; _gridTexture = null; } } - - [Obsolete("Use maxZoom instead")] - public float zoomOutLimit { get { return maxZoom; } set { maxZoom = value; } } - - [UnityEngine.Serialization.FormerlySerializedAs("zoomOutLimit")] - public float maxZoom = 5f; - public float minZoom = 1f; - public Color32 highlightColor = new Color32(255, 255, 255, 255); - public bool gridSnap = true; - public bool autoSave = true; - public bool zoomToMouse = true; - public bool portTooltips = true; - [SerializeField] private string typeColorsData = ""; - [NonSerialized] public Dictionary typeColors = new Dictionary(); - public NoodleType noodleType = NoodleType.Curve; - - private Texture2D _gridTexture; - public Texture2D gridTexture { - get { - if (_gridTexture == null) _gridTexture = NodeEditorResources.GenerateGridTexture(gridLineColor, gridBgColor); - return _gridTexture; - } - } - private Texture2D _crossTexture; - public Texture2D crossTexture { - get { - if (_crossTexture == null) _crossTexture = NodeEditorResources.GenerateCrossTexture(gridLineColor); - return _crossTexture; - } - } - - public void OnAfterDeserialize() { - // Deserialize typeColorsData - typeColors = new Dictionary(); - string[] data = typeColorsData.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < data.Length; i += 2) { - Color col; - if (ColorUtility.TryParseHtmlString("#" + data[i + 1], out col)) { - typeColors.Add(data[i], col); - } - } - } - - public void OnBeforeSerialize() { - // Serialize typeColors - typeColorsData = ""; - foreach (var item in typeColors) { - typeColorsData += item.Key + "," + ColorUtility.ToHtmlStringRGB(item.Value) + ","; - } - } - } - - /// Get settings of current active editor - public static Settings GetSettings() { - if (lastEditor != XNodeEditor.NodeEditorWindow.current.graphEditor) { - object[] attribs = XNodeEditor.NodeEditorWindow.current.graphEditor.GetType().GetCustomAttributes(typeof(XNodeEditor.NodeGraphEditor.CustomNodeGraphEditorAttribute), true); - if (attribs.Length == 1) { - XNodeEditor.NodeGraphEditor.CustomNodeGraphEditorAttribute attrib = attribs[0] as XNodeEditor.NodeGraphEditor.CustomNodeGraphEditorAttribute; - lastEditor = XNodeEditor.NodeEditorWindow.current.graphEditor; - lastKey = attrib.editorPrefsKey; - } else return null; - } - if (!settings.ContainsKey(lastKey)) VerifyLoaded(); - return settings[lastKey]; - } - -#if UNITY_2019_1_OR_NEWER - [SettingsProvider] - public static SettingsProvider CreateXNodeSettingsProvider() { - SettingsProvider provider = new SettingsProvider("Preferences/Node Editor", SettingsScope.User) { - guiHandler = (searchContext) => { XNodeEditor.NodeEditorPreferences.PreferencesGUI(); }, - keywords = new HashSet(new [] { "xNode", "node", "editor", "graph", "connections", "noodles", "ports" }) - }; - return provider; - } -#endif - -#if !UNITY_2019_1_OR_NEWER - [PreferenceItem("Node Editor")] -#endif - private static void PreferencesGUI() { - VerifyLoaded(); - Settings settings = NodeEditorPreferences.settings[lastKey]; - - NodeSettingsGUI(lastKey, settings); - GridSettingsGUI(lastKey, settings); - SystemSettingsGUI(lastKey, settings); - TypeColorsGUI(lastKey, settings); - if (GUILayout.Button(new GUIContent("Set Default", "Reset all values to default"), GUILayout.Width(120))) { - ResetPrefs(); - } - } - - private static void GridSettingsGUI(string key, Settings settings) { - //Label - EditorGUILayout.LabelField("Grid", EditorStyles.boldLabel); - settings.gridSnap = EditorGUILayout.Toggle(new GUIContent("Snap", "Hold CTRL in editor to invert"), settings.gridSnap); - settings.zoomToMouse = EditorGUILayout.Toggle(new GUIContent("Zoom to Mouse", "Zooms towards mouse position"), settings.zoomToMouse); - EditorGUILayout.LabelField("Zoom"); - EditorGUI.indentLevel++; - settings.maxZoom = EditorGUILayout.FloatField(new GUIContent("Max", "Upper limit to zoom"), settings.maxZoom); - settings.minZoom = EditorGUILayout.FloatField(new GUIContent("Min", "Lower limit to zoom"), settings.minZoom); - EditorGUI.indentLevel--; - settings.gridLineColor = EditorGUILayout.ColorField("Color", settings.gridLineColor); - settings.gridBgColor = EditorGUILayout.ColorField(" ", settings.gridBgColor); - if (GUI.changed) { - SavePrefs(key, settings); - - NodeEditorWindow.RepaintAll(); - } - EditorGUILayout.Space(); - } - - private static void SystemSettingsGUI(string key, Settings settings) { - //Label - EditorGUILayout.LabelField("System", EditorStyles.boldLabel); - settings.autoSave = EditorGUILayout.Toggle(new GUIContent("Autosave", "Disable for better editor performance"), settings.autoSave); - if (GUI.changed) SavePrefs(key, settings); - EditorGUILayout.Space(); - } - - private static void NodeSettingsGUI(string key, Settings settings) { - //Label - EditorGUILayout.LabelField("Node", EditorStyles.boldLabel); - settings.highlightColor = EditorGUILayout.ColorField("Selection", settings.highlightColor); - settings.noodleType = (NoodleType) EditorGUILayout.EnumPopup("Noodle type", (Enum) settings.noodleType); - settings.portTooltips = EditorGUILayout.Toggle("Port Tooltips", settings.portTooltips); - if (GUI.changed) { - SavePrefs(key, settings); - NodeEditorWindow.RepaintAll(); - } - EditorGUILayout.Space(); - } - - private static void TypeColorsGUI(string key, Settings settings) { - //Label - EditorGUILayout.LabelField("Types", EditorStyles.boldLabel); - - //Clone keys so we can enumerate the dictionary and make changes. - var typeColorKeys = new List(typeColors.Keys); - - //Display type colors. Save them if they are edited by the user - foreach (var type in typeColorKeys) { - string typeColorKey = NodeEditorUtilities.PrettyName(type); - Color col = typeColors[type]; - EditorGUI.BeginChangeCheck(); - EditorGUILayout.BeginHorizontal(); - col = EditorGUILayout.ColorField(typeColorKey, col); - EditorGUILayout.EndHorizontal(); - if (EditorGUI.EndChangeCheck()) { - typeColors[type] = col; - if (settings.typeColors.ContainsKey(typeColorKey)) settings.typeColors[typeColorKey] = col; - else settings.typeColors.Add(typeColorKey, col); - SavePrefs(key, settings); - NodeEditorWindow.RepaintAll(); - } - } - } - - /// Load prefs if they exist. Create if they don't - private static Settings LoadPrefs() { - // Create settings if it doesn't exist - if (!EditorPrefs.HasKey(lastKey)) { - if (lastEditor != null) EditorPrefs.SetString(lastKey, JsonUtility.ToJson(lastEditor.GetDefaultPreferences())); - else EditorPrefs.SetString(lastKey, JsonUtility.ToJson(new Settings())); - } - return JsonUtility.FromJson(EditorPrefs.GetString(lastKey)); - } - - /// Delete all prefs - public static void ResetPrefs() { - if (EditorPrefs.HasKey(lastKey)) EditorPrefs.DeleteKey(lastKey); - if (settings.ContainsKey(lastKey)) settings.Remove(lastKey); - typeColors = new Dictionary(); - VerifyLoaded(); - NodeEditorWindow.RepaintAll(); - } - - /// Save preferences in EditorPrefs - private static void SavePrefs(string key, Settings settings) { - EditorPrefs.SetString(key, JsonUtility.ToJson(settings)); - } - - /// Check if we have loaded settings for given key. If not, load them - private static void VerifyLoaded() { - if (!settings.ContainsKey(lastKey)) settings.Add(lastKey, LoadPrefs()); - } - - /// Return color based on type - public static Color GetTypeColor(System.Type type) { - VerifyLoaded(); - if (type == null) return Color.gray; - Color col; - if (!typeColors.TryGetValue(type, out col)) { - string typeName = type.PrettyName(); - if (settings[lastKey].typeColors.ContainsKey(typeName)) typeColors.Add(type, settings[lastKey].typeColors[typeName]); - else { -#if UNITY_5_4_OR_NEWER - UnityEngine.Random.State oldState = UnityEngine.Random.state; - UnityEngine.Random.InitState(typeName.GetHashCode()); -#else - int oldSeed = UnityEngine.Random.seed; - UnityEngine.Random.seed = typeName.GetHashCode(); -#endif - col = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value); - typeColors.Add(type, col); -#if UNITY_5_4_OR_NEWER - UnityEngine.Random.state = oldState; -#else - UnityEngine.Random.seed = oldSeed; -#endif - } - } - return col; - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorPreferences.cs.meta b/Scripts/Editor/NodeEditorPreferences.cs.meta deleted file mode 100644 index 156543b..0000000 --- a/Scripts/Editor/NodeEditorPreferences.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 6b1f47e387a6f714c9f2ff82a6888c85 -timeCreated: 1507920216 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorReflection.cs b/Scripts/Editor/NodeEditorReflection.cs deleted file mode 100644 index 0a0a36a..0000000 --- a/Scripts/Editor/NodeEditorReflection.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor; -using UnityEngine; - -namespace XNodeEditor { - /// Contains reflection-related extensions built for xNode - public static class NodeEditorReflection { - [NonSerialized] private static Dictionary nodeTint; - [NonSerialized] private static Dictionary nodeWidth; - /// All available node types - public static Type[] nodeTypes { get { return _nodeTypes != null ? _nodeTypes : _nodeTypes = GetNodeTypes(); } } - - [NonSerialized] private static Type[] _nodeTypes = null; - - /// Return a delegate used to determine whether window is docked or not. It is faster to cache this delegate than run the reflection required each time. - public static Func GetIsDockedDelegate(this EditorWindow window) { - BindingFlags fullBinding = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; - MethodInfo isDockedMethod = typeof(EditorWindow).GetProperty("docked", fullBinding).GetGetMethod(true); - return (Func) Delegate.CreateDelegate(typeof(Func), window, isDockedMethod); - } - - public static Type[] GetNodeTypes() { - //Get all classes deriving from Node via reflection - return GetDerivedTypes(typeof(XNode.Node)); - } - - /// Custom node tint colors defined with [NodeColor(r, g, b)] - public static bool TryGetAttributeTint(this Type nodeType, out Color tint) { - if (nodeTint == null) { - CacheAttributes(ref nodeTint, x => x.color); - } - return nodeTint.TryGetValue(nodeType, out tint); - } - - /// Get custom node widths defined with [NodeWidth(width)] - public static bool TryGetAttributeWidth(this Type nodeType, out int width) { - if (nodeWidth == null) { - CacheAttributes(ref nodeWidth, x => x.width); - } - return nodeWidth.TryGetValue(nodeType, out width); - } - - private static void CacheAttributes(ref Dictionary dict, Func getter) where A : Attribute { - dict = new Dictionary(); - for (int i = 0; i < nodeTypes.Length; i++) { - object[] attribs = nodeTypes[i].GetCustomAttributes(typeof(A), true); - if (attribs == null || attribs.Length == 0) continue; - A attrib = attribs[0] as A; - dict.Add(nodeTypes[i], getter(attrib)); - } - } - - /// Get FieldInfo of a field, including those that are private and/or inherited - public static FieldInfo GetFieldInfo(this Type type, string fieldName) { - // If we can't find field in the first run, it's probably a private field in a base class. - FieldInfo field = type.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - // Search base classes for private fields only. Public fields are found above - while (field == null && (type = type.BaseType) != typeof(XNode.Node)) field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); - return field; - } - - /// Get all classes deriving from baseType via reflection - public static Type[] GetDerivedTypes(this Type baseType) { - List types = new List(); - System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); - foreach (Assembly assembly in assemblies) { - try { - types.AddRange(assembly.GetTypes().Where(t => !t.IsAbstract && baseType.IsAssignableFrom(t)).ToArray()); - } catch (ReflectionTypeLoadException) { } - } - return types.ToArray(); - } - - /// Find methods marked with the [ContextMenu] attribute and add them to the context menu - public static void AddCustomContextMenuItems(this GenericMenu contextMenu, object obj) { - KeyValuePair[] items = GetContextMenuMethods(obj); - if (items.Length != 0) { - contextMenu.AddSeparator(""); - List invalidatedEntries = new List(); - foreach (KeyValuePair checkValidate in items) { - if (checkValidate.Key.validate && !(bool) checkValidate.Value.Invoke(obj, null)) { - invalidatedEntries.Add(checkValidate.Key.menuItem); - } - } - for (int i = 0; i < items.Length; i++) { - KeyValuePair kvp = items[i]; - if (invalidatedEntries.Contains(kvp.Key.menuItem)) { - contextMenu.AddDisabledItem(new GUIContent(kvp.Key.menuItem)); - } else { - contextMenu.AddItem(new GUIContent(kvp.Key.menuItem), false, () => kvp.Value.Invoke(obj, null)); - } - } - } - } - - /// Call OnValidate on target - public static void TriggerOnValidate(this UnityEngine.Object target) { - System.Reflection.MethodInfo onValidate = null; - if (target != null) { - onValidate = target.GetType().GetMethod("OnValidate", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - if (onValidate != null) onValidate.Invoke(target, null); - } - } - - public static KeyValuePair[] GetContextMenuMethods(object obj) { - Type type = obj.GetType(); - MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); - List> kvp = new List>(); - for (int i = 0; i < methods.Length; i++) { - ContextMenu[] attribs = methods[i].GetCustomAttributes(typeof(ContextMenu), true).Select(x => x as ContextMenu).ToArray(); - if (attribs == null || attribs.Length == 0) continue; - if (methods[i].GetParameters().Length != 0) { - Debug.LogWarning("Method " + methods[i].DeclaringType.Name + "." + methods[i].Name + " has parameters and cannot be used for context menu commands."); - continue; - } - if (methods[i].IsStatic) { - Debug.LogWarning("Method " + methods[i].DeclaringType.Name + "." + methods[i].Name + " is static and cannot be used for context menu commands."); - continue; - } - - for (int k = 0; k < attribs.Length; k++) { - kvp.Add(new KeyValuePair(attribs[k], methods[i])); - } - } -#if UNITY_5_5_OR_NEWER - //Sort menu items - kvp.Sort((x, y) => x.Key.priority.CompareTo(y.Key.priority)); -#endif - return kvp.ToArray(); - } - - /// Very crude. Uses a lot of reflection. - public static void OpenPreferences() { - try { -#if UNITY_2018_3_OR_NEWER - SettingsService.OpenUserPreferences("Preferences/Node Editor"); -#else - //Open preferences window - Assembly assembly = Assembly.GetAssembly(typeof(UnityEditor.EditorWindow)); - Type type = assembly.GetType("UnityEditor.PreferencesWindow"); - type.GetMethod("ShowPreferencesWindow", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); - - //Get the window - EditorWindow window = EditorWindow.GetWindow(type); - - //Make sure custom sections are added (because waiting for it to happen automatically is too slow) - FieldInfo refreshField = type.GetField("m_RefreshCustomPreferences", BindingFlags.NonPublic | BindingFlags.Instance); - if ((bool) refreshField.GetValue(window)) { - type.GetMethod("AddCustomSections", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(window, null); - refreshField.SetValue(window, false); - } - - //Get sections - FieldInfo sectionsField = type.GetField("m_Sections", BindingFlags.Instance | BindingFlags.NonPublic); - IList sections = sectionsField.GetValue(window) as IList; - - //Iterate through sections and check contents - Type sectionType = sectionsField.FieldType.GetGenericArguments() [0]; - FieldInfo sectionContentField = sectionType.GetField("content", BindingFlags.Instance | BindingFlags.Public); - for (int i = 0; i < sections.Count; i++) { - GUIContent sectionContent = sectionContentField.GetValue(sections[i]) as GUIContent; - if (sectionContent.text == "Node Editor") { - //Found contents - Set index - FieldInfo sectionIndexField = type.GetField("m_SelectedSectionIndex", BindingFlags.Instance | BindingFlags.NonPublic); - sectionIndexField.SetValue(window, i); - return; - } - } -#endif - } catch (Exception e) { - Debug.LogError(e); - Debug.LogWarning("Unity has changed around internally. Can't open properties through reflection. Please contact xNode developer and supply unity version number."); - } - } - } -} diff --git a/Scripts/Editor/NodeEditorReflection.cs.meta b/Scripts/Editor/NodeEditorReflection.cs.meta deleted file mode 100644 index fe4ba9b..0000000 --- a/Scripts/Editor/NodeEditorReflection.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: c78a0fa4a13abcd408ebe73006b7b1bb -timeCreated: 1505419458 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorResources.cs b/Scripts/Editor/NodeEditorResources.cs deleted file mode 100644 index 0a84e0a..0000000 --- a/Scripts/Editor/NodeEditorResources.cs +++ /dev/null @@ -1,87 +0,0 @@ -using UnityEditor; -using UnityEngine; - -namespace XNodeEditor { - public static class NodeEditorResources { - // Textures - public static Texture2D dot { get { return _dot != null ? _dot : _dot = Resources.Load("xnode_dot"); } } - private static Texture2D _dot; - public static Texture2D dotOuter { get { return _dotOuter != null ? _dotOuter : _dotOuter = Resources.Load("xnode_dot_outer"); } } - private static Texture2D _dotOuter; - public static Texture2D nodeBody { get { return _nodeBody != null ? _nodeBody : _nodeBody = Resources.Load("xnode_node"); } } - private static Texture2D _nodeBody; - public static Texture2D nodeHighlight { get { return _nodeHighlight != null ? _nodeHighlight : _nodeHighlight = Resources.Load("xnode_node_highlight"); } } - private static Texture2D _nodeHighlight; - - // Styles - public static Styles styles { get { return _styles != null ? _styles : _styles = new Styles(); } } - public static Styles _styles = null; - public static GUIStyle OutputPort { get { return new GUIStyle(EditorStyles.label) { alignment = TextAnchor.UpperRight }; } } - public class Styles { - public GUIStyle inputPort, nodeHeader, nodeBody, tooltip, nodeHighlight; - - public Styles() { - GUIStyle baseStyle = new GUIStyle("Label"); - baseStyle.fixedHeight = 18; - - inputPort = new GUIStyle(baseStyle); - inputPort.alignment = TextAnchor.UpperLeft; - inputPort.padding.left = 10; - - nodeHeader = new GUIStyle(); - nodeHeader.alignment = TextAnchor.MiddleCenter; - nodeHeader.fontStyle = FontStyle.Bold; - nodeHeader.normal.textColor = Color.white; - - nodeBody = new GUIStyle(); - nodeBody.normal.background = NodeEditorResources.nodeBody; - nodeBody.border = new RectOffset(32, 32, 32, 32); - nodeBody.padding = new RectOffset(16, 16, 4, 16); - - nodeHighlight = new GUIStyle(); - nodeHighlight.normal.background = NodeEditorResources.nodeHighlight; - nodeHighlight.border = new RectOffset(32, 32, 32, 32); - - tooltip = new GUIStyle("helpBox"); - tooltip.alignment = TextAnchor.MiddleCenter; - } - } - - public static Texture2D GenerateGridTexture(Color line, Color bg) { - Texture2D tex = new Texture2D(64, 64); - Color[] cols = new Color[64 * 64]; - for (int y = 0; y < 64; y++) { - for (int x = 0; x < 64; x++) { - Color col = bg; - if (y % 16 == 0 || x % 16 == 0) col = Color.Lerp(line, bg, 0.65f); - if (y == 63 || x == 63) col = Color.Lerp(line, bg, 0.35f); - cols[(y * 64) + x] = col; - } - } - tex.SetPixels(cols); - tex.wrapMode = TextureWrapMode.Repeat; - tex.filterMode = FilterMode.Bilinear; - tex.name = "Grid"; - tex.Apply(); - return tex; - } - - public static Texture2D GenerateCrossTexture(Color line) { - Texture2D tex = new Texture2D(64, 64); - Color[] cols = new Color[64 * 64]; - for (int y = 0; y < 64; y++) { - for (int x = 0; x < 64; x++) { - Color col = line; - if (y != 31 && x != 31) col.a = 0; - cols[(y * 64) + x] = col; - } - } - tex.SetPixels(cols); - tex.wrapMode = TextureWrapMode.Clamp; - tex.filterMode = FilterMode.Bilinear; - tex.name = "Grid"; - tex.Apply(); - return tex; - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorResources.cs.meta b/Scripts/Editor/NodeEditorResources.cs.meta deleted file mode 100644 index 5e85895..0000000 --- a/Scripts/Editor/NodeEditorResources.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 69f55d341299026489b29443c3dd13d1 -timeCreated: 1505418919 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorUtilities.cs b/Scripts/Editor/NodeEditorUtilities.cs deleted file mode 100644 index bf92ba8..0000000 --- a/Scripts/Editor/NodeEditorUtilities.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using UnityEditor; -using UnityEngine; -using Object = UnityEngine.Object; - -namespace XNodeEditor { - /// A set of editor-only utilities and extensions for xNode - public static class NodeEditorUtilities { - - /// C#'s Script Icon [The one MonoBhevaiour Scripts have]. - private static Texture2D scriptIcon = (EditorGUIUtility.IconContent("cs Script Icon").image as Texture2D); - - /// Saves Attribute from Type+Field for faster lookup. Resets on recompiles. - private static Dictionary>> typeAttributes = new Dictionary>>(); - - public static bool GetAttrib(Type classType, out T attribOut) where T : Attribute { - object[] attribs = classType.GetCustomAttributes(typeof(T), false); - return GetAttrib(attribs, out attribOut); - } - - public static bool GetAttrib(object[] attribs, out T attribOut) where T : Attribute { - for (int i = 0; i < attribs.Length; i++) { - if (attribs[i] is T) { - attribOut = attribs[i] as T; - return true; - } - } - attribOut = null; - return false; - } - - public static bool GetAttrib(Type classType, string fieldName, out T attribOut) where T : Attribute { - // If we can't find field in the first run, it's probably a private field in a base class. - FieldInfo field = classType.GetFieldInfo(fieldName); - // This shouldn't happen. Ever. - if (field == null) { - Debug.LogWarning("Field " + fieldName + " couldnt be found"); - attribOut = null; - return false; - } - object[] attribs = field.GetCustomAttributes(typeof(T), true); - return GetAttrib(attribs, out attribOut); - } - - public static bool HasAttrib(object[] attribs) where T : Attribute { - for (int i = 0; i < attribs.Length; i++) { - if (attribs[i].GetType() == typeof(T)) { - return true; - } - } - return false; - } - - public static bool GetCachedAttrib(Type classType, string fieldName, out T attribOut) where T : Attribute { - Dictionary> typeFields; - if (!typeAttributes.TryGetValue(classType, out typeFields)) { - typeFields = new Dictionary>(); - typeAttributes.Add(classType, typeFields); - } - - Dictionary typeTypes; - if (!typeFields.TryGetValue(fieldName, out typeTypes)) { - typeTypes = new Dictionary(); - typeFields.Add(fieldName, typeTypes); - } - - Attribute attr; - if (!typeTypes.TryGetValue(typeof(T), out attr)) { - if (GetAttrib(classType, fieldName, out attribOut)) typeTypes.Add(typeof(T), attribOut); - else typeTypes.Add(typeof(T), null); - } - - if (attr == null) { - attribOut = null; - return false; - } - - attribOut = attr as T; - return true; - } - - public static bool IsMac() { -#if UNITY_2017_1_OR_NEWER - return SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX; -#else - return SystemInfo.operatingSystem.StartsWith("Mac"); -#endif - } - - /// Returns true if this can be casted to - public static bool IsCastableTo(this Type from, Type to) { - if (to.IsAssignableFrom(from)) return true; - var methods = from.GetMethods(BindingFlags.Public | BindingFlags.Static) - .Where( - m => m.ReturnType == to && - (m.Name == "op_Implicit" || - m.Name == "op_Explicit") - ); - return methods.Count() > 0; - } - - /// Return a prettiefied type name. - public static string PrettyName(this Type type) { - if (type == null) return "null"; - if (type == typeof(System.Object)) return "object"; - if (type == typeof(float)) return "float"; - else if (type == typeof(int)) return "int"; - else if (type == typeof(long)) return "long"; - else if (type == typeof(double)) return "double"; - else if (type == typeof(string)) return "string"; - else if (type == typeof(bool)) return "bool"; - else if (type.IsGenericType) { - string s = ""; - Type genericType = type.GetGenericTypeDefinition(); - if (genericType == typeof(List<>)) s = "List"; - else s = type.GetGenericTypeDefinition().ToString(); - - Type[] types = type.GetGenericArguments(); - string[] stypes = new string[types.Length]; - for (int i = 0; i < types.Length; i++) { - stypes[i] = types[i].PrettyName(); - } - return s + "<" + string.Join(", ", stypes) + ">"; - } else if (type.IsArray) { - string rank = ""; - for (int i = 1; i < type.GetArrayRank(); i++) { - rank += ","; - } - Type elementType = type.GetElementType(); - if (!elementType.IsArray) return elementType.PrettyName() + "[" + rank + "]"; - else { - string s = elementType.PrettyName(); - int i = s.IndexOf('['); - return s.Substring(0, i) + "[" + rank + "]" + s.Substring(i); - } - } else return type.ToString(); - } - - /// Returns the default name for the node type. - public static string NodeDefaultName(Type type) { - string typeName = type.Name; - // Automatically remove redundant 'Node' postfix - if (typeName.EndsWith("Node")) typeName = typeName.Substring(0, typeName.LastIndexOf("Node")); - typeName = UnityEditor.ObjectNames.NicifyVariableName(typeName); - return typeName; - } - - /// Returns the default creation path for the node type. - public static string NodeDefaultPath(Type type) { - string typePath = type.ToString().Replace('.', '/'); - // Automatically remove redundant 'Node' postfix - if (typePath.EndsWith("Node")) typePath = typePath.Substring(0, typePath.LastIndexOf("Node")); - typePath = UnityEditor.ObjectNames.NicifyVariableName(typePath); - return typePath; - } - - /// Creates a new C# Class. - [MenuItem("Assets/Create/xNode/Node C# Script", false, 89)] - private static void CreateNode() { - string[] guids = AssetDatabase.FindAssets("xNode_NodeTemplate.cs"); - if (guids.Length == 0) { - Debug.LogWarning("xNode_NodeTemplate.cs.txt not found in asset database"); - return; - } - string path = AssetDatabase.GUIDToAssetPath(guids[0]); - CreateFromTemplate( - "NewNode.cs", - path - ); - } - - /// Creates a new C# Class. - [MenuItem("Assets/Create/xNode/NodeGraph C# Script", false, 89)] - private static void CreateGraph() { - string[] guids = AssetDatabase.FindAssets("xNode_NodeGraphTemplate.cs"); - if (guids.Length == 0) { - Debug.LogWarning("xNode_NodeGraphTemplate.cs.txt not found in asset database"); - return; - } - string path = AssetDatabase.GUIDToAssetPath(guids[0]); - CreateFromTemplate( - "NewNodeGraph.cs", - path - ); - } - - public static void CreateFromTemplate(string initialName, string templatePath) { - ProjectWindowUtil.StartNameEditingIfProjectWindowExists( - 0, - ScriptableObject.CreateInstance(), - initialName, - scriptIcon, - templatePath - ); - } - - /// Inherits from EndNameAction, must override EndNameAction.Action - public class DoCreateCodeFile : UnityEditor.ProjectWindowCallback.EndNameEditAction { - public override void Action(int instanceId, string pathName, string resourceFile) { - Object o = CreateScript(pathName, resourceFile); - ProjectWindowUtil.ShowCreatedAsset(o); - } - } - - /// Creates Script from Template's path. - internal static UnityEngine.Object CreateScript(string pathName, string templatePath) { - string className = Path.GetFileNameWithoutExtension(pathName).Replace(" ", string.Empty); - string templateText = string.Empty; - - UTF8Encoding encoding = new UTF8Encoding(true, false); - - if (File.Exists(templatePath)) { - /// Read procedures. - StreamReader reader = new StreamReader(templatePath); - templateText = reader.ReadToEnd(); - reader.Close(); - - templateText = templateText.Replace("#SCRIPTNAME#", className); - templateText = templateText.Replace("#NOTRIM#", string.Empty); - /// You can replace as many tags you make on your templates, just repeat Replace function - /// e.g.: - /// templateText = templateText.Replace("#NEWTAG#", "MyText"); - - /// Write procedures. - - StreamWriter writer = new StreamWriter(Path.GetFullPath(pathName), false, encoding); - writer.Write(templateText); - writer.Close(); - - AssetDatabase.ImportAsset(pathName); - return AssetDatabase.LoadAssetAtPath(pathName, typeof(Object)); - } else { - Debug.LogError(string.Format("The template file was not found: {0}", templatePath)); - return null; - } - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorUtilities.cs.meta b/Scripts/Editor/NodeEditorUtilities.cs.meta deleted file mode 100644 index a8988ef..0000000 --- a/Scripts/Editor/NodeEditorUtilities.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 120960fe5b50aba418a8e8ad3c4c4bc8 -timeCreated: 1506073499 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorWindow.cs b/Scripts/Editor/NodeEditorWindow.cs deleted file mode 100644 index a063410..0000000 --- a/Scripts/Editor/NodeEditorWindow.cs +++ /dev/null @@ -1,206 +0,0 @@ -using System.Collections.Generic; -using UnityEditor; -using UnityEditor.Callbacks; -using UnityEngine; -using System; -using Object = UnityEngine.Object; - -namespace XNodeEditor { - [InitializeOnLoad] - public partial class NodeEditorWindow : EditorWindow { - public static NodeEditorWindow current; - - /// Stores node positions for all nodePorts. - public Dictionary portConnectionPoints { get { return _portConnectionPoints; } } - private Dictionary _portConnectionPoints = new Dictionary(); - [SerializeField] private NodePortReference[] _references = new NodePortReference[0]; - [SerializeField] private Rect[] _rects = new Rect[0]; - - private Func isDocked { - get { - if (_isDocked == null) _isDocked = this.GetIsDockedDelegate(); - return _isDocked; - } - } - private Func _isDocked; - - [System.Serializable] private class NodePortReference { - [SerializeField] private XNode.Node _node; - [SerializeField] private string _name; - - public NodePortReference(XNode.NodePort nodePort) { - _node = nodePort.node; - _name = nodePort.fieldName; - } - - public XNode.NodePort GetNodePort() { - if (_node == null) { - return null; - } - return _node.GetPort(_name); - } - } - - private void OnDisable() { - // Cache portConnectionPoints before serialization starts - int count = portConnectionPoints.Count; - _references = new NodePortReference[count]; - _rects = new Rect[count]; - int index = 0; - foreach (var portConnectionPoint in portConnectionPoints) { - _references[index] = new NodePortReference(portConnectionPoint.Key); - _rects[index] = portConnectionPoint.Value; - index++; - } - } - - private void OnEnable() { - // Reload portConnectionPoints if there are any - int length = _references.Length; - if (length == _rects.Length) { - for (int i = 0; i < length; i++) { - XNode.NodePort nodePort = _references[i].GetNodePort(); - if (nodePort != null) - _portConnectionPoints.Add(nodePort, _rects[i]); - } - } - } - - public Dictionary nodeSizes { get { return _nodeSizes; } } - private Dictionary _nodeSizes = new Dictionary(); - public XNode.NodeGraph graph; - public Vector2 panOffset { get { return _panOffset; } set { _panOffset = value; Repaint(); } } - private Vector2 _panOffset; - public float zoom { get { return _zoom; } set { _zoom = Mathf.Clamp(value, NodeEditorPreferences.GetSettings().minZoom, NodeEditorPreferences.GetSettings().maxZoom); Repaint(); } } - private float _zoom = 1; - - void OnFocus() { - current = this; - ValidateGraphEditor(); - if (graphEditor != null && NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } - - [InitializeOnLoadMethod] - private static void OnLoad() { - Selection.selectionChanged -= OnSelectionChanged; - Selection.selectionChanged += OnSelectionChanged; - } - - /// Handle Selection Change events - private static void OnSelectionChanged() { - XNode.NodeGraph nodeGraph = Selection.activeObject as XNode.NodeGraph; - if (nodeGraph && !AssetDatabase.Contains(nodeGraph)) { - Open(nodeGraph); - } - } - - /// Make sure the graph editor is assigned and to the right object - private void ValidateGraphEditor() { - NodeGraphEditor graphEditor = NodeGraphEditor.GetEditor(graph, this); - if (this.graphEditor != graphEditor) { - this.graphEditor = graphEditor; - graphEditor.OnOpen(); - } - } - - /// Create editor window - public static NodeEditorWindow Init() { - NodeEditorWindow w = CreateInstance(); - w.titleContent = new GUIContent("xNode"); - w.wantsMouseMove = true; - w.Show(); - return w; - } - - public void Save() { - if (AssetDatabase.Contains(graph)) { - EditorUtility.SetDirty(graph); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } else SaveAs(); - } - - public void SaveAs() { - string path = EditorUtility.SaveFilePanelInProject("Save NodeGraph", "NewNodeGraph", "asset", ""); - if (string.IsNullOrEmpty(path)) return; - else { - XNode.NodeGraph existingGraph = AssetDatabase.LoadAssetAtPath(path); - if (existingGraph != null) AssetDatabase.DeleteAsset(path); - AssetDatabase.CreateAsset(graph, path); - EditorUtility.SetDirty(graph); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } - } - - private void DraggableWindow(int windowID) { - GUI.DragWindow(); - } - - public Vector2 WindowToGridPosition(Vector2 windowPosition) { - return (windowPosition - (position.size * 0.5f) - (panOffset / zoom)) * zoom; - } - - public Vector2 GridToWindowPosition(Vector2 gridPosition) { - return (position.size * 0.5f) + (panOffset / zoom) + (gridPosition / zoom); - } - - public Rect GridToWindowRectNoClipped(Rect gridRect) { - gridRect.position = GridToWindowPositionNoClipped(gridRect.position); - return gridRect; - } - - public Rect GridToWindowRect(Rect gridRect) { - gridRect.position = GridToWindowPosition(gridRect.position); - gridRect.size /= zoom; - return gridRect; - } - - public Vector2 GridToWindowPositionNoClipped(Vector2 gridPosition) { - Vector2 center = position.size * 0.5f; - // UI Sharpness complete fix - Round final offset not panOffset - float xOffset = Mathf.Round(center.x * zoom + (panOffset.x + gridPosition.x)); - float yOffset = Mathf.Round(center.y * zoom + (panOffset.y + gridPosition.y)); - return new Vector2(xOffset, yOffset); - } - - public void SelectNode(XNode.Node node, bool add) { - if (add) { - List selection = new List(Selection.objects); - selection.Add(node); - Selection.objects = selection.ToArray(); - } else Selection.objects = new Object[] { node }; - } - - public void DeselectNode(XNode.Node node) { - List selection = new List(Selection.objects); - selection.Remove(node); - Selection.objects = selection.ToArray(); - } - - [OnOpenAsset(0)] - public static bool OnOpen(int instanceID, int line) { - XNode.NodeGraph nodeGraph = EditorUtility.InstanceIDToObject(instanceID) as XNode.NodeGraph; - if (nodeGraph != null) { - Open(nodeGraph); - return true; - } - return false; - } - - /// Open the provided graph in the NodeEditor - public static void Open(XNode.NodeGraph graph) { - if (!graph) return; - - NodeEditorWindow w = GetWindow(typeof(NodeEditorWindow), false, "xNode", true) as NodeEditorWindow; - w.wantsMouseMove = true; - w.graph = graph; - } - - /// Repaint all open NodeEditorWindows. - public static void RepaintAll() { - NodeEditorWindow[] windows = Resources.FindObjectsOfTypeAll(); - for (int i = 0; i < windows.Length; i++) { - windows[i].Repaint(); - } - } - } -} diff --git a/Scripts/Editor/NodeEditorWindow.cs.meta b/Scripts/Editor/NodeEditorWindow.cs.meta deleted file mode 100644 index 541b5c7..0000000 --- a/Scripts/Editor/NodeEditorWindow.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5ce2bf59ec7a25c4ba691cad7819bf38 -timeCreated: 1505418450 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs deleted file mode 100644 index a45d566..0000000 --- a/Scripts/Editor/NodeGraphEditor.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; - -namespace XNodeEditor { - /// Base class to derive custom Node Graph editors from. Use this to override how graphs are drawn in the editor. - [CustomNodeGraphEditor(typeof(XNode.NodeGraph))] - public class NodeGraphEditor : XNodeEditor.Internal.NodeEditorBase { - [Obsolete("Use window.position instead")] - public Rect position { get { return window.position; } set { window.position = value; } } - /// Are we currently renaming a node? - protected bool isRenaming; - - public virtual void OnGUI() { } - - /// Called when opened by NodeEditorWindow - public virtual void OnOpen() { } - - public virtual Texture2D GetGridTexture() { - return NodeEditorPreferences.GetSettings().gridTexture; - } - - public virtual Texture2D GetSecondaryGridTexture() { - return NodeEditorPreferences.GetSettings().crossTexture; - } - - /// Return default settings for this graph type. This is the settings the user will load if no previous settings have been saved. - public virtual NodeEditorPreferences.Settings GetDefaultPreferences() { - return new NodeEditorPreferences.Settings(); - } - - /// Returns context node menu path. Null or empty strings for hidden nodes. - public virtual string GetNodeMenuName(Type type) { - //Check if type has the CreateNodeMenuAttribute - XNode.Node.CreateNodeMenuAttribute attrib; - if (NodeEditorUtilities.GetAttrib(type, out attrib)) // Return custom path - return attrib.menuName; - else // Return generated path - return NodeEditorUtilities.NodeDefaultPath(type); - } - - /// Add items for the context menu when right-clicking this node. Override to add custom menu items. - public virtual void AddContextMenuItems(GenericMenu menu) { - Vector2 pos = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition); - for (int i = 0; i < NodeEditorReflection.nodeTypes.Length; i++) { - Type type = NodeEditorReflection.nodeTypes[i]; - - //Get node context menu path - string path = GetNodeMenuName(type); - if (string.IsNullOrEmpty(path)) continue; - - menu.AddItem(new GUIContent(path), false, () => { - CreateNode(type, pos); - }); - } - menu.AddSeparator(""); - if (NodeEditorWindow.copyBuffer != null && NodeEditorWindow.copyBuffer.Length > 0) menu.AddItem(new GUIContent("Paste"), false, () => NodeEditorWindow.current.PasteNodes(pos)); - else menu.AddDisabledItem(new GUIContent("Paste")); - menu.AddItem(new GUIContent("Preferences"), false, () => NodeEditorReflection.OpenPreferences()); - menu.AddCustomContextMenuItems(target); - } - - public virtual Color GetPortColor(XNode.NodePort port) { - return GetTypeColor(port.ValueType); - } - - public virtual Color GetTypeColor(Type type) { - return NodeEditorPreferences.GetTypeColor(type); - } - - public virtual string GetPortTooltip(XNode.NodePort port) { - Type portType = port.ValueType; - string tooltip = ""; - tooltip = portType.PrettyName(); - if (port.IsOutput) { - object obj = port.node.GetValue(port); - tooltip += " = " + (obj != null ? obj.ToString() : "null"); - } - return tooltip; - } - - /// Deal with objects dropped into the graph through DragAndDrop - public virtual void OnDropObjects(UnityEngine.Object[] objects) { - Debug.Log("No OnDropItems override defined for " + GetType()); - } - - /// Create a node and save it in the graph asset - public virtual void CreateNode(Type type, Vector2 position) { - XNode.Node node = target.AddNode(type); - node.position = position; - if (node.name == null || node.name.Trim() == "") node.name = NodeEditorUtilities.NodeDefaultName(type); - AssetDatabase.AddObjectToAsset(node, target); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - NodeEditorWindow.RepaintAll(); - } - - /// Creates a copy of the original node in the graph - public XNode.Node CopyNode(XNode.Node original) { - XNode.Node node = target.CopyNode(original); - node.name = original.name; - AssetDatabase.AddObjectToAsset(node, target); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - return node; - } - - /// Safely remove a node and all its connections. - public virtual void RemoveNode(XNode.Node node) { - target.RemoveNode(node); - UnityEngine.Object.DestroyImmediate(node, true); - if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); - } - - [AttributeUsage(AttributeTargets.Class)] - public class CustomNodeGraphEditorAttribute : Attribute, - XNodeEditor.Internal.NodeEditorBase.INodeEditorAttrib { - private Type inspectedType; - public string editorPrefsKey; - /// Tells a NodeGraphEditor which Graph type it is an editor for - /// Type that this editor can edit - /// Define unique key for unique layout settings instance - public CustomNodeGraphEditorAttribute(Type inspectedType, string editorPrefsKey = "xNode.Settings") { - this.inspectedType = inspectedType; - this.editorPrefsKey = editorPrefsKey; - } - - public Type GetInspectedType() { - return inspectedType; - } - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/NodeGraphEditor.cs.meta b/Scripts/Editor/NodeGraphEditor.cs.meta deleted file mode 100644 index bc1c153..0000000 --- a/Scripts/Editor/NodeGraphEditor.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: ddcbb5432255d3247a0718b15a9c193c -timeCreated: 1505462176 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/RenamePopup.cs b/Scripts/Editor/RenamePopup.cs deleted file mode 100644 index 564374e..0000000 --- a/Scripts/Editor/RenamePopup.cs +++ /dev/null @@ -1,68 +0,0 @@ -using UnityEditor; -using UnityEngine; - -namespace XNodeEditor { - /// Utility for renaming assets - public class RenamePopup : EditorWindow { - public static RenamePopup current { get; private set; } - public Object target; - public string input; - - private bool firstFrame = true; - - /// Show a rename popup for an asset at mouse position. Will trigger reimport of the asset on apply. - public static RenamePopup Show(Object target, float width = 200) { - RenamePopup window = EditorWindow.GetWindow(true, "Rename " + target.name, true); - if (current != null) current.Close(); - current = window; - window.target = target; - window.input = target.name; - window.minSize = new Vector2(100, 44); - window.position = new Rect(0, 0, width, 44); - GUI.FocusControl("ClearAllFocus"); - window.UpdatePositionToMouse(); - return window; - } - - private void UpdatePositionToMouse() { - if (Event.current == null) return; - Vector3 mousePoint = GUIUtility.GUIToScreenPoint(Event.current.mousePosition); - Rect pos = position; - pos.x = mousePoint.x - position.width * 0.5f; - pos.y = mousePoint.y - 10; - position = pos; - } - - private void OnLostFocus() { - // Make the popup close on lose focus - Close(); - } - - private void OnGUI() { - if (firstFrame) { - UpdatePositionToMouse(); - firstFrame = false; - } - input = EditorGUILayout.TextField(input); - Event e = Event.current; - // If input is empty, revert name to default instead - if (input == null || input.Trim() == "") { - if (GUILayout.Button("Revert to default") || (e.isKey && e.keyCode == KeyCode.Return)) { - target.name = NodeEditorUtilities.NodeDefaultName(target.GetType()); - AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target)); - Close(); - target.TriggerOnValidate(); - } - } - // Rename asset to input text - else { - if (GUILayout.Button("Apply") || (e.isKey && e.keyCode == KeyCode.Return)) { - target.name = input; - AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target)); - Close(); - target.TriggerOnValidate(); - } - } - } - } -} \ No newline at end of file diff --git a/Scripts/Editor/RenamePopup.cs.meta b/Scripts/Editor/RenamePopup.cs.meta deleted file mode 100644 index 5c40a02..0000000 --- a/Scripts/Editor/RenamePopup.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 4ef3ddc25518318469bce838980c64be -timeCreated: 1552067957 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Resources.meta b/Scripts/Editor/Resources.meta deleted file mode 100644 index 786ef41..0000000 --- a/Scripts/Editor/Resources.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 964fc201163fe884ca6a20094b6f3b49 -folderAsset: yes -timeCreated: 1506110871 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Resources/ScriptTemplates.meta b/Scripts/Editor/Resources/ScriptTemplates.meta deleted file mode 100644 index b2435e8..0000000 --- a/Scripts/Editor/Resources/ScriptTemplates.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 86b677955452bb5449f9f4dd47b6ddfe -folderAsset: yes -timeCreated: 1519049391 -licenseType: Free -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeGraphTemplate.cs.txt b/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeGraphTemplate.cs.txt deleted file mode 100644 index e3d7c36..0000000 --- a/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeGraphTemplate.cs.txt +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using XNode; - -[CreateAssetMenu] -public class #SCRIPTNAME# : NodeGraph { - #NOTRIM# -} \ No newline at end of file diff --git a/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeGraphTemplate.cs.txt.meta b/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeGraphTemplate.cs.txt.meta deleted file mode 100644 index b55bd75..0000000 --- a/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeGraphTemplate.cs.txt.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 8165767f64da7d94e925f61a38da668c -timeCreated: 1519049802 -licenseType: Free -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeTemplate.cs.txt b/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeTemplate.cs.txt deleted file mode 100644 index de791fc..0000000 --- a/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeTemplate.cs.txt +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using XNode; - -public class #SCRIPTNAME# : Node { - - // Use this for initialization - protected override void Init() { - base.Init(); - #NOTRIM# - } - - // Return the correct value of an output port when requested - public override object GetValue(NodePort port) { - return null; // Replace this - } -} \ No newline at end of file diff --git a/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeTemplate.cs.txt.meta b/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeTemplate.cs.txt.meta deleted file mode 100644 index 455420a..0000000 --- a/Scripts/Editor/Resources/ScriptTemplates/xNode_NodeTemplate.cs.txt.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 85f6f570600a1a44d8e734cb111a8b89 -timeCreated: 1519049802 -licenseType: Free -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Resources/xnode_dot.png b/Scripts/Editor/Resources/xnode_dot.png deleted file mode 100644 index 36c0ce937490b4380137cd287a00095f16c59b31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18297 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 B2}l3{ diff --git a/Scripts/Editor/Resources/xnode_dot.png.meta b/Scripts/Editor/Resources/xnode_dot.png.meta deleted file mode 100644 index 00c23bc..0000000 --- a/Scripts/Editor/Resources/xnode_dot.png.meta +++ /dev/null @@ -1,98 +0,0 @@ -fileFormatVersion: 2 -guid: 75a1fe0b102226a418486ed823c9a7fb -timeCreated: 1506110357 -licenseType: Free -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - sRGBTexture: 0 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -1 - wrapU: 1 - wrapV: -1 - wrapW: -1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaUsage: 1 - alphaIsTransparency: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - - buildTarget: Standalone - maxTextureSize: 2048 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - - buildTarget: Android - maxTextureSize: 2048 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - - buildTarget: WebGL - maxTextureSize: 2048 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Resources/xnode_dot_outer.png b/Scripts/Editor/Resources/xnode_dot_outer.png deleted file mode 100644 index 538cc9fa1ed169cf7797e8cf4304b202f5754b8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18346 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 MSz%pd<+tsB0L%jEQ~&?~ diff --git a/Scripts/Editor/Resources/xnode_node_highlight.png.meta b/Scripts/Editor/Resources/xnode_node_highlight.png.meta deleted file mode 100644 index 21b6034..0000000 --- a/Scripts/Editor/Resources/xnode_node_highlight.png.meta +++ /dev/null @@ -1,87 +0,0 @@ -fileFormatVersion: 2 -guid: 2ab2b92d7e1771b47bba0a46a6f0f6d5 -timeCreated: 1516610730 -licenseType: Free -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - sRGBTexture: 0 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -1 - wrapU: 1 - wrapV: 1 - wrapW: -1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaUsage: 1 - alphaIsTransparency: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Editor/Resources/xnode_node_workfile.psd b/Scripts/Editor/Resources/xnode_node_workfile.psd deleted file mode 100644 index a578c46f72983f361977f536f07fe3642b1ad2eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33269 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 I - /// Base class for all nodes - /// - /// - /// Classes extending this class will be considered as valid nodes by xNode. - /// - /// [System.Serializable] - /// public class Adder : Node { - /// [Input] public float a; - /// [Input] public float b; - /// [Output] public float result; - /// - /// // GetValue should be overridden to return a value for any specified output port - /// public override object GetValue(NodePort port) { - /// return a + b; - /// } - /// } - /// - /// - [Serializable] - public abstract class Node : ScriptableObject { - /// Used by and to determine when to display the field value associated with a - public enum ShowBackingValue { - /// Never show the backing value - Never, - /// Show the backing value only when the port does not have any active connections - Unconnected, - /// Always show the backing value - Always - } - - public enum ConnectionType { - /// Allow multiple connections - Multiple, - /// always override the current connection - Override, - } - - /// Tells which types of input to allow - public enum TypeConstraint { - /// Allow all types of input - None, - /// Allow similar and inherited types - Inherited, - /// Allow only similar types - Strict, - } - -#region Obsolete - [Obsolete("Use DynamicPorts instead")] - public IEnumerable InstancePorts { get { return DynamicPorts; } } - - [Obsolete("Use DynamicOutputs instead")] - public IEnumerable InstanceOutputs { get { return DynamicOutputs; } } - - [Obsolete("Use DynamicInputs instead")] - public IEnumerable InstanceInputs { get { return DynamicInputs; } } - - [Obsolete("Use AddDynamicInput instead")] - public NodePort AddInstanceInput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, Node.TypeConstraint typeConstraint = TypeConstraint.None, string fieldName = null) { - return AddInstanceInput(type, connectionType, typeConstraint, fieldName); - } - - [Obsolete("Use AddDynamicOutput instead")] - public NodePort AddInstanceOutput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, Node.TypeConstraint typeConstraint = TypeConstraint.None, string fieldName = null) { - return AddDynamicOutput(type, connectionType, typeConstraint, fieldName); - } - - [Obsolete("Use AddDynamicPort instead")] - private NodePort AddInstancePort(Type type, NodePort.IO direction, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, Node.TypeConstraint typeConstraint = TypeConstraint.None, string fieldName = null) { - return AddDynamicPort(type, direction, connectionType, typeConstraint, fieldName); - } - - [Obsolete("Use RemoveDynamicPort instead")] - public void RemoveInstancePort(string fieldName) { - RemoveDynamicPort(fieldName); - } - - [Obsolete("Use RemoveDynamicPort instead")] - public void RemoveInstancePort(NodePort port) { - RemoveDynamicPort(port); - } - - [Obsolete("Use ClearDynamicPorts instead")] - public void ClearInstancePorts() { - ClearDynamicPorts(); - } -#endregion - - /// Iterate over all ports on this node. - public IEnumerable Ports { get { foreach (NodePort port in ports.Values) yield return port; } } - /// Iterate over all outputs on this node. - public IEnumerable Outputs { get { foreach (NodePort port in Ports) { if (port.IsOutput) yield return port; } } } - /// Iterate over all inputs on this node. - public IEnumerable Inputs { get { foreach (NodePort port in Ports) { if (port.IsInput) yield return port; } } } - /// Iterate over all dynamic ports on this node. - public IEnumerable DynamicPorts { get { foreach (NodePort port in Ports) { if (port.IsDynamic) yield return port; } } } - /// Iterate over all dynamic outputs on this node. - public IEnumerable DynamicOutputs { get { foreach (NodePort port in Ports) { if (port.IsDynamic && port.IsOutput) yield return port; } } } - /// Iterate over all dynamic inputs on this node. - public IEnumerable DynamicInputs { get { foreach (NodePort port in Ports) { if (port.IsDynamic && port.IsInput) yield return port; } } } - /// Parent - [SerializeField] public NodeGraph graph; - /// Position on the - [SerializeField] public Vector2 position; - /// It is recommended not to modify these at hand. Instead, see and - [SerializeField] private NodePortDictionary ports = new NodePortDictionary(); - - /// Used during node instantiation to fix null/misconfigured graph during OnEnable/Init. Set it before instantiating a node. Will automatically be unset during OnEnable - public static NodeGraph graphHotfix; - - protected void OnEnable() { - if (graphHotfix != null) graph = graphHotfix; - graphHotfix = null; - UpdateStaticPorts(); - Init(); - } - - /// Update static ports to reflect class fields. This happens automatically on enable. - public void UpdateStaticPorts() { - NodeDataCache.UpdatePorts(this, ports); - } - - /// Initialize node. Called on enable. - protected virtual void Init() { } - - /// Checks all connections for invalid references, and removes them. - public void VerifyConnections() { - foreach (NodePort port in Ports) port.VerifyConnections(); - } - -#region Dynamic Ports - /// Convenience function. - /// - /// - public NodePort AddDynamicInput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, Node.TypeConstraint typeConstraint = TypeConstraint.None, string fieldName = null) { - return AddDynamicPort(type, NodePort.IO.Input, connectionType, typeConstraint, fieldName); - } - - /// Convenience function. - /// - /// - public NodePort AddDynamicOutput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, Node.TypeConstraint typeConstraint = TypeConstraint.None, string fieldName = null) { - return AddDynamicPort(type, NodePort.IO.Output, connectionType, typeConstraint, fieldName); - } - - /// Add a dynamic, serialized port to this node. - /// - /// - private NodePort AddDynamicPort(Type type, NodePort.IO direction, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, Node.TypeConstraint typeConstraint = TypeConstraint.None, string fieldName = null) { - if (fieldName == null) { - fieldName = "dynamicInput_0"; - int i = 0; - while (HasPort(fieldName)) fieldName = "dynamicInput_" + (++i); - } else if (HasPort(fieldName)) { - Debug.LogWarning("Port '" + fieldName + "' already exists in " + name, this); - return ports[fieldName]; - } - NodePort port = new NodePort(fieldName, type, direction, connectionType, typeConstraint, this); - ports.Add(fieldName, port); - return port; - } - - /// Remove an dynamic port from the node - public void RemoveDynamicPort(string fieldName) { - NodePort dynamicPort = GetPort(fieldName); - if (dynamicPort == null) throw new ArgumentException("port " + fieldName + " doesn't exist"); - RemoveDynamicPort(GetPort(fieldName)); - } - - /// Remove an dynamic port from the node - public void RemoveDynamicPort(NodePort port) { - if (port == null) throw new ArgumentNullException("port"); - else if (port.IsStatic) throw new ArgumentException("cannot remove static port"); - port.ClearConnections(); - ports.Remove(port.fieldName); - } - - /// Removes all dynamic ports from the node - [ContextMenu("Clear Dynamic Ports")] - public void ClearDynamicPorts() { - List dynamicPorts = new List(DynamicPorts); - foreach (NodePort port in dynamicPorts) { - RemoveDynamicPort(port); - } - } -#endregion - -#region Ports - /// Returns output port which matches fieldName - public NodePort GetOutputPort(string fieldName) { - NodePort port = GetPort(fieldName); - if (port == null || port.direction != NodePort.IO.Output) return null; - else return port; - } - - /// Returns input port which matches fieldName - public NodePort GetInputPort(string fieldName) { - NodePort port = GetPort(fieldName); - if (port == null || port.direction != NodePort.IO.Input) return null; - else return port; - } - - /// Returns port which matches fieldName - public NodePort GetPort(string fieldName) { - NodePort port; - if (ports.TryGetValue(fieldName, out port)) return port; - else return null; - } - - public bool HasPort(string fieldName) { - return ports.ContainsKey(fieldName); - } -#endregion - -#region Inputs/Outputs - /// Return input value for a specified port. Returns fallback value if no ports are connected - /// Field name of requested input port - /// If no ports are connected, this value will be returned - public T GetInputValue(string fieldName, T fallback = default(T)) { - NodePort port = GetPort(fieldName); - if (port != null && port.IsConnected) return port.GetInputValue(); - else return fallback; - } - - /// Return all input values for a specified port. Returns fallback value if no ports are connected - /// Field name of requested input port - /// If no ports are connected, this value will be returned - public T[] GetInputValues(string fieldName, params T[] fallback) { - NodePort port = GetPort(fieldName); - if (port != null && port.IsConnected) return port.GetInputValues(); - else return fallback; - } - - /// Returns a value based on requested port output. Should be overridden in all derived nodes with outputs. - /// The requested port. - public virtual object GetValue(NodePort port) { - Debug.LogWarning("No GetValue(NodePort port) override defined for " + GetType()); - return null; - } -#endregion - - /// Called after a connection between two s is created - /// Output Input - public virtual void OnCreateConnection(NodePort from, NodePort to) { } - - /// Called after a connection is removed from this port - /// Output or Input - public virtual void OnRemoveConnection(NodePort port) { } - - /// Disconnect everything from this node - public void ClearConnections() { - foreach (NodePort port in Ports) port.ClearConnections(); - } - -#region Attributes - /// Mark a serializable field as an input port. You can access this through - [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)] - public class InputAttribute : Attribute { - public ShowBackingValue backingValue; - public ConnectionType connectionType; - [Obsolete("Use dynamicPortList instead")] - public bool instancePortList { get { return dynamicPortList; } set { dynamicPortList = value; } } - public bool dynamicPortList; - public TypeConstraint typeConstraint; - - /// Mark a serializable field as an input port. You can access this through - /// Should we display the backing value for this port as an editor field? - /// Should we allow multiple connections? - /// Constrains which input connections can be made to this port - /// If true, will display a reorderable list of inputs instead of a single port. Will automatically add and display values for lists and arrays - public InputAttribute(ShowBackingValue backingValue = ShowBackingValue.Unconnected, ConnectionType connectionType = ConnectionType.Multiple, TypeConstraint typeConstraint = TypeConstraint.None, bool dynamicPortList = false) { - this.backingValue = backingValue; - this.connectionType = connectionType; - this.dynamicPortList = dynamicPortList; - this.typeConstraint = typeConstraint; - } - } - - /// Mark a serializable field as an output port. You can access this through - [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)] - public class OutputAttribute : Attribute { - public ShowBackingValue backingValue; - public ConnectionType connectionType; - [Obsolete("Use dynamicPortList instead")] - public bool instancePortList { get { return dynamicPortList; } set { dynamicPortList = value; } } - public bool dynamicPortList; - public TypeConstraint typeConstraint; - - /// Mark a serializable field as an output port. You can access this through - /// Should we display the backing value for this port as an editor field? - /// Should we allow multiple connections? - /// Constrains which input connections can be made from this port - /// If true, will display a reorderable list of outputs instead of a single port. Will automatically add and display values for lists and arrays - public OutputAttribute(ShowBackingValue backingValue = ShowBackingValue.Never, ConnectionType connectionType = ConnectionType.Multiple, TypeConstraint typeConstraint = TypeConstraint.None, bool dynamicPortList = false) { - this.backingValue = backingValue; - this.connectionType = connectionType; - this.dynamicPortList = dynamicPortList; - this.typeConstraint = typeConstraint; - } - - /// Mark a serializable field as an output port. You can access this through - /// Should we display the backing value for this port as an editor field? - /// Should we allow multiple connections? - /// If true, will display a reorderable list of outputs instead of a single port. Will automatically add and display values for lists and arrays - [Obsolete("Use constructor with TypeConstraint")] - public OutputAttribute(ShowBackingValue backingValue, ConnectionType connectionType, bool dynamicPortList) : this(backingValue, connectionType, TypeConstraint.None, dynamicPortList) { } - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class CreateNodeMenuAttribute : Attribute { - public string menuName; - /// Manually supply node class with a context menu path - /// Path to this node in the context menu. Null or empty hides it. - public CreateNodeMenuAttribute(string menuName) { - this.menuName = menuName; - } - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class NodeTintAttribute : Attribute { - public Color color; - /// Specify a color for this node type - /// Red [0.0f .. 1.0f] - /// Green [0.0f .. 1.0f] - /// Blue [0.0f .. 1.0f] - public NodeTintAttribute(float r, float g, float b) { - color = new Color(r, g, b); - } - - /// Specify a color for this node type - /// HEX color value - public NodeTintAttribute(string hex) { - ColorUtility.TryParseHtmlString(hex, out color); - } - - /// Specify a color for this node type - /// Red [0 .. 255] - /// Green [0 .. 255] - /// Blue [0 .. 255] - public NodeTintAttribute(byte r, byte g, byte b) { - color = new Color32(r, g, b, byte.MaxValue); - } - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class NodeWidthAttribute : Attribute { - public int width; - /// Specify a width for this node type - /// Width - public NodeWidthAttribute(int width) { - this.width = width; - } - } -#endregion - - [Serializable] private class NodePortDictionary : Dictionary, ISerializationCallbackReceiver { - [SerializeField] private List keys = new List(); - [SerializeField] private List values = new List(); - - public void OnBeforeSerialize() { - keys.Clear(); - values.Clear(); - foreach (KeyValuePair pair in this) { - keys.Add(pair.Key); - values.Add(pair.Value); - } - } - - public void OnAfterDeserialize() { - this.Clear(); - - if (keys.Count != values.Count) - throw new System.Exception("there are " + keys.Count + " keys and " + values.Count + " values after deserialization. Make sure that both key and value types are serializable."); - - for (int i = 0; i < keys.Count; i++) - this.Add(keys[i], values[i]); - } - } - } -} diff --git a/Scripts/Node.cs.meta b/Scripts/Node.cs.meta deleted file mode 100644 index a267e40..0000000 --- a/Scripts/Node.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f26231e5ab9368746948d0ea49e8178a -timeCreated: 1505419984 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/NodeDataCache.cs b/Scripts/NodeDataCache.cs deleted file mode 100644 index 02e35a1..0000000 --- a/Scripts/NodeDataCache.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEngine; - -namespace XNode { - /// Precaches reflection data in editor so we won't have to do it runtime - public static class NodeDataCache { - private static PortDataCache portDataCache; - private static bool Initialized { get { return portDataCache != null; } } - - /// Update static ports to reflect class fields. - public static void UpdatePorts(Node node, Dictionary ports) { - if (!Initialized) BuildCache(); - - Dictionary staticPorts = new Dictionary(); - Dictionary> removedPorts = new Dictionary>(); - System.Type nodeType = node.GetType(); - - List typePortCache; - if (portDataCache.TryGetValue(nodeType, out typePortCache)) { - for (int i = 0; i < typePortCache.Count; i++) { - staticPorts.Add(typePortCache[i].fieldName, portDataCache[nodeType][i]); - } - } - - // Cleanup port dict - Remove nonexisting static ports - update static port types - // Loop through current node ports - foreach (NodePort port in ports.Values.ToList()) { - // If port still exists, check it it has been changed - NodePort staticPort; - if (staticPorts.TryGetValue(port.fieldName, out staticPort)) { - // If port exists but with wrong settings, remove it. Re-add it later. - if (port.IsDynamic || port.direction != staticPort.direction || port.connectionType != staticPort.connectionType || port.typeConstraint != staticPort.typeConstraint) { - // If port is not dynamic and direction hasn't changed, add it to the list so we can try reconnecting the ports connections. - if (!port.IsDynamic && port.direction == staticPort.direction) removedPorts.Add(port.fieldName, port.GetConnections()); - port.ClearConnections(); - ports.Remove(port.fieldName); - } else port.ValueType = staticPort.ValueType; - } - // If port doesn't exist anymore, remove it - else if (port.IsStatic) { - port.ClearConnections(); - ports.Remove(port.fieldName); - } - } - // Add missing ports - foreach (NodePort staticPort in staticPorts.Values) { - if (!ports.ContainsKey(staticPort.fieldName)) { - NodePort port = new NodePort(staticPort, node); - //If we just removed the port, try re-adding the connections - List reconnectConnections; - if (removedPorts.TryGetValue(staticPort.fieldName, out reconnectConnections)) { - for (int i = 0; i < reconnectConnections.Count; i++) { - NodePort connection = reconnectConnections[i]; - if (connection == null) continue; - if (port.CanConnectTo(connection)) port.Connect(connection); - } - } - ports.Add(staticPort.fieldName, port); - } - } - } - - /// Cache node types - private static void BuildCache() { - portDataCache = new PortDataCache(); - System.Type baseType = typeof(Node); - List nodeTypes = new List(); - System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); - - // Loop through assemblies and add node types to list - foreach (Assembly assembly in assemblies) { - // Skip certain dlls to improve performance - string assemblyName = assembly.GetName().Name; - int index = assemblyName.IndexOf('.'); - if (index != -1) assemblyName = assemblyName.Substring(0, index); - switch (assemblyName) { - // The following assemblies, and sub-assemblies (eg. UnityEngine.UI) are skipped - case "UnityEditor": - case "UnityEngine": - case "System": - case "mscorlib": - continue; - default: - nodeTypes.AddRange(assembly.GetTypes().Where(t => !t.IsAbstract && baseType.IsAssignableFrom(t)).ToArray()); - break; - } - } - - for (int i = 0; i < nodeTypes.Count; i++) { - CachePorts(nodeTypes[i]); - } - } - - public static List GetNodeFields(System.Type nodeType) { - List fieldInfo = new List(nodeType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); - - // GetFields doesnt return inherited private fields, so walk through base types and pick those up - System.Type tempType = nodeType; - while ((tempType = tempType.BaseType) != typeof(XNode.Node)) { - fieldInfo.AddRange(tempType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)); - } - return fieldInfo; - } - - private static void CachePorts(System.Type nodeType) { - List fieldInfo = GetNodeFields(nodeType); - - for (int i = 0; i < fieldInfo.Count; i++) { - - //Get InputAttribute and OutputAttribute - object[] attribs = fieldInfo[i].GetCustomAttributes(true); - Node.InputAttribute inputAttrib = attribs.FirstOrDefault(x => x is Node.InputAttribute) as Node.InputAttribute; - Node.OutputAttribute outputAttrib = attribs.FirstOrDefault(x => x is Node.OutputAttribute) as Node.OutputAttribute; - - if (inputAttrib == null && outputAttrib == null) continue; - - if (inputAttrib != null && outputAttrib != null) Debug.LogError("Field " + fieldInfo[i].Name + " of type " + nodeType.FullName + " cannot be both input and output."); - else { - if (!portDataCache.ContainsKey(nodeType)) portDataCache.Add(nodeType, new List()); - portDataCache[nodeType].Add(new NodePort(fieldInfo[i])); - } - } - } - - [System.Serializable] - private class PortDataCache : Dictionary>, ISerializationCallbackReceiver { - [SerializeField] private List keys = new List(); - [SerializeField] private List> values = new List>(); - - // save the dictionary to lists - public void OnBeforeSerialize() { - keys.Clear(); - values.Clear(); - foreach (var pair in this) { - keys.Add(pair.Key); - values.Add(pair.Value); - } - } - - // load dictionary from lists - public void OnAfterDeserialize() { - this.Clear(); - - if (keys.Count != values.Count) - throw new System.Exception(string.Format("there are {0} keys and {1} values after deserialization. Make sure that both key and value types are serializable.")); - - for (int i = 0; i < keys.Count; i++) - this.Add(keys[i], values[i]); - } - } - } -} diff --git a/Scripts/NodeDataCache.cs.meta b/Scripts/NodeDataCache.cs.meta deleted file mode 100644 index 34482f2..0000000 --- a/Scripts/NodeDataCache.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 64ea6af1e195d024d8df0ead1921e517 -timeCreated: 1507566823 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/NodeGraph.cs b/Scripts/NodeGraph.cs deleted file mode 100644 index 6a0cead..0000000 --- a/Scripts/NodeGraph.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XNode { - /// Base class for all node graphs - [Serializable] - public abstract class NodeGraph : ScriptableObject { - - /// All nodes in the graph. - /// See: - [SerializeField] public List nodes = new List(); - - /// Add a node to the graph by type (convenience method - will call the System.Type version) - public T AddNode() where T : Node { - return AddNode(typeof(T)) as T; - } - - /// Add a node to the graph by type - public virtual Node AddNode(Type type) { - Node.graphHotfix = this; - Node node = ScriptableObject.CreateInstance(type) as Node; - node.graph = this; - nodes.Add(node); - return node; - } - - /// Creates a copy of the original node in the graph - public virtual Node CopyNode(Node original) { - Node.graphHotfix = this; - Node node = ScriptableObject.Instantiate(original); - node.graph = this; - node.ClearConnections(); - nodes.Add(node); - return node; - } - - /// Safely remove a node and all its connections - /// The node to remove - public virtual void RemoveNode(Node node) { - node.ClearConnections(); - nodes.Remove(node); - if (Application.isPlaying) Destroy(node); - } - - /// Remove all nodes and connections from the graph - public virtual void Clear() { - if (Application.isPlaying) { - for (int i = 0; i < nodes.Count; i++) { - Destroy(nodes[i]); - } - } - nodes.Clear(); - } - - /// Create a new deep copy of this graph - public virtual XNode.NodeGraph Copy() { - // Instantiate a new nodegraph instance - NodeGraph graph = Instantiate(this); - // Instantiate all nodes inside the graph - for (int i = 0; i < nodes.Count; i++) { - if (nodes[i] == null) continue; - Node.graphHotfix = graph; - Node node = Instantiate(nodes[i]) as Node; - node.graph = graph; - graph.nodes[i] = node; - } - - // Redirect all connections - for (int i = 0; i < graph.nodes.Count; i++) { - if (graph.nodes[i] == null) continue; - foreach (NodePort port in graph.nodes[i].Ports) { - port.Redirect(nodes, graph.nodes); - } - } - - return graph; - } - - protected virtual void OnDestroy() { - // Remove all nodes prior to graph destruction - Clear(); - } - } -} \ No newline at end of file diff --git a/Scripts/NodeGraph.cs.meta b/Scripts/NodeGraph.cs.meta deleted file mode 100644 index b2e1264..0000000 --- a/Scripts/NodeGraph.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 093f68ef2455d544fa2d14b80c811322 -timeCreated: 1505461376 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/NodePort.cs b/Scripts/NodePort.cs deleted file mode 100644 index 1000b23..0000000 --- a/Scripts/NodePort.cs +++ /dev/null @@ -1,403 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using UnityEngine; - -namespace XNode { - [Serializable] - public class NodePort { - public enum IO { Input, Output } - - public int ConnectionCount { get { return connections.Count; } } - /// Return the first non-null connection - public NodePort Connection { - get { - for (int i = 0; i < connections.Count; i++) { - if (connections[i] != null) return connections[i].Port; - } - return null; - } - } - - public IO direction { get { return _direction; } } - public Node.ConnectionType connectionType { get { return _connectionType; } } - public Node.TypeConstraint typeConstraint { get { return _typeConstraint; } } - - /// Is this port connected to anytihng? - public bool IsConnected { get { return connections.Count != 0; } } - public bool IsInput { get { return direction == IO.Input; } } - public bool IsOutput { get { return direction == IO.Output; } } - - public string fieldName { get { return _fieldName; } } - public Node node { get { return _node; } } - public bool IsDynamic { get { return _dynamic; } } - public bool IsStatic { get { return !_dynamic; } } - public Type ValueType { - get { - if (valueType == null && !string.IsNullOrEmpty(_typeQualifiedName)) valueType = Type.GetType(_typeQualifiedName, false); - return valueType; - } - set { - valueType = value; - if (value != null) _typeQualifiedName = value.AssemblyQualifiedName; - } - } - private Type valueType; - - [SerializeField] private string _fieldName; - [SerializeField] private Node _node; - [SerializeField] private string _typeQualifiedName; - [SerializeField] private List connections = new List(); - [SerializeField] private IO _direction; - [SerializeField] private Node.ConnectionType _connectionType; - [SerializeField] private Node.TypeConstraint _typeConstraint; - [SerializeField] private bool _dynamic; - - /// Construct a static targetless nodeport. Used as a template. - public NodePort(FieldInfo fieldInfo) { - _fieldName = fieldInfo.Name; - ValueType = fieldInfo.FieldType; - _dynamic = false; - var attribs = fieldInfo.GetCustomAttributes(false); - for (int i = 0; i < attribs.Length; i++) { - if (attribs[i] is Node.InputAttribute) { - _direction = IO.Input; - _connectionType = (attribs[i] as Node.InputAttribute).connectionType; - _typeConstraint = (attribs[i] as Node.InputAttribute).typeConstraint; - } else if (attribs[i] is Node.OutputAttribute) { - _direction = IO.Output; - _connectionType = (attribs[i] as Node.OutputAttribute).connectionType; - _typeConstraint = (attribs[i] as Node.OutputAttribute).typeConstraint; - } - } - } - - /// Copy a nodePort but assign it to another node. - public NodePort(NodePort nodePort, Node node) { - _fieldName = nodePort._fieldName; - ValueType = nodePort.valueType; - _direction = nodePort.direction; - _dynamic = nodePort._dynamic; - _connectionType = nodePort._connectionType; - _typeConstraint = nodePort._typeConstraint; - _node = node; - } - - /// Construct a dynamic port. Dynamic ports are not forgotten on reimport, and is ideal for runtime-created ports. - public NodePort(string fieldName, Type type, IO direction, Node.ConnectionType connectionType, Node.TypeConstraint typeConstraint, Node node) { - _fieldName = fieldName; - this.ValueType = type; - _direction = direction; - _node = node; - _dynamic = true; - _connectionType = connectionType; - _typeConstraint = typeConstraint; - } - - /// Checks all connections for invalid references, and removes them. - public void VerifyConnections() { - for (int i = connections.Count - 1; i >= 0; i--) { - if (connections[i].node != null && - !string.IsNullOrEmpty(connections[i].fieldName) && - connections[i].node.GetPort(connections[i].fieldName) != null) - continue; - connections.RemoveAt(i); - } - } - - /// Return the output value of this node through its parent nodes GetValue override method. - /// - public object GetOutputValue() { - if (direction == IO.Input) return null; - return node.GetValue(this); - } - - /// Return the output value of the first connected port. Returns null if none found or invalid. - /// - public object GetInputValue() { - NodePort connectedPort = Connection; - if (connectedPort == null) return null; - return connectedPort.GetOutputValue(); - } - - /// Return the output values of all connected ports. - /// - public object[] GetInputValues() { - object[] objs = new object[ConnectionCount]; - for (int i = 0; i < ConnectionCount; i++) { - NodePort connectedPort = connections[i].Port; - if (connectedPort == null) { // if we happen to find a null port, remove it and look again - connections.RemoveAt(i); - i--; - continue; - } - objs[i] = connectedPort.GetOutputValue(); - } - return objs; - } - - /// Return the output value of the first connected port. Returns null if none found or invalid. - /// - public T GetInputValue() { - object obj = GetInputValue(); - return obj is T ? (T) obj : default(T); - } - - /// Return the output values of all connected ports. - /// - public T[] GetInputValues() { - object[] objs = GetInputValues(); - T[] ts = new T[objs.Length]; - for (int i = 0; i < objs.Length; i++) { - if (objs[i] is T) ts[i] = (T) objs[i]; - } - return ts; - } - - /// Return true if port is connected and has a valid input. - /// - public bool TryGetInputValue(out T value) { - object obj = GetInputValue(); - if (obj is T) { - value = (T) obj; - return true; - } else { - value = default(T); - return false; - } - } - - /// Return the sum of all inputs. - /// - public float GetInputSum(float fallback) { - object[] objs = GetInputValues(); - if (objs.Length == 0) return fallback; - float result = 0; - for (int i = 0; i < objs.Length; i++) { - if (objs[i] is float) result += (float) objs[i]; - } - return result; - } - - /// Return the sum of all inputs. - /// - public int GetInputSum(int fallback) { - object[] objs = GetInputValues(); - if (objs.Length == 0) return fallback; - int result = 0; - for (int i = 0; i < objs.Length; i++) { - if (objs[i] is int) result += (int) objs[i]; - } - return result; - } - - /// Connect this to another - /// The to connect to - public void Connect(NodePort port) { - if (connections == null) connections = new List(); - if (port == null) { Debug.LogWarning("Cannot connect to null port"); return; } - if (port == this) { Debug.LogWarning("Cannot connect port to self."); return; } - if (IsConnectedTo(port)) { Debug.LogWarning("Port already connected. "); return; } - if (direction == port.direction) { Debug.LogWarning("Cannot connect two " + (direction == IO.Input ? "input" : "output") + " connections"); return; } - if (port.connectionType == Node.ConnectionType.Override && port.ConnectionCount != 0) { port.ClearConnections(); } - if (connectionType == Node.ConnectionType.Override && ConnectionCount != 0) { ClearConnections(); } - connections.Add(new PortConnection(port)); - if (port.connections == null) port.connections = new List(); - if (!port.IsConnectedTo(this)) port.connections.Add(new PortConnection(this)); - node.OnCreateConnection(this, port); - port.node.OnCreateConnection(this, port); - } - - public List GetConnections() { - List result = new List(); - 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) { - //If the connection is broken for some reason, remove it. - if (connections[i].node == null || string.IsNullOrEmpty(connections[i].fieldName)) { - connections.RemoveAt(i); - return null; - } - NodePort port = connections[i].node.GetPort(connections[i].fieldName); - if (port == null) { - connections.RemoveAt(i); - return null; - } - return port; - } - - /// Get index of the connection connecting this and specified ports - public int GetConnectionIndex(NodePort port) { - for (int i = 0; i < ConnectionCount; i++) { - if (connections[i].Port == port) return i; - } - return -1; - } - - public bool IsConnectedTo(NodePort port) { - for (int i = 0; i < connections.Count; i++) { - if (connections[i].Port == port) return true; - } - return false; - } - - /// Returns true if this port can connect to specified port - public bool CanConnectTo(NodePort port) { - // Figure out which is input and which is output - NodePort input = null, output = null; - if (IsInput) input = this; - else output = this; - if (port.IsInput) input = port; - else output = port; - // If there isn't one of each, they can't connect - if (input == null || output == null) return false; - // Check input type constraints - if (input.typeConstraint == XNode.Node.TypeConstraint.Inherited && !input.ValueType.IsAssignableFrom(output.ValueType)) return false; - if (input.typeConstraint == XNode.Node.TypeConstraint.Strict && input.ValueType != output.ValueType) return false; - // Check output type constraints - if (output.typeConstraint == XNode.Node.TypeConstraint.Inherited && !output.ValueType.IsAssignableFrom(input.ValueType)) return false; - if (output.typeConstraint == XNode.Node.TypeConstraint.Strict && output.ValueType != input.ValueType) return false; - // Success - return true; - } - - /// Disconnect this port from another port - public void Disconnect(NodePort port) { - // Remove this ports connection to the other - for (int i = connections.Count - 1; i >= 0; i--) { - if (connections[i].Port == port) { - connections.RemoveAt(i); - } - } - if (port != null) { - // Remove the other ports connection to this port - for (int i = 0; i < port.connections.Count; i++) { - if (port.connections[i].Port == this) { - port.connections.RemoveAt(i); - } - } - } - // Trigger OnRemoveConnection - node.OnRemoveConnection(this); - 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); - } - } - - /// 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; - - List portConnections = new List(); - List targetPortConnections = new List(); - - // Cache port connections - for (int i = 0; i < aConnectionCount; i++) - portConnections.Add(connections[i].Port); - - // Cache target port connections - for (int i = 0; i < bConnectionCount; i++) - targetPortConnections.Add(targetPort.connections[i].Port); - - ClearConnections(); - targetPort.ClearConnections(); - - // Add port connections to targetPort - for (int i = 0; i < portConnections.Count; i++) - targetPort.Connect(portConnections[i]); - - // Add target port connections to this one - for (int i = 0; i < targetPortConnections.Count; i++) - Connect(targetPortConnections[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) { - int index = oldNodes.IndexOf(connection.node); - if (index >= 0) connection.node = newNodes[index]; - } - } - - [Serializable] - private class PortConnection { - [SerializeField] public string fieldName; - [SerializeField] public Node node; - public NodePort Port { get { return port != null ? port : port = GetPort(); } } - - [NonSerialized] private NodePort port; - /// Extra connection path points for organization - [SerializeField] public List reroutePoints = new List(); - - public PortConnection(NodePort port) { - this.port = port; - node = port.node; - fieldName = port.fieldName; - } - - /// Returns the port that this points to - private NodePort GetPort() { - if (node == null || string.IsNullOrEmpty(fieldName)) return null; - return node.GetPort(fieldName); - } - } - } -} \ No newline at end of file diff --git a/Scripts/NodePort.cs.meta b/Scripts/NodePort.cs.meta deleted file mode 100644 index 3863705..0000000 --- a/Scripts/NodePort.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 7dd2f76ac25c6f44c9426dff3e7491a3 -timeCreated: 1505734054 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/XNode.asmdef b/Scripts/XNode.asmdef deleted file mode 100644 index eb64493..0000000 --- a/Scripts/XNode.asmdef +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "XNode", - "references": [], - "optionalUnityReferences": [], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [] -} diff --git a/Scripts/XNode.asmdef.meta b/Scripts/XNode.asmdef.meta deleted file mode 100644 index 8479d75..0000000 --- a/Scripts/XNode.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: b8e24fd1eb19b4226afebb2810e3c19b -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: