1
0
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:
Thor Brigsted 2017-09-22 12:19:21 +02:00
parent d237e1529b
commit 638e784ca9
8 changed files with 70 additions and 28 deletions

View File

@ -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() {

View File

@ -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;
}
}

View File

@ -105,7 +105,7 @@ public partial class NodeEditorWindow {
}
}
else if (e.button == 1) {
if (!isPanning) RightClickContextMenu();
if (!isPanning) ShowContextMenu();
isPanning = false;
}
UpdateHovered();

View File

@ -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);
});
}

View File

@ -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();
}

View 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;
}
}

View 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:

View File

@ -4,6 +4,7 @@ using UnityEngine;
using UnityEditor;
using System.IO;
using UnityEditor.Callbacks;
using System;
[InitializeOnLoad]
public partial class NodeEditorWindow : EditorWindow {