1
0
mirror of https://github.com/Siccity/xNode.git synced 2025-12-20 17:26:02 +08:00

Rewrite that caches the ordered property attributes so the gui layout drawer can draw them in the correct order.

Rewrote how the property attributes are drawn, more compact less messy code.
This commit is contained in:
Simon Rodriguez 2019-11-12 22:37:29 +01:00
parent 984fe730c0
commit 72ff273b5c
2 changed files with 56 additions and 36 deletions

View File

@ -41,14 +41,7 @@ namespace XNodeEditor {
else {
Rect rect = new Rect();
float spacePadding = 0;
SpaceAttribute spaceAttribute;
if (NodeEditorUtilities.GetCachedAttrib(port.node.GetType(), property.name, out spaceAttribute)) spacePadding = spaceAttribute.height;
//GUI Values are from https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/ScriptAttributeGUI/Implementations/DecoratorDrawers.cs
float headerPadding = 0;
HeaderAttribute headerAttribute;
if (NodeEditorUtilities.GetCachedAttrib(port.node.GetType(), property.name, out headerAttribute)) headerPadding = EditorGUIUtility.singleLineHeight * 1.5f;
List<PropertyAttribute> propertyAttributes = NodeEditorUtilities.GetCachedPropertyAttribs(port.node.GetType(), property.name);
// If property is an input, display a regular property field and put a port handle on the left side
if (port.direction == XNode.NodePort.IO.Input) {
@ -61,21 +54,24 @@ namespace XNodeEditor {
showBacking = inputAttribute.backingValue;
}
//Call GUILayout.Space if Space attribute is set and we are NOT drawing a PropertyField
bool useLayoutSpace = dynamicPortList ||
bool usePropertyAttributes = dynamicPortList ||
showBacking == XNode.Node.ShowBackingValue.Never ||
(showBacking == XNode.Node.ShowBackingValue.Unconnected && port.IsConnected);
if (spacePadding > 0 && useLayoutSpace) {
GUILayout.Space(spacePadding);
spacePadding = 0;
}
if (headerPadding > 0 && useLayoutSpace)
{
Rect position = GUILayoutUtility.GetRect(0, EditorGUIUtility.singleLineHeight * 1.5f);
position.yMin += (EditorGUIUtility.singleLineHeight * 0.5f) + EditorGUIUtility.standardVerticalSpacing;
position = EditorGUI.IndentedRect(position);
GUI.Label(position, headerAttribute.header, EditorStyles.boldLabel);
headerPadding = 0;
float spacePadding = 0;
foreach (var attr in propertyAttributes) {
if (attr is SpaceAttribute) {
if (usePropertyAttributes) GUILayout.Space((attr as SpaceAttribute).height);
else spacePadding += (attr as SpaceAttribute).height;
} else if (attr is HeaderAttribute) {
if (usePropertyAttributes) {
//GUI Values are from https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/ScriptAttributeGUI/Implementations/DecoratorDrawers.cs
Rect position = GUILayoutUtility.GetRect(0, (EditorGUIUtility.singleLineHeight * 1.5f) - EditorGUIUtility.standardVerticalSpacing); //Layout adds standardVerticalSpacing after rect so we subtract it.
position.yMin += EditorGUIUtility.singleLineHeight * 0.5f;
position = EditorGUI.IndentedRect(position);
GUI.Label(position, (attr as HeaderAttribute).header, EditorStyles.boldLabel);
} else spacePadding += EditorGUIUtility.singleLineHeight * 1.5f;
}
}
if (dynamicPortList) {
@ -102,7 +98,7 @@ namespace XNodeEditor {
}
rect = GUILayoutUtility.GetLastRect();
rect.position = rect.position - new Vector2(16, -(spacePadding + headerPadding));
rect.position = rect.position - new Vector2(16, -spacePadding);
// If property is an output, display a text label and put a port handle on the right side
} else if (port.direction == XNode.NodePort.IO.Output) {
// Get data from [Output] attribute
@ -114,21 +110,24 @@ namespace XNodeEditor {
showBacking = outputAttribute.backingValue;
}
//Call GUILayout.Space if Space attribute is set and we are NOT drawing a PropertyField
bool useLayoutSpace = dynamicPortList ||
bool usePropertyAttributes = dynamicPortList ||
showBacking == XNode.Node.ShowBackingValue.Never ||
(showBacking == XNode.Node.ShowBackingValue.Unconnected && port.IsConnected);
if (spacePadding > 0 && useLayoutSpace) {
GUILayout.Space(spacePadding);
spacePadding = 0;
}
if (headerPadding > 0 && useLayoutSpace)
{
Rect position = GUILayoutUtility.GetRect(0, EditorGUIUtility.singleLineHeight * 1.5f);
position.yMin += (EditorGUIUtility.singleLineHeight * 0.5f) + EditorGUIUtility.standardVerticalSpacing;
position = EditorGUI.IndentedRect(position);
GUI.Label(position, headerAttribute.header, EditorStyles.boldLabel);
headerPadding = 0;
float spacePadding = 0;
foreach (var attr in propertyAttributes) {
if (attr is SpaceAttribute) {
if (usePropertyAttributes) GUILayout.Space((attr as SpaceAttribute).height);
else spacePadding += (attr as SpaceAttribute).height;
} else if (attr is HeaderAttribute) {
if (usePropertyAttributes) {
//GUI Values are from https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/ScriptAttributeGUI/Implementations/DecoratorDrawers.cs
Rect position = GUILayoutUtility.GetRect(0, (EditorGUIUtility.singleLineHeight * 1.5f) - EditorGUIUtility.standardVerticalSpacing); //Layout adds standardVerticalSpacing after rect so we subtract it.
position.yMin += EditorGUIUtility.singleLineHeight * 0.5f;
position = EditorGUI.IndentedRect(position);
GUI.Label(position, (attr as HeaderAttribute).header, EditorStyles.boldLabel);
} else spacePadding += EditorGUIUtility.singleLineHeight * 1.5f;
}
}
if (dynamicPortList) {
@ -155,7 +154,7 @@ namespace XNodeEditor {
}
rect = GUILayoutUtility.GetLastRect();
rect.position = rect.position + new Vector2(rect.width, spacePadding + headerPadding);
rect.position = rect.position + new Vector2(rect.width, spacePadding);
}
rect.size = new Vector2(16, 16);

View File

@ -18,6 +18,9 @@ namespace XNodeEditor {
/// Saves Attribute from Type+Field for faster lookup. Resets on recompiles.
private static Dictionary<Type, Dictionary<string, Dictionary<Type, Attribute>>> typeAttributes = new Dictionary<Type, Dictionary<string, Dictionary<Type, Attribute>>>();
/// Saves ordered PropertyAttribute from Type+Field for faster lookup. Resets on recompiles.
private static Dictionary<Type, Dictionary<string, List<PropertyAttribute>>> typeOrderedPropertyAttributes = new Dictionary<Type, Dictionary<string, List<PropertyAttribute>>>();
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);
@ -84,6 +87,24 @@ namespace XNodeEditor {
return true;
}
public static List<PropertyAttribute> GetCachedPropertyAttribs(Type classType, string fieldName) {
Dictionary<string, List<PropertyAttribute>> typeFields;
if (!typeOrderedPropertyAttributes.TryGetValue(classType, out typeFields)) {
typeFields = new Dictionary<string, List<PropertyAttribute>>();
typeOrderedPropertyAttributes.Add(classType, typeFields);
}
List<PropertyAttribute> typeAttributes;
if (!typeFields.TryGetValue(fieldName, out typeAttributes)) {
FieldInfo field = classType.GetFieldInfo(fieldName);
object[] attribs = field.GetCustomAttributes(typeof(PropertyAttribute), true);
typeAttributes = attribs.Cast<PropertyAttribute>().Reverse().ToList(); //Unity draws them in reverse
typeFields.Add(fieldName, typeAttributes);
}
return typeAttributes;
}
public static bool IsMac() {
#if UNITY_2017_1_OR_NEWER
return SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX;