@@ -28,6 +28,7 @@ public class BaseNodeView : NodeView
2828 public VisualElement controlsContainer ;
2929 protected VisualElement debugContainer ;
3030 protected VisualElement rightTitleContainer ;
31+ private VisualElement inputContainerElement ;
3132
3233 VisualElement settings ;
3334 NodeSettingsView settingsContainer ;
@@ -537,32 +538,55 @@ void ComputeOrderUpdatedCallback()
537538 Dictionary < string , VisualElement > hideElementIfConnected = new Dictionary < string , VisualElement > ( ) ;
538539 Dictionary < FieldInfo , List < VisualElement > > fieldControlsMap = new Dictionary < FieldInfo , List < VisualElement > > ( ) ;
539540
541+ protected void AddInputContainer ( )
542+ {
543+ inputContainerElement = new VisualElement { name = "input-container" } ;
544+ mainContainer . parent . Add ( inputContainerElement ) ;
545+ inputContainerElement . SendToBack ( ) ;
546+ inputContainerElement . pickingMode = PickingMode . Ignore ;
547+ }
548+
540549 protected virtual void DrawDefaultInspector ( bool fromInspector = false )
541550 {
551+ AddInputContainer ( ) ;
542552 var fields = nodeTarget . GetType ( ) . GetFields ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . DeclaredOnly ) ;
543553
544554 foreach ( var field in fields )
545555 {
546556 //skip if the field is not serializable
547- if ( ! field . IsPublic && field . GetCustomAttribute ( typeof ( SerializeField ) ) == null )
548- continue ;
557+ if ( ! field . IsPublic && field . GetCustomAttribute ( typeof ( SerializeField ) ) == null )
558+ {
559+ AddEmptyField ( field ) ;
560+ continue ;
561+ }
549562
550563 //skip if the field is an input/output and not marked as SerializedField
551- bool hasInputAttribute = field . GetCustomAttribute ( typeof ( InputAttribute ) ) != null ;
564+ bool hasInputAttribute = field . GetCustomAttribute ( typeof ( InputAttribute ) ) != null ;
552565 bool hasInputOrOutputAttribute = hasInputAttribute || field . GetCustomAttribute ( typeof ( OutputAttribute ) ) != null ;
553566 if ( field . GetCustomAttribute ( typeof ( SerializeField ) ) == null && hasInputOrOutputAttribute )
554- continue ;
567+ {
568+ AddEmptyField ( field ) ;
569+ continue ;
570+ }
555571
556- //skip if marked with NonSerialized or HideInInspector
557- if ( field . GetCustomAttribute ( typeof ( System . NonSerializedAttribute ) ) != null || field . GetCustomAttribute ( typeof ( HideInInspector ) ) != null )
558- continue ;
572+ //skip if marked with NonSerialized or HideInInspector
573+ if ( field . GetCustomAttribute ( typeof ( System . NonSerializedAttribute ) ) != null || field . GetCustomAttribute ( typeof ( HideInInspector ) ) != null )
574+ {
575+ AddEmptyField ( field ) ;
576+ continue ;
577+ }
559578
560579 // Hide the field if we want to display in in the inspector
561580 var showInInspector = field . GetCustomAttribute < ShowInInspector > ( ) ;
562581 if ( showInInspector != null && ! showInInspector . showInNode && ! fromInspector )
582+ {
583+ AddEmptyField ( field ) ;
563584 continue ;
585+ }
564586
565- var elem = AddControlField ( field , ObjectNames . NicifyVariableName ( field . Name ) ) ;
587+ var isSerializedInput = field . GetCustomAttribute ( typeof ( InputAttribute ) ) != null && field . GetCustomAttribute ( typeof ( SerializeField ) ) != null ;
588+
589+ var elem = AddControlField ( field , ObjectNames . NicifyVariableName ( field . Name ) , isSerializedInput ) ;
566590 if ( hasInputAttribute )
567591 {
568592 hideElementIfConnected [ field . Name ] = elem ;
@@ -575,6 +599,16 @@ protected virtual void DrawDefaultInspector(bool fromInspector = false)
575599 }
576600 }
577601
602+ private void AddEmptyField ( FieldInfo field )
603+ {
604+ if ( field . GetCustomAttribute ( typeof ( InputAttribute ) ) == null ) return ;
605+
606+ var box = new VisualElement { name = field . Name } ;
607+ box . AddToClassList ( "port-input-element" ) ;
608+ box . AddToClassList ( "empty" ) ;
609+ inputContainerElement . Add ( box ) ;
610+ }
611+
578612 void UpdateFieldVisibility ( string fieldName , object newValue )
579613 {
580614 if ( visibleConditions . TryGetValue ( fieldName , out var list ) )
@@ -605,10 +639,10 @@ void UpdateOtherFieldValue(FieldInfo info, object newValue)
605639 genericUpdate . Invoke ( this , new object [ ] { info , newValue } ) ;
606640 }
607641
608- protected VisualElement AddControlField ( string fieldName , string label = null , Action valueChangedCallback = null )
609- => AddControlField ( nodeTarget . GetType ( ) . GetField ( fieldName , BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance ) , label , valueChangedCallback ) ;
642+ protected VisualElement AddControlField ( string fieldName , string label = null , bool isSerializedInput = false , Action valueChangedCallback = null )
643+ => AddControlField ( nodeTarget . GetType ( ) . GetField ( fieldName , BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance ) , label , isSerializedInput , valueChangedCallback ) ;
610644
611- protected VisualElement AddControlField ( FieldInfo field , string label = null , Action valueChangedCallback = null )
645+ protected VisualElement AddControlField ( FieldInfo field , string label = null , bool isSerializedInput = false , Action valueChangedCallback = null )
612646 {
613647 if ( field == null )
614648 return null ;
@@ -622,14 +656,26 @@ protected VisualElement AddControlField(FieldInfo field, string label = null, Ac
622656 // When you have the node inspector, it's possible to have multiple input fields pointing to the same
623657 // property. We need to update those manually otherwise they still have the old value in the inspector.
624658 UpdateOtherFieldValue ( field , newValue ) ;
625- } , label ) ;
659+ } , isSerializedInput ? "" : label ) ;
626660
627661 if ( ! fieldControlsMap . TryGetValue ( field , out var inputFieldList ) )
628662 inputFieldList = fieldControlsMap [ field ] = new List < VisualElement > ( ) ;
629663 inputFieldList . Add ( element ) ;
630664
631- if ( element != null )
632- controlsContainer . Add ( element ) ;
665+ if ( element != null )
666+ {
667+ if ( isSerializedInput )
668+ {
669+ var box = new VisualElement { name = field . Name } ;
670+ box . AddToClassList ( "port-input-element" ) ;
671+ box . Add ( element ) ;
672+ inputContainerElement . Add ( box ) ;
673+ }
674+ else
675+ {
676+ controlsContainer . Add ( element ) ;
677+ }
678+ }
633679
634680 var visibleCondition = field . GetCustomAttribute ( typeof ( VisibleIf ) ) as VisibleIf ;
635681 if ( visibleCondition != null )
@@ -659,6 +705,9 @@ void UpdateFieldValues()
659705
660706 internal void OnPortConnected ( PortView port )
661707 {
708+ if ( port . direction == Direction . Input && inputContainerElement ? . Q ( port . fieldName ) != null )
709+ inputContainerElement . Q ( port . fieldName ) . AddToClassList ( "empty" ) ;
710+
662711 if ( hideElementIfConnected . TryGetValue ( port . fieldName , out var elem ) )
663712 elem . style . display = DisplayStyle . None ;
664713
@@ -667,6 +716,9 @@ internal void OnPortConnected(PortView port)
667716
668717 internal void OnPortDisconnected ( PortView port )
669718 {
719+ if ( port . direction == Direction . Input && inputContainerElement ? . Q ( port . fieldName ) != null )
720+ inputContainerElement . Q ( port . fieldName ) . RemoveFromClassList ( "empty" ) ;
721+
670722 if ( hideElementIfConnected . TryGetValue ( port . fieldName , out var elem ) )
671723 elem . style . display = DisplayStyle . Flex ;
672724
0 commit comments