【a】XNode
This commit is contained in:
71
Assets/10.XNode/Scripts/Editor/Drawers/NodeEnumDrawer.cs
Normal file
71
Assets/10.XNode/Scripts/Editor/Drawers/NodeEnumDrawer.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83db81f92abadca439507e25d517cabe
|
||||
timeCreated: 1541633798
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/10.XNode/Scripts/Editor/Drawers/Odin.meta
Normal file
8
Assets/10.XNode/Scripts/Editor/Drawers/Odin.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 327994a52f523b641898a39ff7500a02
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
#if UNITY_EDITOR && ODIN_INSPECTOR
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using UnityEngine;
|
||||
using XNode;
|
||||
|
||||
namespace XNodeEditor {
|
||||
internal class OdinNodeInGraphAttributeProcessor<T> : OdinAttributeProcessor<T> where T : Node {
|
||||
public override bool CanProcessSelfAttributes(InspectorProperty property) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member) {
|
||||
if (!NodeEditor.inNodeEditor)
|
||||
return false;
|
||||
|
||||
if (member.MemberType == MemberTypes.Field) {
|
||||
switch (member.Name) {
|
||||
case "graph":
|
||||
case "position":
|
||||
case "ports":
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member, List<Attribute> attributes) {
|
||||
switch (member.Name) {
|
||||
case "graph":
|
||||
case "position":
|
||||
case "ports":
|
||||
attributes.Add(new HideInInspector());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3cf2561fbfea9a041ac81efbbb5b3e0d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
#if UNITY_EDITOR && ODIN_INSPECTOR
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using Sirenix.Utilities.Editor;
|
||||
using UnityEngine;
|
||||
using XNode;
|
||||
|
||||
namespace XNodeEditor {
|
||||
public class InputAttributeDrawer : OdinAttributeDrawer<XNode.Node.InputAttribute> {
|
||||
protected override bool CanDrawAttributeProperty(InspectorProperty property) {
|
||||
Node node = property.Tree.WeakTargets[0] as Node;
|
||||
return node != null;
|
||||
}
|
||||
|
||||
protected override void DrawPropertyLayout(GUIContent label) {
|
||||
Node node = Property.Tree.WeakTargets[0] as Node;
|
||||
NodePort port = node.GetInputPort(Property.Name);
|
||||
|
||||
if (!NodeEditor.inNodeEditor) {
|
||||
if (Attribute.backingValue == XNode.Node.ShowBackingValue.Always || Attribute.backingValue == XNode.Node.ShowBackingValue.Unconnected && !port.IsConnected)
|
||||
CallNextDrawer(label);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Property.Tree.WeakTargets.Count > 1) {
|
||||
SirenixEditorGUI.WarningMessageBox("Cannot draw ports with multiple nodes selected");
|
||||
return;
|
||||
}
|
||||
|
||||
if (port != null) {
|
||||
var portPropoerty = Property.Tree.GetUnityPropertyForPath(Property.UnityPropertyPath);
|
||||
if (portPropoerty == null) {
|
||||
SirenixEditorGUI.ErrorMessageBox("Port property missing at: " + Property.UnityPropertyPath);
|
||||
return;
|
||||
} else {
|
||||
var labelWidth = Property.GetAttribute<LabelWidthAttribute>();
|
||||
if (labelWidth != null)
|
||||
GUIHelper.PushLabelWidth(labelWidth.Width);
|
||||
|
||||
NodeEditorGUILayout.PropertyField(portPropoerty, label == null ? GUIContent.none : label, true, GUILayout.MinWidth(30));
|
||||
|
||||
if (labelWidth != null)
|
||||
GUIHelper.PopLabelWidth();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fd590b2e9ea0bd49b6986a2ca9010ab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
#if UNITY_EDITOR && ODIN_INSPECTOR
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using Sirenix.Utilities.Editor;
|
||||
using UnityEngine;
|
||||
using XNode;
|
||||
|
||||
namespace XNodeEditor {
|
||||
public class OutputAttributeDrawer : OdinAttributeDrawer<XNode.Node.OutputAttribute> {
|
||||
protected override bool CanDrawAttributeProperty(InspectorProperty property) {
|
||||
Node node = property.Tree.WeakTargets[0] as Node;
|
||||
return node != null;
|
||||
}
|
||||
|
||||
protected override void DrawPropertyLayout(GUIContent label) {
|
||||
Node node = Property.Tree.WeakTargets[0] as Node;
|
||||
NodePort port = node.GetOutputPort(Property.Name);
|
||||
|
||||
if (!NodeEditor.inNodeEditor) {
|
||||
if (Attribute.backingValue == XNode.Node.ShowBackingValue.Always || Attribute.backingValue == XNode.Node.ShowBackingValue.Unconnected && !port.IsConnected)
|
||||
CallNextDrawer(label);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Property.Tree.WeakTargets.Count > 1) {
|
||||
SirenixEditorGUI.WarningMessageBox("Cannot draw ports with multiple nodes selected");
|
||||
return;
|
||||
}
|
||||
|
||||
if (port != null) {
|
||||
var portPropoerty = Property.Tree.GetUnityPropertyForPath(Property.UnityPropertyPath);
|
||||
if (portPropoerty == null) {
|
||||
SirenixEditorGUI.ErrorMessageBox("Port property missing at: " + Property.UnityPropertyPath);
|
||||
return;
|
||||
} else {
|
||||
var labelWidth = Property.GetAttribute<LabelWidthAttribute>();
|
||||
if (labelWidth != null)
|
||||
GUIHelper.PushLabelWidth(labelWidth.Width);
|
||||
|
||||
NodeEditorGUILayout.PropertyField(portPropoerty, label == null ? GUIContent.none : label, true, GUILayout.MinWidth(30));
|
||||
|
||||
if (labelWidth != null)
|
||||
GUIHelper.PopLabelWidth();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7ebd8f2b42e2384aa109551dc46af88
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user