using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
/// Base class to derive custom Node editors from. Use this to create your own custom inspectors and editors for your nodes.
public class NodeEditor {
/// Fires every whenever a node was modified through the editor
public static Action onUpdateNode;
public Node target;
/// Draws the node GUI.
/// Port handle positions need to be returned to the NodeEditorWindow
public void OnNodeGUI(out Dictionary portPositions) {
OnHeaderGUI();
OnBodyGUI(out portPositions);
}
protected virtual void OnHeaderGUI() {
GUI.color = Color.white;
string title = NodeEditorUtilities.PrettifyCamelCase(target.name);
GUILayout.Label(title, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30));
}
/// Draws standard field editors for all public fields
protected virtual void OnBodyGUI(out Dictionary portPositions) {
portPositions = new Dictionary();
EditorGUI.BeginChangeCheck();
FieldInfo[] fields = GetInspectorFields(target);
for (int i = 0; i < fields.Length; i++) {
if (fields[i].Name == "graph" || fields[i].Name == "position") continue;
NodeEditorGUILayout.PropertyField(target, fields[i], portPositions);
}
//If user changed a value, notify other scripts through onUpdateNode
if (EditorGUI.EndChangeCheck()) {
if (onUpdateNode != null) onUpdateNode(target);
}
}
private static FieldInfo[] GetInspectorFields(Node node) {
return node.GetType().GetFields().Where(f => f.IsPublic || f.GetCustomAttributes(typeof(SerializeField), false) != null).ToArray();
}
public virtual int GetWidth() {
return 200;
}
}
[AttributeUsage(AttributeTargets.Class)]
public class CustomNodeEditorAttribute : Attribute {
public Type inspectedType { get { return _inspectedType; } }
private Type _inspectedType;
public string contextMenuName { get { return _contextMenuName; } }
private string _contextMenuName;
/// Tells a NodeEditor which Node type it is an editor for
/// Type that this editor can edit
/// Path to the node
public CustomNodeEditorAttribute(Type inspectedType, string contextMenuName) {
_inspectedType = inspectedType;
_contextMenuName = contextMenuName;
}
}