From 3666509002eb9107ec3982c777ab4b07f116cd0e Mon Sep 17 00:00:00 2001 From: Kailey Joanette Date: Sat, 25 Dec 2021 13:07:43 -0500 Subject: [PATCH 1/4] Advanced Generic menu that can be searched --- Scripts/Editor/AdvancedGenericMenu.cs | 206 +++++++++++++++++++++ Scripts/Editor/AdvancedGenericMenu.cs.meta | 11 ++ Scripts/Editor/NodeEditor.cs | 3 + Scripts/Editor/NodeEditorAction.cs | 3 + Scripts/Editor/NodeEditorGUI.cs | 3 + Scripts/Editor/NodeEditorReflection.cs | 3 + Scripts/Editor/NodeGraphEditor.cs | 3 + 7 files changed, 232 insertions(+) create mode 100644 Scripts/Editor/AdvancedGenericMenu.cs create mode 100644 Scripts/Editor/AdvancedGenericMenu.cs.meta diff --git a/Scripts/Editor/AdvancedGenericMenu.cs b/Scripts/Editor/AdvancedGenericMenu.cs new file mode 100644 index 0000000..549b028 --- /dev/null +++ b/Scripts/Editor/AdvancedGenericMenu.cs @@ -0,0 +1,206 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEditor.IMGUI.Controls; +using UnityEngine; +using static UnityEditor.GenericMenu; + +namespace XNodeEditor +{ + public class AdvancedGenericMenu : AdvancedDropdown + { + private class AdvancedGenericMenuItem : AdvancedDropdownItem + { + private MenuFunction func; + + private MenuFunction2 func2; + private object userData; + + public AdvancedGenericMenuItem( string name ) : base( name ) + { + } + + public AdvancedGenericMenuItem( string name, bool enabled, Texture2D icon, MenuFunction func ) : base( name ) + { + Set( enabled, icon, func ); + } + + public AdvancedGenericMenuItem( string name, bool enabled, Texture2D icon, MenuFunction2 func, object userData ) : base( name ) + { + Set( enabled, icon, func, userData ); + } + + public void Set( bool enabled, Texture2D icon, MenuFunction func ) + { + this.enabled = enabled; + this.icon = icon; + this.func = func; + } + + public void Set( bool enabled, Texture2D icon, MenuFunction2 func, object userData ) + { + this.enabled = enabled; + this.icon = icon; + this.func2 = func; + this.userData = userData; + } + + public void Run() + { + if ( func2 != null ) + func2( userData ); + else if ( func != null ) + func(); + } + } + + private List items = new List(); + + private AdvancedGenericMenuItem FindOrCreateItem( string name, AdvancedGenericMenuItem currentRoot = null ) + { + if ( string.IsNullOrWhiteSpace( name ) ) + return null; + + AdvancedGenericMenuItem item = null; + + string[] paths = name.Split( '/' ); + if ( currentRoot == null ) + { + item = items.FirstOrDefault( x => x != null && x.name == paths[0] ); + if ( item == null ) + items.Add( item = new AdvancedGenericMenuItem( name ) ); + } + else + { + item = currentRoot.children.OfType().FirstOrDefault( x => x.name == paths[0] ); + if ( item == null ) + currentRoot.AddChild( item = new AdvancedGenericMenuItem( name ) ); + } + + if ( paths.Length > 1 ) + return FindOrCreateItem( string.Join( "/", paths, 1, paths.Length - 1 ), item ); + + return item; + } + + private AdvancedGenericMenuItem FindParent( string name ) + { + string[] paths = name.Split( '/' ); + return FindOrCreateItem( string.Join( "/", paths, 0, paths.Length - 1 ) ); + } + + private string Name { get; set; } + + public AdvancedGenericMenu() : base( new AdvancedDropdownState() ) + { + Name = ""; + } + + public AdvancedGenericMenu( string name, AdvancedDropdownState state ) : base( state ) + { + Name = name; + } + + // + // Summary: + // Add a disabled item to the menu. + // + // Parameters: + // content: + // The GUIContent to display as a disabled menu item. + public void AddDisabledItem( GUIContent content ) + { + //var parent = FindParent( content.text ); + var item = FindOrCreateItem( content.text ); + item.Set( false, null, null ); + } + + // + // Summary: + // Add a disabled item to the menu. + // + // Parameters: + // content: + // The GUIContent to display as a disabled menu item. + // + // on: + // Specifies whether to show that the item is currently activated (i.e. a tick next + // to the item in the menu). + public void AddDisabledItem( GUIContent content, bool on ) + { + } + + public void AddItem( string name, bool on, MenuFunction func ) + { + AddItem( new GUIContent( name ), on, func ); + } + + public void AddItem( GUIContent content, bool on, MenuFunction func ) + { + //var parent = FindParent( content.text ); + var item = FindOrCreateItem( content.text ); + item.Set( true/*on*/, null, func ); + } + + public void AddItem( string name, bool on, MenuFunction2 func, object userData ) + { + AddItem( new GUIContent( name ), on, func, userData ); + } + + public void AddItem( GUIContent content, bool on, MenuFunction2 func, object userData ) + { + //var parent = FindParent( content.text ); + var item = FindOrCreateItem( content.text ); + item.Set( true/*on*/, null, func, userData ); + } + + // + // Summary: + // Add a seperator item to the menu. + // + // Parameters: + // path: + // The path to the submenu, if adding a separator to a submenu. When adding a separator + // to the top level of a menu, use an empty string as the path. + public void AddSeparator( string path = null ) + { + var parent = string.IsNullOrWhiteSpace( path ) ? null : FindParent( path ); + if ( parent == null ) + items.Add( null ); + else + parent.AddSeparator(); + } + + // + // Summary: + // Show the menu at the given screen rect. + // + // Parameters: + // position: + // The position at which to show the menu. + public void DropDown( Rect position ) + { + Show( position ); + } + + protected override AdvancedDropdownItem BuildRoot() + { + var root = new AdvancedDropdownItem( Name ); + + foreach ( var m in items ) + { + if ( m == null ) + root.AddSeparator(); + else + root.AddChild( m ); + } + + return root; + } + + protected override void ItemSelected( AdvancedDropdownItem item ) + { + if ( item is AdvancedGenericMenuItem gmItem ) + gmItem.Run(); + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/AdvancedGenericMenu.cs.meta b/Scripts/Editor/AdvancedGenericMenu.cs.meta new file mode 100644 index 0000000..2c5c440 --- /dev/null +++ b/Scripts/Editor/AdvancedGenericMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ddde711109af02e42bfe8eb006577081 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs index efe0072..0f92e61 100644 --- a/Scripts/Editor/NodeEditor.cs +++ b/Scripts/Editor/NodeEditor.cs @@ -8,6 +8,9 @@ using Sirenix.OdinInspector.Editor; using Sirenix.Utilities; using Sirenix.Utilities.Editor; #endif +#if USE_ADVANCED_GENERIC_MENU +using GenericMenu = XNodeEditor.AdvancedGenericMenu; +#endif namespace XNodeEditor { /// Base class to derive custom Node editors from. Use this to create your own custom inspectors and editors for your nodes. diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs index b7fb3b4..106590c 100644 --- a/Scripts/Editor/NodeEditorAction.cs +++ b/Scripts/Editor/NodeEditorAction.cs @@ -4,6 +4,9 @@ using System.Linq; using UnityEditor; using UnityEngine; using XNodeEditor.Internal; +#if USE_ADVANCED_GENERIC_MENU +using GenericMenu = XNodeEditor.AdvancedGenericMenu; +#endif namespace XNodeEditor { public partial class NodeEditorWindow { diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index 70c4cd1..630ad4a 100755 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -4,6 +4,9 @@ using System.Linq; using UnityEditor; using UnityEngine; using XNodeEditor.Internal; +#if USE_ADVANCED_GENERIC_MENU +using GenericMenu = XNodeEditor.AdvancedGenericMenu; +#endif namespace XNodeEditor { /// Contains GUI methods diff --git a/Scripts/Editor/NodeEditorReflection.cs b/Scripts/Editor/NodeEditorReflection.cs index 0a0a36a..2069302 100644 --- a/Scripts/Editor/NodeEditorReflection.cs +++ b/Scripts/Editor/NodeEditorReflection.cs @@ -5,6 +5,9 @@ using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; +#if USE_ADVANCED_GENERIC_MENU +using GenericMenu = XNodeEditor.AdvancedGenericMenu; +#endif namespace XNodeEditor { /// Contains reflection-related extensions built for xNode diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs index b6198ca..80b1c1f 100644 --- a/Scripts/Editor/NodeGraphEditor.cs +++ b/Scripts/Editor/NodeGraphEditor.cs @@ -2,6 +2,9 @@ using System.Linq; using UnityEditor; using UnityEngine; +#if USE_ADVANCED_GENERIC_MENU +using GenericMenu = XNodeEditor.AdvancedGenericMenu; +#endif namespace XNodeEditor { /// Base class to derive custom Node Graph editors from. Use this to override how graphs are drawn in the editor. From 840eb7818d8f3fbf457523bcb8f5214783cc2918 Mon Sep 17 00:00:00 2001 From: Kailey Joanette Date: Sun, 26 Dec 2021 15:07:00 -0500 Subject: [PATCH 2/4] Fixed menu item naming Added min/maxwidth options --- Scripts/Editor/AdvancedGenericMenu.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Scripts/Editor/AdvancedGenericMenu.cs b/Scripts/Editor/AdvancedGenericMenu.cs index 549b028..943c52f 100644 --- a/Scripts/Editor/AdvancedGenericMenu.cs +++ b/Scripts/Editor/AdvancedGenericMenu.cs @@ -8,6 +8,9 @@ namespace XNodeEditor { public class AdvancedGenericMenu : AdvancedDropdown { + public static float? DefaultMinWidth = 200f; + public static float? DefaultMaxWidth = 300f; + private class AdvancedGenericMenuItem : AdvancedDropdownItem { private MenuFunction func; @@ -67,13 +70,13 @@ namespace XNodeEditor { item = items.FirstOrDefault( x => x != null && x.name == paths[0] ); if ( item == null ) - items.Add( item = new AdvancedGenericMenuItem( name ) ); + items.Add( item = new AdvancedGenericMenuItem( paths[0] ) ); } else { item = currentRoot.children.OfType().FirstOrDefault( x => x.name == paths[0] ); if ( item == null ) - currentRoot.AddChild( item = new AdvancedGenericMenuItem( name ) ); + currentRoot.AddChild( item = new AdvancedGenericMenuItem( paths[0] ) ); } if ( paths.Length > 1 ) @@ -179,6 +182,8 @@ namespace XNodeEditor // The position at which to show the menu. public void DropDown( Rect position ) { + position.width = Mathf.Clamp( position.width, DefaultMinWidth.HasValue ? DefaultMinWidth.Value : 1f, DefaultMaxWidth.HasValue ? DefaultMaxWidth.Value : Screen.width ); + Show( position ); } From f1cbe6191d8028ebfea549d3ca7043dbb90c7451 Mon Sep 17 00:00:00 2001 From: Kailey Joanette Date: Sun, 26 Dec 2021 15:12:46 -0500 Subject: [PATCH 3/4] Limit AdvancedGenericMenu to UNITY_2019_1_OR_NEWER --- Scripts/Editor/AdvancedGenericMenu.cs | 6 ++++-- Scripts/Editor/NodeEditor.cs | 2 +- Scripts/Editor/NodeEditorAction.cs | 2 +- Scripts/Editor/NodeEditorGUI.cs | 2 +- Scripts/Editor/NodeEditorReflection.cs | 2 +- Scripts/Editor/NodeGraphEditor.cs | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Scripts/Editor/AdvancedGenericMenu.cs b/Scripts/Editor/AdvancedGenericMenu.cs index 943c52f..a22fa83 100644 --- a/Scripts/Editor/AdvancedGenericMenu.cs +++ b/Scripts/Editor/AdvancedGenericMenu.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#if UNITY_2019_1_OR_NEWER +using System.Collections.Generic; using System.Linq; using UnityEditor.IMGUI.Controls; using UnityEngine; @@ -208,4 +209,5 @@ namespace XNodeEditor gmItem.Run(); } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs index 0f92e61..8522fc0 100644 --- a/Scripts/Editor/NodeEditor.cs +++ b/Scripts/Editor/NodeEditor.cs @@ -8,7 +8,7 @@ using Sirenix.OdinInspector.Editor; using Sirenix.Utilities; using Sirenix.Utilities.Editor; #endif -#if USE_ADVANCED_GENERIC_MENU +#if UNITY_2019_1_OR_NEWER && USE_ADVANCED_GENERIC_MENU using GenericMenu = XNodeEditor.AdvancedGenericMenu; #endif diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs index 106590c..5d8d32b 100644 --- a/Scripts/Editor/NodeEditorAction.cs +++ b/Scripts/Editor/NodeEditorAction.cs @@ -4,7 +4,7 @@ using System.Linq; using UnityEditor; using UnityEngine; using XNodeEditor.Internal; -#if USE_ADVANCED_GENERIC_MENU +#if UNITY_2019_1_OR_NEWER && USE_ADVANCED_GENERIC_MENU using GenericMenu = XNodeEditor.AdvancedGenericMenu; #endif diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index 630ad4a..35b2e2a 100755 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -4,7 +4,7 @@ using System.Linq; using UnityEditor; using UnityEngine; using XNodeEditor.Internal; -#if USE_ADVANCED_GENERIC_MENU +#if UNITY_2019_1_OR_NEWER && USE_ADVANCED_GENERIC_MENU using GenericMenu = XNodeEditor.AdvancedGenericMenu; #endif diff --git a/Scripts/Editor/NodeEditorReflection.cs b/Scripts/Editor/NodeEditorReflection.cs index 2069302..d401139 100644 --- a/Scripts/Editor/NodeEditorReflection.cs +++ b/Scripts/Editor/NodeEditorReflection.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; -#if USE_ADVANCED_GENERIC_MENU +#if UNITY_2019_1_OR_NEWER && USE_ADVANCED_GENERIC_MENU using GenericMenu = XNodeEditor.AdvancedGenericMenu; #endif diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs index 80b1c1f..a304c2c 100644 --- a/Scripts/Editor/NodeGraphEditor.cs +++ b/Scripts/Editor/NodeGraphEditor.cs @@ -2,7 +2,7 @@ using System.Linq; using UnityEditor; using UnityEngine; -#if USE_ADVANCED_GENERIC_MENU +#if UNITY_2019_1_OR_NEWER && USE_ADVANCED_GENERIC_MENU using GenericMenu = XNodeEditor.AdvancedGenericMenu; #endif From 46076527f850c10b7074558787299e015e7abc6b Mon Sep 17 00:00:00 2001 From: RomanZanevski <92728725+RomanZanevski@users.noreply.github.com> Date: Mon, 25 Apr 2022 16:24:08 +0200 Subject: [PATCH 4/4] Fix OnRemoveConnection from calling side If we use the original: if (port != null && port.IsConnectedTo(this)) port.node.OnRemoveConnection(port); we going to have always wrong condition, about "IsConnectedTo(this)" and port.node.OnRemoveConnection(port) just won't be called, cause we already have disconnected ports. So we need to do it exactly at the moment of disconnection. --- Scripts/NodePort.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Scripts/NodePort.cs b/Scripts/NodePort.cs index 9fa465e..6bcc638 100644 --- a/Scripts/NodePort.cs +++ b/Scripts/NodePort.cs @@ -296,12 +296,13 @@ namespace XNode { for (int i = 0; i < port.connections.Count; i++) { if (port.connections[i].Port == this) { port.connections.RemoveAt(i); + // Trigger OnRemoveConnection from this side port + port.node.OnRemoveConnection(port); } } } // Trigger OnRemoveConnection node.OnRemoveConnection(this); - if (port != null && port.IsConnectedTo(this)) port.node.OnRemoveConnection(port); } /// Disconnect this port from another port @@ -413,4 +414,4 @@ namespace XNode { } } } -} \ No newline at end of file +}