mirror of
https://github.com/Siccity/xNode.git
synced 2026-02-08 16:24:53 +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 UnityEngine;
|
||||
|
||||
[CustomNodeEditor(typeof(MathNode))]
|
||||
[CustomNodeEditor(typeof(MathNode), "Math")]
|
||||
public class AddNodeEditor : NodeEditor {
|
||||
|
||||
public override void OnNodeGUI() {
|
||||
|
||||
@ -7,7 +7,6 @@ using System.Linq;
|
||||
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>
|
||||
[CustomNodeEditor(typeof(Node))]
|
||||
public class NodeEditor {
|
||||
|
||||
public Node target;
|
||||
@ -26,7 +25,7 @@ public class NodeEditor {
|
||||
object[] fieldAttribs = fields[i].GetCustomAttributes(false);
|
||||
|
||||
HeaderAttribute headerAttrib;
|
||||
if (GetAttrib(fieldAttribs, out headerAttrib)) {
|
||||
if (NodeEditorUtilities.GetAttrib(fieldAttribs, out headerAttrib)) {
|
||||
EditorGUILayout.LabelField(headerAttrib.header);
|
||||
}
|
||||
|
||||
@ -41,15 +40,17 @@ public class NodeEditor {
|
||||
fieldValue = EditorGUILayout.EnumPopup(fieldName, (Enum)fieldValue);
|
||||
}
|
||||
else if (fieldType == typeof(string)) {
|
||||
|
||||
if (fieldName == "name") continue; //Ignore 'name'
|
||||
TextAreaAttribute textAreaAttrib;
|
||||
if (GetAttrib(fieldAttribs, out textAreaAttrib)) {
|
||||
if (NodeEditorUtilities.GetAttrib(fieldAttribs, out textAreaAttrib)) {
|
||||
fieldValue = EditorGUILayout.TextArea(fieldValue != null ? (string)fieldValue : "");
|
||||
}
|
||||
else
|
||||
fieldValue = EditorGUILayout.TextField(fieldName, fieldValue != null ? (string)fieldValue : "");
|
||||
}
|
||||
else if (fieldType == typeof(Rect)) {
|
||||
if (fieldName == "position") continue;
|
||||
if (fieldName == "position") continue; //Ignore 'position'
|
||||
fieldValue = EditorGUILayout.RectField(fieldName, (Rect)fieldValue);
|
||||
}
|
||||
else if (fieldType == typeof(float)) {
|
||||
@ -80,28 +81,25 @@ public class NodeEditor {
|
||||
fields[i].SetValue(target, fieldValue);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
private static FieldInfo[] GetInspectorFields(Node node) {
|
||||
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)]
|
||||
public class CustomNodeEditorAttribute : Attribute {
|
||||
public Type inspectedType;
|
||||
public CustomNodeEditorAttribute(Type inspectedType) {
|
||||
this.inspectedType = inspectedType;
|
||||
public Type inspectedType { get { return _inspectedType; } }
|
||||
private Type _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) {
|
||||
if (!isPanning) RightClickContextMenu();
|
||||
if (!isPanning) ShowContextMenu();
|
||||
isPanning = false;
|
||||
}
|
||||
UpdateHovered();
|
||||
|
||||
@ -76,18 +76,26 @@ public partial class NodeEditorWindow {
|
||||
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();
|
||||
Vector2 pos = WindowToGridPosition(Event.current.mousePosition);
|
||||
|
||||
if (hoveredNode != null) {
|
||||
Node node = hoveredNode;
|
||||
contextMenu.AddItem(new GUIContent("Remove"), false, () => graph.RemoveNode(node));
|
||||
}
|
||||
else {
|
||||
Vector2 pos = WindowToGridPosition(Event.current.mousePosition);
|
||||
for (int i = 0; i < nodeTypes.Length; 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);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary> Contains reflection-related info </summary>
|
||||
public partial class NodeEditorWindow {
|
||||
|
||||
private static Dictionary<Type, NodeEditor> customNodeEditor;
|
||||
[NonSerialized] private static Dictionary<Type, NodeEditor> customNodeEditor;
|
||||
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) {
|
||||
if (customNodeEditor == null) CacheCustomNodeEditors();
|
||||
@ -30,6 +29,7 @@ public partial class NodeEditorWindow {
|
||||
for (int i = 0; i < nodeEditors.Length; i++) {
|
||||
var attribs = nodeEditors[i].GetCustomAttributes(typeof(CustomNodeEditorAttribute), false);
|
||||
if (attribs == null || attribs.Length == 0) continue;
|
||||
if (nodeEditors[i].IsAbstract) continue;
|
||||
CustomNodeEditorAttribute attrib = attribs[0] as CustomNodeEditorAttribute;
|
||||
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
|
||||
Assembly assembly = Assembly.GetAssembly(baseType);
|
||||
return assembly.GetTypes().Where(t =>
|
||||
t != baseType &&
|
||||
!t.IsAbstract &&
|
||||
baseType.IsAssignableFrom(t)
|
||||
).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 System.IO;
|
||||
using UnityEditor.Callbacks;
|
||||
using System;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public partial class NodeEditorWindow : EditorWindow {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user