mirror of
https://github.com/Siccity/xNode.git
synced 2026-03-26 22:49:02 +08:00
Added support for ports
This commit is contained in:
parent
fa18c8d343
commit
8339af2b26
8
Scripts/Editor/Drawers/Odin.meta
Normal file
8
Scripts/Editor/Drawers/Odin.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 327994a52f523b641898a39ff7500a02
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
#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<T> : OdinAttributeProcessor<T> 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<Attribute> attributes) {
|
||||||
|
switch (member.Name) {
|
||||||
|
case "graph":
|
||||||
|
case "position":
|
||||||
|
case "ports":
|
||||||
|
attributes.Add(new HideInInspector());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3cf2561fbfea9a041ac81efbbb5b3e0d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
49
Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs
Normal file
49
Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#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<XNode.Node.InputAttribute> {
|
||||||
|
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<LabelWidthAttribute>();
|
||||||
|
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
|
||||||
11
Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs.meta
Normal file
11
Scripts/Editor/Drawers/Odin/InputAttributeDrawer.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2fd590b2e9ea0bd49b6986a2ca9010ab
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
49
Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs
Normal file
49
Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#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<XNode.Node.OutputAttribute> {
|
||||||
|
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<LabelWidthAttribute>();
|
||||||
|
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
|
||||||
11
Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs.meta
Normal file
11
Scripts/Editor/Drawers/Odin/OutputAttributeDrawer.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e7ebd8f2b42e2384aa109551dc46af88
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -20,12 +20,18 @@ namespace XNodeEditor {
|
|||||||
public static Action<XNode.Node> onUpdateNode;
|
public static Action<XNode.Node> onUpdateNode;
|
||||||
public readonly static Dictionary<XNode.NodePort, Vector2> portPositions = new Dictionary<XNode.NodePort, Vector2>();
|
public readonly static Dictionary<XNode.NodePort, Vector2> portPositions = new Dictionary<XNode.NodePort, Vector2>();
|
||||||
|
|
||||||
|
#if ODIN_INSPECTOR
|
||||||
|
internal static bool inNodeEditor = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
public virtual void OnHeaderGUI() {
|
public virtual void OnHeaderGUI() {
|
||||||
GUILayout.Label(target.name, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30));
|
GUILayout.Label(target.name, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Draws standard field editors for all public fields </summary>
|
/// <summary> Draws standard field editors for all public fields </summary>
|
||||||
public virtual void OnBodyGUI() {
|
public virtual void OnBodyGUI() {
|
||||||
|
inNodeEditor = true;
|
||||||
|
|
||||||
// Unity specifically requires this to save/update any serial object.
|
// Unity specifically requires this to save/update any serial object.
|
||||||
// serializedObject.Update(); must go at the start of an inspector gui, and
|
// serializedObject.Update(); must go at the start of an inspector gui, and
|
||||||
// serializedObject.ApplyModifiedProperties(); goes at the end.
|
// serializedObject.ApplyModifiedProperties(); goes at the end.
|
||||||
@ -33,9 +39,12 @@ namespace XNodeEditor {
|
|||||||
string[] excludes = { "m_Script", "graph", "position", "ports" };
|
string[] excludes = { "m_Script", "graph", "position", "ports" };
|
||||||
|
|
||||||
#if ODIN_INSPECTOR
|
#if ODIN_INSPECTOR
|
||||||
// let xNode handle these
|
InspectorUtilities.BeginDrawPropertyTree(objectTree, true);
|
||||||
string[] drawnbyXNode = target.Ports.Select(x => x.fieldName).ToArray();
|
GUIHelper.PushLabelWidth(84);
|
||||||
#endif
|
objectTree.Draw(true);
|
||||||
|
InspectorUtilities.EndDrawPropertyTree(objectTree);
|
||||||
|
GUIHelper.PopLabelWidth();
|
||||||
|
#else
|
||||||
|
|
||||||
// Iterate through serialized properties and draw them like the Inspector (But with ports)
|
// Iterate through serialized properties and draw them like the Inspector (But with ports)
|
||||||
SerializedProperty iterator = serializedObject.GetIterator();
|
SerializedProperty iterator = serializedObject.GetIterator();
|
||||||
@ -43,22 +52,9 @@ namespace XNodeEditor {
|
|||||||
EditorGUIUtility.labelWidth = 84;
|
EditorGUIUtility.labelWidth = 84;
|
||||||
while (iterator.NextVisible(enterChildren)) {
|
while (iterator.NextVisible(enterChildren)) {
|
||||||
enterChildren = false;
|
enterChildren = false;
|
||||||
#if ODIN_INSPECTOR
|
|
||||||
if (drawnbyXNode.Contains(iterator.name)) NodeEditorGUILayout.PropertyField(iterator, true);
|
|
||||||
#else
|
|
||||||
if (excludes.Contains(iterator.name)) continue;
|
if (excludes.Contains(iterator.name)) continue;
|
||||||
NodeEditorGUILayout.PropertyField(iterator, true);
|
NodeEditorGUILayout.PropertyField(iterator, true);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ODIN_INSPECTOR
|
|
||||||
InspectorUtilities.BeginDrawPropertyTree(objectTree, true);
|
|
||||||
objectTree.EnumerateTree(includeChildren: false).ForEach(p => {
|
|
||||||
if (!drawnbyXNode.Contains(p.Name) && !excludes.Contains(p.Name)) {
|
|
||||||
p.Draw();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
InspectorUtilities.EndDrawPropertyTree(objectTree);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Iterate through dynamic ports and draw them in the order in which they are serialized
|
// Iterate through dynamic ports and draw them in the order in which they are serialized
|
||||||
@ -78,6 +74,8 @@ namespace XNodeEditor {
|
|||||||
#else
|
#else
|
||||||
window.Repaint();
|
window.Repaint();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
inNodeEditor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int GetWidth() {
|
public virtual int GetWidth() {
|
||||||
@ -144,4 +142,4 @@ namespace XNodeEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,7 +26,10 @@ namespace XNodeEditor.Internal {
|
|||||||
get {
|
get {
|
||||||
if (this._objectTree == null) {
|
if (this._objectTree == null) {
|
||||||
try {
|
try {
|
||||||
|
bool wasInEditor = NodeEditor.inNodeEditor;
|
||||||
|
NodeEditor.inNodeEditor = true;
|
||||||
this._objectTree = PropertyTree.Create(this.serializedObject);
|
this._objectTree = PropertyTree.Create(this.serializedObject);
|
||||||
|
NodeEditor.inNodeEditor = wasInEditor;
|
||||||
} catch (ArgumentException ex) {
|
} catch (ArgumentException ex) {
|
||||||
Debug.Log(ex);
|
Debug.Log(ex);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user