diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs index ed44c60..7c0a1dc 100644 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ b/Scripts/Editor/NodeEditorGUILayout.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using UnityEditor; using UnityEngine; using XNode; @@ -36,15 +37,54 @@ namespace XNodeEditor { // If property is an input, display a regular property field and put a port handle on the left side if (port.direction == NodePort.IO.Input) { - // 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)); + // Get data from [Input] attribute + Node.ShowBackingValue showBacking = Node.ShowBackingValue.Unconnected; + Node.InputAttribute inputAttribute; + if (NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out inputAttribute)) showBacking = inputAttribute.backingValue; + + switch (showBacking) { + case 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 Node.ShowBackingValue.Never: + // Display a label + EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName)); + break; + case 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, 0); // If property is an output, display a text label and put a port handle on the right side } else if (port.direction == NodePort.IO.Output) { - EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.styles.outputPort, GUILayout.MinWidth(30)); + // Get data from [Output] attribute + Node.ShowBackingValue showBacking = Node.ShowBackingValue.Unconnected; + Node.OutputAttribute outputAttribute; + if (NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out outputAttribute)) showBacking = outputAttribute.backingValue; + + switch (showBacking) { + case Node.ShowBackingValue.Unconnected: + // Display a label if port is connected + if (port.IsConnected) EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.styles.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 Node.ShowBackingValue.Never: + // Display a label + EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.styles.outputPort, GUILayout.MinWidth(30)); + break; + case 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, 0); } diff --git a/Scripts/Editor/NodeEditorUtilities.cs b/Scripts/Editor/NodeEditorUtilities.cs index 9496ec1..47f0407 100644 --- a/Scripts/Editor/NodeEditorUtilities.cs +++ b/Scripts/Editor/NodeEditorUtilities.cs @@ -23,6 +23,11 @@ namespace XNodeEditor { return false; } + public static bool GetAttrib(Type classType, string fieldName, out T attribOut) where T : Attribute { + object[] attribs = classType.GetField(fieldName).GetCustomAttributes(typeof(T), false); + 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)) { diff --git a/Scripts/Node.cs b/Scripts/Node.cs index b541439..17e4d4f 100644 --- a/Scripts/Node.cs +++ b/Scripts/Node.cs @@ -160,8 +160,11 @@ namespace XNode { /// 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; + /// Mark a serializable field as an output port. You can access this through - public OutputAttribute() { } + /// Should we display the backing value for this port as an editor field? + public OutputAttribute(ShowBackingValue backingValue = ShowBackingValue.Never) { this.backingValue = backingValue; } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]