mirror of
https://github.com/Siccity/xNode.git
synced 2026-02-10 00:58:44 +08:00
Added custom context menu path in attribute
Created NodeEditorUtilities Renamed 'RightClickContextMenu' to 'ShowContextMenu' Excluded abstract classes from nodeTypes and nodeEditorTypes
This commit is contained in:
parent
d237e1529b
commit
638e784ca9
@ -2,7 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
[CustomNodeEditor(typeof(MathNode))]
|
[CustomNodeEditor(typeof(MathNode), "Math")]
|
||||||
public class AddNodeEditor : NodeEditor {
|
public class AddNodeEditor : NodeEditor {
|
||||||
|
|
||||||
public override void OnNodeGUI() {
|
public override void OnNodeGUI() {
|
||||||
|
|||||||
@ -7,7 +7,6 @@ using System.Linq;
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
/// <summary> Base class to derive custom Node editors from. Use this to create your own custom inspectors and editors for your nodes. </summary>
|
/// <summary> Base class to derive custom Node editors from. Use this to create your own custom inspectors and editors for your nodes. </summary>
|
||||||
[CustomNodeEditor(typeof(Node))]
|
|
||||||
public class NodeEditor {
|
public class NodeEditor {
|
||||||
|
|
||||||
public Node target;
|
public Node target;
|
||||||
@ -26,7 +25,7 @@ public class NodeEditor {
|
|||||||
object[] fieldAttribs = fields[i].GetCustomAttributes(false);
|
object[] fieldAttribs = fields[i].GetCustomAttributes(false);
|
||||||
|
|
||||||
HeaderAttribute headerAttrib;
|
HeaderAttribute headerAttrib;
|
||||||
if (GetAttrib(fieldAttribs, out headerAttrib)) {
|
if (NodeEditorUtilities.GetAttrib(fieldAttribs, out headerAttrib)) {
|
||||||
EditorGUILayout.LabelField(headerAttrib.header);
|
EditorGUILayout.LabelField(headerAttrib.header);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,15 +40,17 @@ public class NodeEditor {
|
|||||||
fieldValue = EditorGUILayout.EnumPopup(fieldName, (Enum)fieldValue);
|
fieldValue = EditorGUILayout.EnumPopup(fieldName, (Enum)fieldValue);
|
||||||
}
|
}
|
||||||
else if (fieldType == typeof(string)) {
|
else if (fieldType == typeof(string)) {
|
||||||
|
|
||||||
|
if (fieldName == "name") continue; //Ignore 'name'
|
||||||
TextAreaAttribute textAreaAttrib;
|
TextAreaAttribute textAreaAttrib;
|
||||||
if (GetAttrib(fieldAttribs, out textAreaAttrib)) {
|
if (NodeEditorUtilities.GetAttrib(fieldAttribs, out textAreaAttrib)) {
|
||||||
fieldValue = EditorGUILayout.TextArea(fieldValue != null ? (string)fieldValue : "");
|
fieldValue = EditorGUILayout.TextArea(fieldValue != null ? (string)fieldValue : "");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fieldValue = EditorGUILayout.TextField(fieldName, fieldValue != null ? (string)fieldValue : "");
|
fieldValue = EditorGUILayout.TextField(fieldName, fieldValue != null ? (string)fieldValue : "");
|
||||||
}
|
}
|
||||||
else if (fieldType == typeof(Rect)) {
|
else if (fieldType == typeof(Rect)) {
|
||||||
if (fieldName == "position") continue;
|
if (fieldName == "position") continue; //Ignore 'position'
|
||||||
fieldValue = EditorGUILayout.RectField(fieldName, (Rect)fieldValue);
|
fieldValue = EditorGUILayout.RectField(fieldName, (Rect)fieldValue);
|
||||||
}
|
}
|
||||||
else if (fieldType == typeof(float)) {
|
else if (fieldType == typeof(float)) {
|
||||||
@ -80,28 +81,25 @@ public class NodeEditor {
|
|||||||
fields[i].SetValue(target, fieldValue);
|
fields[i].SetValue(target, fieldValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EditorGUILayout.Space();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FieldInfo[] GetInspectorFields(Node node) {
|
private static FieldInfo[] GetInspectorFields(Node node) {
|
||||||
return node.GetType().GetFields().Where(f => f.IsPublic || f.GetCustomAttributes(typeof(SerializeField),false) != null).ToArray();
|
return node.GetType().GetFields().Where(f => f.IsPublic || f.GetCustomAttributes(typeof(SerializeField),false) != null).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool GetAttrib<T>(object[] attribs, out T attribOut) where T : Attribute {
|
|
||||||
for (int i = 0; i < attribs.Length; i++) {
|
|
||||||
if (attribs[i].GetType() == typeof(T)) {
|
|
||||||
attribOut = attribs[i] as T;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attribOut = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
public class CustomNodeEditorAttribute : Attribute {
|
public class CustomNodeEditorAttribute : Attribute {
|
||||||
public Type inspectedType;
|
public Type inspectedType { get { return _inspectedType; } }
|
||||||
public CustomNodeEditorAttribute(Type inspectedType) {
|
private Type _inspectedType;
|
||||||
this.inspectedType = inspectedType;
|
public string contextMenuName { get { return _contextMenuName; } }
|
||||||
|
private string _contextMenuName;
|
||||||
|
/// <summary> Tells a NodeEditor which Node type it is an editor for </summary>
|
||||||
|
/// <param name="inspectedType">Type that this editor can edit</param>
|
||||||
|
/// <param name="contextMenuName">Path to the node</param>
|
||||||
|
public CustomNodeEditorAttribute(Type inspectedType, string contextMenuName) {
|
||||||
|
_inspectedType = inspectedType;
|
||||||
|
_contextMenuName = contextMenuName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,7 +105,7 @@ public partial class NodeEditorWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (e.button == 1) {
|
else if (e.button == 1) {
|
||||||
if (!isPanning) RightClickContextMenu();
|
if (!isPanning) ShowContextMenu();
|
||||||
isPanning = false;
|
isPanning = false;
|
||||||
}
|
}
|
||||||
UpdateHovered();
|
UpdateHovered();
|
||||||
|
|||||||
@ -76,18 +76,26 @@ public partial class NodeEditorWindow {
|
|||||||
return GUILayout.Button(name, EditorStyles.toolbarDropDown, GUILayout.Width(width));
|
return GUILayout.Button(name, EditorStyles.toolbarDropDown, GUILayout.Width(width));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RightClickContextMenu() {
|
/// <summary> Show right-click context menu </summary>
|
||||||
|
public void ShowContextMenu() {
|
||||||
GenericMenu contextMenu = new GenericMenu();
|
GenericMenu contextMenu = new GenericMenu();
|
||||||
|
Vector2 pos = WindowToGridPosition(Event.current.mousePosition);
|
||||||
|
|
||||||
if (hoveredNode != null) {
|
if (hoveredNode != null) {
|
||||||
Node node = hoveredNode;
|
Node node = hoveredNode;
|
||||||
contextMenu.AddItem(new GUIContent("Remove"), false, () => graph.RemoveNode(node));
|
contextMenu.AddItem(new GUIContent("Remove"), false, () => graph.RemoveNode(node));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Vector2 pos = WindowToGridPosition(Event.current.mousePosition);
|
|
||||||
for (int i = 0; i < nodeTypes.Length; i++) {
|
for (int i = 0; i < nodeTypes.Length; i++) {
|
||||||
Type type = nodeTypes[i];
|
Type type = nodeTypes[i];
|
||||||
contextMenu.AddItem(new GUIContent(nodeTypes[i].ToString()), false, () => {
|
Type editorType = GetNodeEditor(type).GetType();
|
||||||
|
|
||||||
|
string name = nodeTypes[i].ToString().Replace('.', '/');
|
||||||
|
CustomNodeEditorAttribute attrib;
|
||||||
|
if (NodeEditorUtilities.GetAttrib(editorType, out attrib)) {
|
||||||
|
name = attrib.contextMenuName;
|
||||||
|
}
|
||||||
|
contextMenu.AddItem(new GUIContent(name), false, () => {
|
||||||
CreateNode(type, pos);
|
CreateNode(type, pos);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,14 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
/// <summary> Contains reflection-related info </summary>
|
/// <summary> Contains reflection-related info </summary>
|
||||||
public partial class NodeEditorWindow {
|
public partial class NodeEditorWindow {
|
||||||
|
[NonSerialized] private static Dictionary<Type, NodeEditor> customNodeEditor;
|
||||||
private static Dictionary<Type, NodeEditor> customNodeEditor;
|
|
||||||
public static Type[] nodeTypes { get { return _nodeTypes != null ? _nodeTypes : _nodeTypes = GetNodeTypes(); } }
|
public static Type[] nodeTypes { get { return _nodeTypes != null ? _nodeTypes : _nodeTypes = GetNodeTypes(); } }
|
||||||
private static Type[] _nodeTypes;
|
[NonSerialized] private static Type[] _nodeTypes = null;
|
||||||
|
|
||||||
public static NodeEditor GetNodeEditor(Type node) {
|
public static NodeEditor GetNodeEditor(Type node) {
|
||||||
if (customNodeEditor == null) CacheCustomNodeEditors();
|
if (customNodeEditor == null) CacheCustomNodeEditors();
|
||||||
@ -30,6 +29,7 @@ public partial class NodeEditorWindow {
|
|||||||
for (int i = 0; i < nodeEditors.Length; i++) {
|
for (int i = 0; i < nodeEditors.Length; i++) {
|
||||||
var attribs = nodeEditors[i].GetCustomAttributes(typeof(CustomNodeEditorAttribute), false);
|
var attribs = nodeEditors[i].GetCustomAttributes(typeof(CustomNodeEditorAttribute), false);
|
||||||
if (attribs == null || attribs.Length == 0) continue;
|
if (attribs == null || attribs.Length == 0) continue;
|
||||||
|
if (nodeEditors[i].IsAbstract) continue;
|
||||||
CustomNodeEditorAttribute attrib = attribs[0] as CustomNodeEditorAttribute;
|
CustomNodeEditorAttribute attrib = attribs[0] as CustomNodeEditorAttribute;
|
||||||
customNodeEditor.Add(attrib.inspectedType, Activator.CreateInstance(nodeEditors[i]) as NodeEditor);
|
customNodeEditor.Add(attrib.inspectedType, Activator.CreateInstance(nodeEditors[i]) as NodeEditor);
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ public partial class NodeEditorWindow {
|
|||||||
//Get all classes deriving from baseType via reflection
|
//Get all classes deriving from baseType via reflection
|
||||||
Assembly assembly = Assembly.GetAssembly(baseType);
|
Assembly assembly = Assembly.GetAssembly(baseType);
|
||||||
return assembly.GetTypes().Where(t =>
|
return assembly.GetTypes().Where(t =>
|
||||||
t != baseType &&
|
!t.IsAbstract &&
|
||||||
baseType.IsAssignableFrom(t)
|
baseType.IsAssignableFrom(t)
|
||||||
).ToArray();
|
).ToArray();
|
||||||
}
|
}
|
||||||
|
|||||||
23
Scripts/Editor/NodeEditorUtilities.cs
Normal file
23
Scripts/Editor/NodeEditorUtilities.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public static class NodeEditorUtilities {
|
||||||
|
|
||||||
|
public static bool GetAttrib<T>(Type classType, out T attribOut) where T : Attribute {
|
||||||
|
object[] attribs = classType.GetCustomAttributes(typeof(T), false);
|
||||||
|
return GetAttrib(attribs, out attribOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool GetAttrib<T>(object[] attribs, out T attribOut) where T : Attribute {
|
||||||
|
for (int i = 0; i < attribs.Length; i++) {
|
||||||
|
if (attribs[i].GetType() == typeof(T)) {
|
||||||
|
attribOut = attribs[i] as T;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attribOut = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Scripts/Editor/NodeEditorUtilities.cs.meta
Normal file
12
Scripts/Editor/NodeEditorUtilities.cs.meta
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 120960fe5b50aba418a8e8ad3c4c4bc8
|
||||||
|
timeCreated: 1506073499
|
||||||
|
licenseType: Free
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -4,6 +4,7 @@ using UnityEngine;
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using UnityEditor.Callbacks;
|
using UnityEditor.Callbacks;
|
||||||
|
using System;
|
||||||
|
|
||||||
[InitializeOnLoad]
|
[InitializeOnLoad]
|
||||||
public partial class NodeEditorWindow : EditorWindow {
|
public partial class NodeEditorWindow : EditorWindow {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user