From 6783324018c231710e5898d3c3e5d40acef7f152 Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Mon, 4 Mar 2019 18:29:43 +0100 Subject: [PATCH 01/10] Fix drawing instance twice for instanceportlists --- Scripts/Editor/NodeEditor.cs | 1 + Scripts/Editor/NodeEditorGUILayout.cs | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs index d222f9e..1fffc66 100644 --- a/Scripts/Editor/NodeEditor.cs +++ b/Scripts/Editor/NodeEditor.cs @@ -64,6 +64,7 @@ namespace XNodeEditor { // Iterate through instance ports and draw them in the order in which they are serialized foreach(XNode.NodePort instancePort in target.InstancePorts) { + if (NodeEditorGUILayout.IsInstancePortListPort(instancePort)) continue; NodeEditorGUILayout.PortField(instancePort); } diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs index 7cc1a21..b2ac5e8 100644 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ b/Scripts/Editor/NodeEditorGUILayout.cs @@ -254,6 +254,18 @@ namespace XNodeEditor { GUI.color = col; } + /// Is this port part of an InstancePortList? + public static bool IsInstancePortListPort(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 instance ports. Port names are named as "[fieldName] [index]" /// Supply a list for editable values /// Value type of added instance ports From 01d7f782e41e145cb52bf9bd7bea8f4a7cf2e927 Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Mon, 4 Mar 2019 19:04:00 +0100 Subject: [PATCH 02/10] Fixed issues relating to InstancePortList --- Scripts/Editor/NodeEditorGUILayout.cs | 35 +++++++++++++++++---------- Scripts/Node.cs | 2 ++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs index b2ac5e8..4eca18c 100644 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ b/Scripts/Editor/NodeEditorGUILayout.cs @@ -301,7 +301,6 @@ namespace XNodeEditor { private static ReorderableList CreateReorderableList(string fieldName, List instancePorts, 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; - int arraySize = hasArrayData ? arrayData.arraySize : 0; XNode.Node node = serializedObject.targetObject as XNode.Node; ReorderableList list = new ReorderableList(instancePorts, null, true, true, true, true); string label = arrayData != null ? arrayData.displayName : ObjectNames.NicifyVariableName(fieldName); @@ -317,8 +316,10 @@ namespace XNodeEditor { SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index); EditorGUI.PropertyField(rect, itemData, true); } else EditorGUI.LabelField(rect, port.fieldName); - Vector2 pos = rect.position + (port.IsOutput?new Vector2(rect.width + 6, 0) : new Vector2(-36, 0)); - NodeEditorGUILayout.PortField(pos, port); + 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) => { @@ -391,11 +392,22 @@ namespace XNodeEditor { else node.AddInstanceInput(type, connectionType, typeConstraint, newName); serializedObject.Update(); EditorUtility.SetDirty(node); - if (hasArrayData) arrayData.InsertArrayElementAtIndex(arraySize); + if (hasArrayData) { + arrayData.InsertArrayElementAtIndex(arrayData.arraySize); + } serializedObject.ApplyModifiedProperties(); }; list.onRemoveCallback = (ReorderableList rl) => { + + Predicate isMatchingInstancePort = + x => { + string[] split = x.Split(' '); + if (split != null && split.Length == 2) return split[0] == fieldName; + else return false; + }; + instancePorts = node.InstancePorts.Where(x => isMatchingInstancePort(x.fieldName)).OrderBy(x => x.fieldName).ToList(); + int index = rl.index; // Clear the removed ports connections instancePorts[index].ClearConnections(); @@ -413,23 +425,21 @@ namespace XNodeEditor { EditorUtility.SetDirty(node); if (hasArrayData) { arrayData.DeleteArrayElementAtIndex(index); - arraySize--; // Error handling. If the following happens too often, file a bug report at https://github.com/Siccity/xNode/issues - if (instancePorts.Count <= arraySize) { - while (instancePorts.Count <= arraySize) { - arrayData.DeleteArrayElementAtIndex(--arraySize); + if (instancePorts.Count <= arrayData.arraySize) { + while (instancePorts.Count <= arrayData.arraySize) { + arrayData.DeleteArrayElementAtIndex(arrayData.arraySize - 1); } UnityEngine.Debug.LogWarning("Array size exceeded instance ports size. Excess items removed."); } serializedObject.ApplyModifiedProperties(); serializedObject.Update(); } - }; if (hasArrayData) { int instancePortCount = instancePorts.Count; - while (instancePortCount < arraySize) { + while (instancePortCount < arrayData.arraySize) { // Add instance port postfixed with an index number string newName = arrayData.name + " 0"; int i = 0; @@ -439,9 +449,8 @@ namespace XNodeEditor { EditorUtility.SetDirty(node); instancePortCount++; } - while (arraySize < instancePortCount) { - arrayData.InsertArrayElementAtIndex(arraySize); - arraySize++; + while (arrayData.arraySize < instancePortCount) { + arrayData.InsertArrayElementAtIndex(arrayData.arraySize); } serializedObject.ApplyModifiedProperties(); serializedObject.Update(); diff --git a/Scripts/Node.cs b/Scripts/Node.cs index 8785280..74eb309 100644 --- a/Scripts/Node.cs +++ b/Scripts/Node.cs @@ -127,6 +127,8 @@ namespace XNode { /// Remove an instance port from the node public void RemoveInstancePort(string fieldName) { + NodePort instancePort = GetPort(fieldName); + if (instancePort == null) throw new ArgumentException("port " + fieldName + " doesn't exist"); RemoveInstancePort(GetPort(fieldName)); } From 4263e45b2482229dab42ba4613d60a8f90874f92 Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Fri, 8 Mar 2019 19:50:31 +0100 Subject: [PATCH 03/10] Rework node renaming Renaming now happens on a separate popup. --- Scripts/Editor/NodeEditor.cs | 34 ++------------- Scripts/Editor/NodeEditorAction.cs | 7 +++- Scripts/Editor/RenamePopup.cs | 66 ++++++++++++++++++++++++++++++ Scripts/Editor/RenamePopup.cs.meta | 13 ++++++ 4 files changed, 88 insertions(+), 32 deletions(-) create mode 100644 Scripts/Editor/RenamePopup.cs create mode 100644 Scripts/Editor/RenamePopup.cs.meta diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs index 1fffc66..a6d1748 100644 --- a/Scripts/Editor/NodeEditor.cs +++ b/Scripts/Editor/NodeEditor.cs @@ -13,34 +13,9 @@ namespace XNodeEditor { /// Fires every whenever a node was modified through the editor public static Action onUpdateNode; public static Dictionary portPositions; - public int renaming; public virtual void OnHeaderGUI() { - string title = target.name; - if (renaming != 0) { - if (Selection.Contains(target)) { - int controlID = EditorGUIUtility.GetControlID(FocusType.Keyboard) + 1; - if (renaming == 1) { - EditorGUIUtility.keyboardControl = controlID; - EditorGUIUtility.editingTextField = true; - renaming = 2; - } - target.name = EditorGUILayout.TextField(target.name, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30)); - if (!EditorGUIUtility.editingTextField) { - Debug.Log("Finish renaming"); - Rename(target.name); - renaming = 0; - } - } - else { - // Selection changed, so stop renaming. - GUILayout.Label(title, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30)); - Rename(target.name); - renaming = 0; - } - } else { - GUILayout.Label(title, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30)); - } + GUILayout.Label(target.name, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30)); } /// Draws standard field editors for all public fields @@ -63,7 +38,7 @@ namespace XNodeEditor { } // Iterate through instance ports and draw them in the order in which they are serialized - foreach(XNode.NodePort instancePort in target.InstancePorts) { + foreach (XNode.NodePort instancePort in target.InstancePorts) { if (NodeEditorGUILayout.IsInstancePortListPort(instancePort)) continue; NodeEditorGUILayout.PortField(instancePort); } @@ -109,10 +84,7 @@ namespace XNodeEditor { } } - public void InitiateRename() { - renaming = 1; - } - + /// Rename the node asset. This will trigger a reimport of the node. public void Rename(string newName) { if (newName == null || newName.Trim() == "") newName = UnityEditor.ObjectNames.NicifyVariableName(target.GetType().Name); target.name = newName; diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs index b4f6562..211f3cc 100644 --- a/Scripts/Editor/NodeEditorAction.cs +++ b/Scripts/Editor/NodeEditorAction.cs @@ -366,7 +366,12 @@ namespace XNodeEditor { public void RenameSelectedNode() { if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) { XNode.Node node = Selection.activeObject as XNode.Node; - NodeEditor.GetEditor(node).InitiateRename(); + Vector2 size; + if (nodeSizes.TryGetValue(node, out size)) { + RenamePopup.Show(Selection.activeObject, size.x); + } else { + RenamePopup.Show(Selection.activeObject); + } } } diff --git a/Scripts/Editor/RenamePopup.cs b/Scripts/Editor/RenamePopup.cs new file mode 100644 index 0000000..a49a948 --- /dev/null +++ b/Scripts/Editor/RenamePopup.cs @@ -0,0 +1,66 @@ +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 = UnityEditor.ObjectNames.NicifyVariableName(target.GetType().Name); + AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target)); + Close(); + } + } + // 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(); + } + } + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/RenamePopup.cs.meta b/Scripts/Editor/RenamePopup.cs.meta new file mode 100644 index 0000000..5c40a02 --- /dev/null +++ b/Scripts/Editor/RenamePopup.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 4ef3ddc25518318469bce838980c64be +timeCreated: 1552067957 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 2f4adadb72b01c522b82b765b6db43955c89a7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20K=C4=B1r=C4=B1mgeri?= Date: Wed, 20 Mar 2019 12:42:47 +0300 Subject: [PATCH 04/10] Zoom out limit feature (#122) Zoom out limit added --- Scripts/Editor/NodeEditorPreferences.cs | 3 ++- Scripts/Editor/NodeEditorWindow.cs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Scripts/Editor/NodeEditorPreferences.cs b/Scripts/Editor/NodeEditorPreferences.cs index e896f34..bd2cb55 100644 --- a/Scripts/Editor/NodeEditorPreferences.cs +++ b/Scripts/Editor/NodeEditorPreferences.cs @@ -23,6 +23,7 @@ namespace XNodeEditor { [SerializeField] private Color32 _gridBgColor = new Color(0.18f, 0.18f, 0.18f); public Color32 gridBgColor { get { return _gridBgColor; } set { _gridBgColor = value; _gridTexture = null; } } + public float zoomOutLimit = 5f; public Color32 highlightColor = new Color32(255, 255, 255, 255); public bool gridSnap = true; public bool autoSave = true; @@ -113,7 +114,7 @@ namespace XNodeEditor { 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); - + settings.zoomOutLimit = EditorGUILayout.FloatField(new GUIContent("Zoom out Limit", "Upper limit to zoom"), settings.zoomOutLimit); settings.gridLineColor = EditorGUILayout.ColorField("Color", settings.gridLineColor); settings.gridBgColor = EditorGUILayout.ColorField(" ", settings.gridBgColor); if (GUI.changed) { diff --git a/Scripts/Editor/NodeEditorWindow.cs b/Scripts/Editor/NodeEditorWindow.cs index 740fd20..08b0a56 100644 --- a/Scripts/Editor/NodeEditorWindow.cs +++ b/Scripts/Editor/NodeEditorWindow.cs @@ -61,7 +61,7 @@ namespace XNodeEditor { 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, 1f, 5f); Repaint(); } } + public float zoom { get { return _zoom; } set { _zoom = Mathf.Clamp(value, 1f, NodeEditorPreferences.GetSettings().zoomOutLimit); Repaint(); } } private float _zoom = 1; void OnFocus() { @@ -163,4 +163,4 @@ namespace XNodeEditor { } } } -} \ No newline at end of file +} From af0523db2d5311401f4033ae40ebb71477d9da65 Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Mon, 1 Apr 2019 19:16:54 +0200 Subject: [PATCH 05/10] Fixed #124 - Errors on DynamicPortList with >10 items Was using OrderBy(x => x.fieldName). The resulting order would then be 1, 10, 11, .. , 2, 3, 4, etc. Fixed by parsing the indices as ints, and ordering by that value instead --- Scripts/Editor/NodeEditorGUILayout.cs | 36 ++++++++++++++++----------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs index 4eca18c..32e527f 100644 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ b/Scripts/Editor/NodeEditorGUILayout.cs @@ -275,13 +275,17 @@ namespace XNodeEditor { 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) { XNode.Node node = serializedObject.targetObject as XNode.Node; - Predicate isMatchingInstancePort = - x => { - string[] split = x.Split(' '); - if (split != null && split.Length == 2) return split[0] == fieldName; - else return false; - }; - List instancePorts = node.InstancePorts.Where(x => isMatchingInstancePort(x.fieldName)).OrderBy(x => x.fieldName).ToList(); + var indexedPorts = node.InstancePorts.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 }; + }); + List instancePorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList(); ReorderableList list = null; Dictionary rlc; @@ -400,13 +404,17 @@ namespace XNodeEditor { list.onRemoveCallback = (ReorderableList rl) => { - Predicate isMatchingInstancePort = - x => { - string[] split = x.Split(' '); - if (split != null && split.Length == 2) return split[0] == fieldName; - else return false; - }; - instancePorts = node.InstancePorts.Where(x => isMatchingInstancePort(x.fieldName)).OrderBy(x => x.fieldName).ToList(); + var indexedPorts = node.InstancePorts.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 }; + }); + instancePorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList(); int index = rl.index; // Clear the removed ports connections From d8a4a41a8f57007dc3931a44e1ddd58070051e48 Mon Sep 17 00:00:00 2001 From: Robin Neal Date: Wed, 3 Apr 2019 19:39:21 +0100 Subject: [PATCH 06/10] Open non-persistent graphs on double-click (#126) --- Scripts/Editor/NodeEditorWindow.cs | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Scripts/Editor/NodeEditorWindow.cs b/Scripts/Editor/NodeEditorWindow.cs index 08b0a56..24bd8f5 100644 --- a/Scripts/Editor/NodeEditorWindow.cs +++ b/Scripts/Editor/NodeEditorWindow.cs @@ -70,6 +70,20 @@ namespace XNodeEditor { 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); + } + } + /// Create editor window public static NodeEditorWindow Init() { NodeEditorWindow w = CreateInstance(); @@ -147,14 +161,21 @@ namespace XNodeEditor { public static bool OnOpen(int instanceID, int line) { XNode.NodeGraph nodeGraph = EditorUtility.InstanceIDToObject(instanceID) as XNode.NodeGraph; if (nodeGraph != null) { - NodeEditorWindow w = GetWindow(typeof(NodeEditorWindow), false, "xNode", true) as NodeEditorWindow; - w.wantsMouseMove = true; - w.graph = nodeGraph; + 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(); From f6e0e3bc4d839b41ce792c161229d530117b29da Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Wed, 3 Apr 2019 21:50:29 +0200 Subject: [PATCH 07/10] Added NodeGraphEditor.GetPortColor --- Scripts/Editor/NodeEditorGUI.cs | 2 +- Scripts/Editor/NodeEditorGUILayout.cs | 6 +++--- Scripts/Editor/NodeGraphEditor.cs | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index e22a0b4..b26b9ba 100644 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -184,7 +184,7 @@ namespace XNodeEditor { Rect fromRect; if (!_portConnectionPoints.TryGetValue(output, out fromRect)) continue; - Color connectionColor = graphEditor.GetTypeColor(output.ValueType); + Color connectionColor = graphEditor.GetPortColor(output); for (int k = 0; k < output.ConnectionCount; k++) { XNode.NodePort input = output.GetConnection(k); diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs index 32e527f..e3f7c60 100644 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ b/Scripts/Editor/NodeEditorGUILayout.cs @@ -142,7 +142,7 @@ namespace XNodeEditor { Color backgroundColor = new Color32(90, 97, 105, 255); Color tint; if (NodeEditorWindow.nodeTint.TryGetValue(port.node.GetType(), out tint)) backgroundColor *= tint; - Color col = NodeEditorWindow.current.graphEditor.GetTypeColor(port.ValueType); + Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port); DrawPortHandle(rect, backgroundColor, col); // Register the handle position @@ -199,7 +199,7 @@ namespace XNodeEditor { Color backgroundColor = new Color32(90, 97, 105, 255); Color tint; if (NodeEditorWindow.nodeTint.TryGetValue(port.node.GetType(), out tint)) backgroundColor *= tint; - Color col = NodeEditorWindow.current.graphEditor.GetTypeColor(port.ValueType); + Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port); DrawPortHandle(rect, backgroundColor, col); // Register the handle position @@ -228,7 +228,7 @@ namespace XNodeEditor { Color backgroundColor = new Color32(90, 97, 105, 255); Color tint; if (NodeEditorWindow.nodeTint.TryGetValue(port.node.GetType(), out tint)) backgroundColor *= tint; - Color col = NodeEditorWindow.current.graphEditor.GetTypeColor(port.ValueType); + Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port); DrawPortHandle(rect, backgroundColor, col); // Register the handle position diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs index 81a53c8..1286f7a 100644 --- a/Scripts/Editor/NodeGraphEditor.cs +++ b/Scripts/Editor/NodeGraphEditor.cs @@ -57,6 +57,10 @@ namespace XNodeEditor { NodeEditorWindow.AddCustomContextMenuItems(menu, target); } + public virtual Color GetPortColor(XNode.NodePort port) { + return GetTypeColor(port.ValueType); + } + public virtual Color GetTypeColor(Type type) { return NodeEditorPreferences.GetTypeColor(type); } From 8adc4fd459a103dcd5cf51c28d8b168136901a51 Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Sat, 6 Apr 2019 13:27:44 +0200 Subject: [PATCH 08/10] Fixed #128, #127, #64 - Added NodeEditorBase.OnCreate, OnGraphEditor.OnOpen, and NodeEditorBase.window --- Scripts/Editor/NodeEditorAction.cs | 2 +- Scripts/Editor/NodeEditorBase.cs | 9 ++++++++- Scripts/Editor/NodeEditorGUI.cs | 6 ++---- Scripts/Editor/NodeEditorWindow.cs | 11 ++++++++++- Scripts/Editor/NodeGraphEditor.cs | 7 +++++-- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs index 211f3cc..0570777 100644 --- a/Scripts/Editor/NodeEditorAction.cs +++ b/Scripts/Editor/NodeEditorAction.cs @@ -269,7 +269,7 @@ namespace XNodeEditor { } else if (IsHoveringNode && IsHoveringTitle(hoveredNode)) { if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode, false); GenericMenu menu = new GenericMenu(); - NodeEditor.GetEditor(hoveredNode).AddContextMenuItems(menu); + 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) { diff --git a/Scripts/Editor/NodeEditorBase.cs b/Scripts/Editor/NodeEditorBase.cs index b94f290..ab463e6 100644 --- a/Scripts/Editor/NodeEditorBase.cs +++ b/Scripts/Editor/NodeEditorBase.cs @@ -14,10 +14,11 @@ namespace XNodeEditor.Internal { /// Custom editors defined with [CustomNodeEditor] private static Dictionary editorTypes; private static Dictionary editors = new Dictionary(); + public NodeEditorWindow window; public K target; public SerializedObject serializedObject; - public static T GetEditor(K target) { + public static T GetEditor(K target, NodeEditorWindow window) { if (target == null) return null; T editor; if (!editors.TryGetValue(target, out editor)) { @@ -26,9 +27,12 @@ namespace XNodeEditor.Internal { 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; } @@ -56,6 +60,9 @@ namespace XNodeEditor.Internal { } } + /// Called on creation, after references have been set + public virtual void OnCreate() { } + public interface INodeEditorAttrib { Type GetInspectedType(); } diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index b26b9ba..509f871 100644 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -18,9 +18,7 @@ namespace XNodeEditor { Event e = Event.current; Matrix4x4 m = GUI.matrix; if (graph == null) return; - graphEditor = NodeGraphEditor.GetEditor(graph); - graphEditor.position = position; - + ValidateGraphEditor(); Controls(); DrawGrid(position, zoom, panOffset); @@ -288,7 +286,7 @@ namespace XNodeEditor { _portConnectionPoints = _portConnectionPoints.Where(x => x.Key.node != node).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } - NodeEditor nodeEditor = NodeEditor.GetEditor(node); + NodeEditor nodeEditor = NodeEditor.GetEditor(node, this); NodeEditor.portPositions = new Dictionary(); diff --git a/Scripts/Editor/NodeEditorWindow.cs b/Scripts/Editor/NodeEditorWindow.cs index 24bd8f5..a575c8d 100644 --- a/Scripts/Editor/NodeEditorWindow.cs +++ b/Scripts/Editor/NodeEditorWindow.cs @@ -66,7 +66,7 @@ namespace XNodeEditor { void OnFocus() { current = this; - graphEditor = NodeGraphEditor.GetEditor(graph); + ValidateGraphEditor(); if (graphEditor != null && NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); } @@ -84,6 +84,15 @@ namespace XNodeEditor { } } + /// 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(); diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs index 1286f7a..8a9d2f0 100644 --- a/Scripts/Editor/NodeGraphEditor.cs +++ b/Scripts/Editor/NodeGraphEditor.cs @@ -8,13 +8,16 @@ 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 { - /// The position of the window in screen space. - public Rect position; + [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; } From 32fa3d7c9f12ebfb2ef6cfb334f8e0d604d49c51 Mon Sep 17 00:00:00 2001 From: Woland Date: Thu, 11 Apr 2019 12:27:56 +0200 Subject: [PATCH 09/10] gitignore: Ignore meta files for git dot files --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 68af404..1460751 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,8 @@ sysinfo.txt /Examples/ README.md.meta LICENSE.md.meta -CONTRIBUTING.md.meta \ No newline at end of file +CONTRIBUTING.md.meta + +.git.meta +.gitignore.meta +.gitattributes.meta From 7eaa15af4a70aea49267fb39da81a8c317916b51 Mon Sep 17 00:00:00 2001 From: Woland Date: Sun, 14 Apr 2019 03:21:29 +0200 Subject: [PATCH 10/10] NodeEditorReflection: Catch ReflectionTypeLoadException (#131) * NodeEditorReflection: Catch ReflectionTypeLoadException Can happen if dll can not be loaded for some reason * Removed unnecessary editor precompile tags --- Scripts/Editor/NodeEditorReflection.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Scripts/Editor/NodeEditorReflection.cs b/Scripts/Editor/NodeEditorReflection.cs index a2be28e..18b72fa 100644 --- a/Scripts/Editor/NodeEditorReflection.cs +++ b/Scripts/Editor/NodeEditorReflection.cs @@ -75,7 +75,9 @@ namespace XNodeEditor { List types = new List(); System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { - types.AddRange(assembly.GetTypes().Where(t => !t.IsAbstract && baseType.IsAssignableFrom(t)).ToArray()); + try { + types.AddRange(assembly.GetTypes().Where(t => !t.IsAbstract && baseType.IsAssignableFrom(t)).ToArray()); + } catch(ReflectionTypeLoadException) {} } return types.ToArray(); } @@ -162,4 +164,4 @@ namespace XNodeEditor { } } } -} \ No newline at end of file +}