From 3666509002eb9107ec3982c777ab4b07f116cd0e Mon Sep 17 00:00:00 2001 From: Kailey Joanette Date: Sat, 25 Dec 2021 13:07:43 -0500 Subject: [PATCH 1/3] 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/3] 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/3] 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