mirror of
https://github.com/Siccity/xNode.git
synced 2026-03-26 22:49:02 +08:00
Added support for user added dynamic ports (no attribute)
This commit is contained in:
parent
c39dda0701
commit
a66926e777
@ -10,18 +10,17 @@ namespace XNodeEditor.Odin
|
||||
{
|
||||
internal abstract class AsDynamicPortAtribute : System.Attribute
|
||||
{
|
||||
internal string fieldName { get; set; }
|
||||
internal int index { get; set; }
|
||||
internal Node Node { get; set; }
|
||||
public string FieldName { get; set; }
|
||||
public Node Node { get; set; }
|
||||
|
||||
internal ConnectionType connectionType { get; set; }
|
||||
internal ShowBackingValue backingValue { get; set; }
|
||||
public bool InList { get; set; }
|
||||
public ShowBackingValue BackingValue { get; set; }
|
||||
|
||||
internal NodePort Port
|
||||
public NodePort Port
|
||||
{
|
||||
get
|
||||
{
|
||||
return Node.GetPort( $"{fieldName} {index}" );
|
||||
return Node.GetPort( FieldName );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -31,19 +30,31 @@ namespace XNodeEditor.Odin
|
||||
|
||||
internal struct AsDynamicPortScope : IDisposable
|
||||
{
|
||||
public AsDynamicPortScope( NodePort port )
|
||||
public AsDynamicPortScope( NodePort port, bool inList )
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
var rect = GUILayoutUtility.GetRect( 0f, float.MaxValue, 0f, 0f, GUI.skin.label, GUILayout.ExpandWidth( true ) );
|
||||
if ( NodeEditor.isNodeEditor )
|
||||
if ( port != null && NodeEditor.isNodeEditor )
|
||||
{
|
||||
if ( port.IsInput )
|
||||
{
|
||||
NodeEditorGUILayout.PortField( new Vector2( rect.xMin - 42, rect.center.y ), port );
|
||||
Vector2 offset;
|
||||
if ( inList )
|
||||
offset = new Vector2( -42, 0 );
|
||||
else
|
||||
offset = new Vector2( -18, 0 );
|
||||
|
||||
NodeEditorGUILayout.PortField( new Vector2( rect.xMin, rect.center.y ) + offset, port );
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeEditorGUILayout.PortField( new Vector2( rect.xMax + 21, rect.center.y ), port );
|
||||
Vector2 offset;
|
||||
if ( inList )
|
||||
offset = new Vector2( 21, 0 );
|
||||
else
|
||||
offset = new Vector2( 0, 0 );
|
||||
|
||||
NodeEditorGUILayout.PortField( new Vector2( rect.xMax, rect.center.y ) + offset, port );
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +78,7 @@ namespace XNodeEditor.Odin
|
||||
if ( Attribute.Port == null )
|
||||
return;
|
||||
|
||||
using ( new AsDynamicPortScope( Attribute.Port ) )
|
||||
using ( new AsDynamicPortScope( Attribute.Port, Attribute.InList ) )
|
||||
CallNextDrawer( label );
|
||||
}
|
||||
}
|
||||
@ -83,9 +94,9 @@ namespace XNodeEditor.Odin
|
||||
return;
|
||||
|
||||
if ( Event.current.type == EventType.Layout )
|
||||
drawData = Attribute.backingValue == ShowBackingValue.Always || Attribute.backingValue == ShowBackingValue.Unconnected && !Attribute.Port.IsConnected;
|
||||
drawData = Attribute.BackingValue == ShowBackingValue.Always || Attribute.BackingValue == ShowBackingValue.Unconnected && !Attribute.Port.IsConnected;
|
||||
|
||||
using ( new AsDynamicPortScope( Attribute.Port ) )
|
||||
using ( new AsDynamicPortScope( Attribute.Port, Attribute.InList ) )
|
||||
{
|
||||
if ( drawData )
|
||||
CallNextDrawer( label );
|
||||
|
||||
@ -14,7 +14,7 @@ namespace XNodeEditor.Odin
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
var rect = GUILayoutUtility.GetRect( 0f, float.MaxValue, 0f, 0f, GUI.skin.label, GUILayout.ExpandWidth( true ) );
|
||||
if ( NodeEditor.isNodeEditor )
|
||||
if ( port != null && NodeEditor.isNodeEditor )
|
||||
{
|
||||
if ( port.IsInput )
|
||||
{
|
||||
|
||||
@ -86,12 +86,11 @@ namespace XNodeEditor.Odin
|
||||
{
|
||||
return new AsDynamicPortWithDataAtribute()
|
||||
{
|
||||
fieldName = fieldName,
|
||||
index = index,
|
||||
FieldName = string.Format( "{0} {1}", fieldName, index ),
|
||||
InList = true,
|
||||
Node = node,
|
||||
|
||||
connectionType = connectionType,
|
||||
backingValue = backingValue
|
||||
BackingValue = backingValue
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -69,12 +69,11 @@ namespace XNodeEditor
|
||||
{
|
||||
return new AsDynamicPortNoDataAtribute()
|
||||
{
|
||||
fieldName = fieldName,
|
||||
index = index,
|
||||
FieldName = string.Format( "{0} {1}", fieldName, index ),
|
||||
InList = true,
|
||||
Node = node,
|
||||
|
||||
connectionType = connectionType,
|
||||
backingValue = backingValue
|
||||
BackingValue = backingValue
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
#if UNITY_EDITOR && ODIN_INSPECTOR
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using Sirenix.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using XNode;
|
||||
using XNodeEditor.Odin;
|
||||
using static XNode.Node;
|
||||
|
||||
namespace XNodeEditor
|
||||
{
|
||||
[ResolverPriority( -4 )]
|
||||
public class FullyDynamicPortPropertyResolver<T> : BaseMemberPropertyResolver<T>
|
||||
where T : Node
|
||||
{
|
||||
private List<OdinPropertyProcessor> processors;
|
||||
|
||||
protected override InspectorPropertyInfo[] GetPropertyInfos()
|
||||
{
|
||||
if ( this.processors == null )
|
||||
{
|
||||
this.processors = OdinPropertyProcessorLocator.GetMemberProcessors( this.Property );
|
||||
}
|
||||
|
||||
var includeSpeciallySerializedMembers = this.Property.ValueEntry.SerializationBackend != SerializationBackend.Unity;
|
||||
var infos = InspectorPropertyInfoUtility.CreateMemberProperties( this.Property, typeof( T ), includeSpeciallySerializedMembers );
|
||||
|
||||
for ( int i = 0; i < this.processors.Count; i++ )
|
||||
{
|
||||
ProcessedMemberPropertyResolverExtensions.ProcessingOwnerType = typeof( T );
|
||||
this.processors[i].ProcessMemberProperties( infos );
|
||||
}
|
||||
|
||||
// Find ports that aren't managed by an attribute
|
||||
if ( this.Property.Tree.UnitySerializedObject.targetObjects.Length == 1 )
|
||||
{
|
||||
var node = Property.Tree.UnitySerializedObject.targetObject as Node;
|
||||
var nodeType = typeof( T );
|
||||
|
||||
string error;
|
||||
MemberInfo[] fieldsAndProperties;
|
||||
nodeType.FindMember()
|
||||
.IsFieldOrProperty()
|
||||
.TryGetMembers( out fieldsAndProperties, out error );
|
||||
var attributedMembers = fieldsAndProperties?.Where( x => x.GetAttribute<InputAttribute>() != null || x.GetAttribute<OutputAttribute>() != null );
|
||||
|
||||
foreach ( var port in node.DynamicPorts )
|
||||
{
|
||||
if ( attributedMembers.Any( x => port.fieldName.StartsWith( string.Format( "{0} ", x.Name ) ) ) )
|
||||
continue;
|
||||
|
||||
// value can't possibly matter here so many this "lie" is ok
|
||||
infos.AddValue( port.fieldName, () => 0, value => { },
|
||||
new AsDynamicPortNoDataAtribute()
|
||||
{
|
||||
BackingValue = ShowBackingValue.Never,
|
||||
FieldName = port.fieldName,
|
||||
InList = false,
|
||||
Node = node
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return InspectorPropertyInfoUtility.BuildPropertyGroupsAndFinalize( this.Property, typeof( T ), infos, includeSpeciallySerializedMembers );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95e515f7b1abc3440b3e1a9f324f9187
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
x
Reference in New Issue
Block a user