mirror of
https://github.com/Siccity/xNode.git
synced 2025-12-20 17:26:02 +08:00
Added NodeHeaderAttribute
This commit is contained in:
parent
d2b4b55872
commit
9ec2abb061
@ -1,71 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using XNode;
|
|
||||||
using XNodeEditor;
|
|
||||||
|
|
||||||
namespace XNodeEditor {
|
|
||||||
[CustomPropertyDrawer(typeof(NodeEnumAttribute))]
|
|
||||||
public class NodeEnumDrawer : PropertyDrawer {
|
|
||||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
|
||||||
EditorGUI.BeginProperty(position, label, property);
|
|
||||||
|
|
||||||
EnumPopup(position, property, label);
|
|
||||||
|
|
||||||
EditorGUI.EndProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void EnumPopup(Rect position, SerializedProperty property, GUIContent label) {
|
|
||||||
// Throw error on wrong type
|
|
||||||
if (property.propertyType != SerializedPropertyType.Enum) {
|
|
||||||
throw new ArgumentException("Parameter selected must be of type System.Enum");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add label
|
|
||||||
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
|
|
||||||
|
|
||||||
// Get current enum name
|
|
||||||
string enumName = "";
|
|
||||||
if (property.enumValueIndex >= 0 && property.enumValueIndex < property.enumDisplayNames.Length) enumName = property.enumDisplayNames[property.enumValueIndex];
|
|
||||||
|
|
||||||
#if UNITY_2017_1_OR_NEWER
|
|
||||||
// Display dropdown
|
|
||||||
if (EditorGUI.DropdownButton(position, new GUIContent(enumName), FocusType.Passive)) {
|
|
||||||
// Position is all wrong if we show the dropdown during the node draw phase.
|
|
||||||
// Instead, add it to onLateGUI to display it later.
|
|
||||||
NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Display dropdown
|
|
||||||
if (GUI.Button(position, new GUIContent(enumName), "MiniPopup")) {
|
|
||||||
// Position is all wrong if we show the dropdown during the node draw phase.
|
|
||||||
// Instead, add it to onLateGUI to display it later.
|
|
||||||
NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ShowContextMenuAtMouse(SerializedProperty property) {
|
|
||||||
// Initialize menu
|
|
||||||
GenericMenu menu = new GenericMenu();
|
|
||||||
|
|
||||||
// Add all enum display names to menu
|
|
||||||
for (int i = 0; i < property.enumDisplayNames.Length; i++) {
|
|
||||||
int index = i;
|
|
||||||
menu.AddItem(new GUIContent(property.enumDisplayNames[i]), false, () => SetEnum(property, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display at cursor position
|
|
||||||
Rect r = new Rect(Event.current.mousePosition, new Vector2(0, 0));
|
|
||||||
menu.DropDown(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetEnum(SerializedProperty property, int index) {
|
|
||||||
property.enumValueIndex = index;
|
|
||||||
property.serializedObject.ApplyModifiedProperties();
|
|
||||||
property.serializedObject.Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 83db81f92abadca439507e25d517cabe
|
|
||||||
timeCreated: 1541633798
|
|
||||||
licenseType: Free
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -25,8 +25,17 @@ namespace XNodeEditor {
|
|||||||
protected internal static bool inNodeEditor = false;
|
protected internal static bool inNodeEditor = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public virtual void OnHeaderGUI() {
|
public virtual void OnHeaderGUI()
|
||||||
GUILayout.Label(target.name, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30));
|
{
|
||||||
|
var content = new GUIContent(target.name);
|
||||||
|
var type = target.GetType();
|
||||||
|
if (type.TryGetAttributeHeader(out GUIContent attrContent))
|
||||||
|
{
|
||||||
|
if (content.text != NodeEditorUtilities.NodeDefaultName(type))
|
||||||
|
attrContent.text = content.text;
|
||||||
|
content = attrContent;
|
||||||
|
}
|
||||||
|
GUILayout.Label(content, 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>
|
||||||
|
|||||||
@ -14,6 +14,7 @@ namespace XNodeEditor {
|
|||||||
public static class NodeEditorReflection {
|
public static class NodeEditorReflection {
|
||||||
[NonSerialized] private static Dictionary<Type, Color> nodeTint;
|
[NonSerialized] private static Dictionary<Type, Color> nodeTint;
|
||||||
[NonSerialized] private static Dictionary<Type, int> nodeWidth;
|
[NonSerialized] private static Dictionary<Type, int> nodeWidth;
|
||||||
|
[NonSerialized] private static Dictionary<Type, GUIContent> nodeHeader;
|
||||||
/// <summary> All available node types </summary>
|
/// <summary> All available node types </summary>
|
||||||
public static Type[] nodeTypes { get { return _nodeTypes != null ? _nodeTypes : _nodeTypes = GetNodeTypes(); } }
|
public static Type[] nodeTypes { get { return _nodeTypes != null ? _nodeTypes : _nodeTypes = GetNodeTypes(); } }
|
||||||
|
|
||||||
@ -47,6 +48,14 @@ namespace XNodeEditor {
|
|||||||
return nodeWidth.TryGetValue(nodeType, out width);
|
return nodeWidth.TryGetValue(nodeType, out width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Get custom node headers defined with [NodeHeader] </summary>
|
||||||
|
public static bool TryGetAttributeHeader(this Type nodeType, out GUIContent content)
|
||||||
|
{
|
||||||
|
if (nodeHeader == null)
|
||||||
|
CacheAttributes<GUIContent, XNode.Node.NodeHeaderAttribute>(ref nodeHeader, x => x.content);
|
||||||
|
return nodeHeader.TryGetValue(nodeType, out content);
|
||||||
|
}
|
||||||
|
|
||||||
private static void CacheAttributes<V, A>(ref Dictionary<Type, V> dict, Func<A, V> getter) where A : Attribute {
|
private static void CacheAttributes<V, A>(ref Dictionary<Type, V> dict, Func<A, V> getter) where A : Attribute {
|
||||||
dict = new Dictionary<Type, V>();
|
dict = new Dictionary<Type, V>();
|
||||||
for (int i = 0; i < nodeTypes.Length; i++) {
|
for (int i = 0; i < nodeTypes.Length; i++) {
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5644dfc7eed151045af664a9d4fd1906
|
|
||||||
folderAsset: yes
|
|
||||||
timeCreated: 1541633926
|
|
||||||
licenseType: Free
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
/// <summary> Draw enums correctly within nodes. Without it, enums show up at the wrong positions. </summary>
|
|
||||||
/// <remarks> Enums with this attribute are not detected by EditorGui.ChangeCheck due to waiting before executing </remarks>
|
|
||||||
public class NodeEnumAttribute : PropertyAttribute { }
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 10a8338f6c985854697b35459181af0a
|
|
||||||
timeCreated: 1541633942
|
|
||||||
licenseType: Free
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace XNode {
|
namespace XNode {
|
||||||
@ -387,6 +388,16 @@ namespace XNode {
|
|||||||
this.width = width;
|
this.width = width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Specify header GUIContent for this node type </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||||
|
public class NodeHeaderAttribute : Attribute
|
||||||
|
{
|
||||||
|
public GUIContent content;
|
||||||
|
|
||||||
|
public NodeHeaderAttribute(string name) => content = new GUIContent(name);
|
||||||
|
public NodeHeaderAttribute(string name, string iconPath) => content = new GUIContent(EditorGUIUtility.IconContent(iconPath)) {text = name};
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
[Serializable] private class NodePortDictionary : Dictionary<string, NodePort>, ISerializationCallbackReceiver {
|
[Serializable] private class NodePortDictionary : Dictionary<string, NodePort>, ISerializationCallbackReceiver {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user