public static void DrawVariable(Type fieldType, string fieldName, object fieldValue, string tooltip, VariableAttributes variableAttributes, IEnumerable <Attribute> customAttributes, bool allowExtensions, Type contextType, Action <object> changeCallback) { if ((variableAttributes & VariableAttributes.Static) != 0) { var style = new GUIStyle { normal = { background = SidekickEditorGUI.StaticBackground } }; EditorGUILayout.BeginVertical(style); } GUIStyle expandButtonStyle = new GUIStyle(GUI.skin.button); RectOffset padding = expandButtonStyle.padding; padding.left = 0; padding.right = 1; expandButtonStyle.padding = padding; fieldValue ??= TypeUtility.GetDefaultValue(fieldType); string displayName = SidekickUtility.NicifyIdentifier(fieldName); GUIContent label = new GUIContent(displayName, tooltip); bool isArray = fieldType.IsArray; bool isGenericList = TypeUtility.IsGenericList(fieldType); bool isGenericDictionary = TypeUtility.IsGenericDictionary(fieldType); if (isGenericDictionary) { EditorGUILayout.BeginHorizontal(); string expandedID = fieldType.FullName + fieldName; bool expanded = DrawHeader(expandedID, label, (variableAttributes & VariableAttributes.Static) != 0); int count = 0; if (fieldValue != null) { EditorGUI.BeginDisabledGroup(true); count = (int)fieldType.GetProperty("Count").GetValue(fieldValue); EditorGUILayout.IntField(count, GUILayout.Width(80)); EditorGUI.EndDisabledGroup(); } if (allowExtensions) { DrawExtensions(fieldValue, expandButtonStyle); } EditorGUILayout.EndHorizontal(); if (expanded) { EditorGUI.indentLevel++; if (fieldValue != null) { FieldInfo entriesArrayField = fieldType.GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance); IList entriesArray = (IList)entriesArrayField.GetValue(fieldValue); Type elementType = TypeUtility.GetFirstElementType(entriesArrayField.FieldType); FieldInfo elementKeyFieldInfo = elementType.GetField("key", BindingFlags.Public | BindingFlags.Instance); FieldInfo elementValueFieldInfo = elementType.GetField("value", BindingFlags.Public | BindingFlags.Instance); int oldIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; for (int i = 0; i < count; i++) { object entry = entriesArray[i]; EditorGUILayout.BeginHorizontal(); object key = elementKeyFieldInfo.GetValue(entry); object value = elementValueFieldInfo.GetValue(entry); using (new EditorGUI.DisabledScope(true)) { DrawIndividualVariable(GUIContent.none, key.GetType(), key, null, out _, newValue => { /*list[index] = newValue;*/ }); } DrawIndividualVariable(GUIContent.none, value.GetType(), value, null, out var handled, newValue => { PropertyInfo indexer = fieldType.GetProperties().First(x => x.GetIndexParameters().Length > 0); indexer.SetValue(fieldValue, newValue, new[] { key }); }); EditorGUILayout.EndHorizontal(); } EditorGUI.indentLevel = oldIndent; } EditorGUI.indentLevel--; } EditorGUILayout.EndFoldoutHeaderGroup(); } else if (isArray || isGenericList) { Type elementType = TypeUtility.GetFirstElementType(fieldType); EditorGUILayout.BeginHorizontal(); string expandedID = fieldType.FullName + fieldName; bool expanded = DrawHeader(expandedID, label, (variableAttributes & VariableAttributes.Static) != 0); EditorGUI.BeginDisabledGroup((variableAttributes & VariableAttributes.ReadOnly) != 0); IList list = null; int previousSize = 0; if (fieldValue != null) { list = (IList)fieldValue; previousSize = list.Count; } int newSize = Mathf.Max(0, EditorGUILayout.IntField(previousSize, GUILayout.Width(80))); if (newSize != previousSize) { var newValue = CollectionUtility.Resize(list, isArray, fieldType, elementType, newSize); changeCallback(newValue); } if (allowExtensions) { DrawExtensions(fieldValue, expandButtonStyle); } EditorGUILayout.EndHorizontal(); if (expanded) { EditorGUI.indentLevel++; if (list != null) { for (int i = 0; i < list.Count; i++) { EditorGUILayout.BeginHorizontal(); int index = i; DrawIndividualVariable(new GUIContent("Element " + i), elementType, list[i], null, out var handled, newValue => { list[index] = newValue; }); if (allowExtensions) { DrawExtensions(list[i], expandButtonStyle); } EditorGUILayout.EndHorizontal(); } } EditorGUI.indentLevel--; } EditorGUILayout.EndFoldoutHeaderGroup(); } else { EditorGUI.BeginDisabledGroup((variableAttributes & VariableAttributes.ReadOnly) != 0); // Not a collection EditorGUILayout.BeginHorizontal(); DrawIndividualVariable(label, fieldType, fieldValue, customAttributes, out var handled, changeCallback); if (handled && allowExtensions) { DrawExtensions(fieldValue, expandButtonStyle); } EditorGUILayout.EndHorizontal(); if (!handled) { EditorGUI.EndDisabledGroup(); string expandedID = fieldType.FullName + fieldName; EditorGUILayout.BeginHorizontal(); bool expanded = DrawHeader(expandedID, label, (variableAttributes & VariableAttributes.Static) != 0); if (allowExtensions) { DrawExtensions(fieldValue, expandButtonStyle); } EditorGUILayout.EndHorizontal(); EditorGUI.BeginDisabledGroup((variableAttributes & VariableAttributes.ReadOnly) != 0); if (expanded) { EditorGUI.indentLevel++; if (fieldValue != null) { var fields = fieldType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (var fieldInfo in fields) { GUIContent subLabel = new GUIContent(fieldInfo.Name); DrawIndividualVariable(subLabel, fieldInfo.FieldType, fieldInfo.GetValue(fieldValue), null, out _, newValue => { fieldInfo.SetValue(fieldValue, newValue); }); } } else { GUILayout.Label("Null"); } EditorGUI.indentLevel--; } EditorGUILayout.EndFoldoutHeaderGroup(); } } EditorGUI.EndDisabledGroup(); if ((variableAttributes & VariableAttributes.Static) != 0) { EditorGUILayout.EndVertical(); } }
public static object DrawVariable(Type fieldType, string fieldName, object fieldValue, string metaSuffix, bool allowExtensions, Type contextType) { GUIStyle expandButtonStyle = new GUIStyle(GUI.skin.button); RectOffset padding = expandButtonStyle.padding; padding.left = 0; padding.right = 1; expandButtonStyle.padding = padding; if (fieldValue == null) { fieldValue = TypeUtility.GetDefaultValue(fieldType); } fieldName = SidekickUtility.ParseDisplayString(fieldName); if (!string.IsNullOrEmpty(metaSuffix)) { fieldName += " " + metaSuffix; } object newValue = fieldValue; bool isArray = fieldType.IsArray; bool isGenericList = TypeUtility.IsGenericList(fieldType); if (isArray || isGenericList) { Type elementType = TypeUtility.GetElementType(fieldType); string elementTypeName = TypeUtility.NameForType(elementType); if (isGenericList) { GUILayout.Label("List<" + elementTypeName + "> " + fieldName); } else { GUILayout.Label(elementTypeName + "[] " + fieldName); } IList list = null; int previousSize = 0; if (fieldValue != null) { list = (IList)fieldValue; previousSize = list.Count; } int newSize = Mathf.Max(0, EditorGUILayout.IntField("Size", previousSize)); if (newSize != previousSize) { if (list == null) { list = (IList)Activator.CreateInstance(fieldType); } CollectionUtility.Resize(ref list, elementType, newSize); } if (list != null) { for (int i = 0; i < list.Count; i++) { list[i] = DrawIndividualVariable("Element " + i, elementType, list[i]); } } } else { // Not a collection EditorGUILayout.BeginHorizontal(); newValue = DrawIndividualVariable(fieldName, fieldType, fieldValue); if (allowExtensions) { GUI.enabled = true; // GUI.SetNextControlName( if (GUILayout.Button("->", expandButtonStyle, GUILayout.Width(20))) { OldInspectorSidekick.Current.SetSelection(fieldValue, true); } bool expanded = GUILayout.Button("...", expandButtonStyle, GUILayout.Width(20)); if (Event.current.type == EventType.Repaint) { string methodIdentifier = contextType.FullName + "." + fieldType.FullName; guiRects[methodIdentifier] = GUILayoutUtility.GetLastRect(); } // if (GUIUtility.hot { // GUILayoutUtility // gridRect = GUILayoutUtility.GetLastRect(); // gridRect.width = 100; } if (expanded) { string methodIdentifier = contextType.FullName + "." + fieldType.FullName; Rect gridRect = guiRects[methodIdentifier]; GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Placeholder"), false, null); // if(fieldType == typeof(Texture)) { menu.AddItem(new GUIContent("Export PNG"), false, ExportTexture, fieldValue); } menu.DropDown(gridRect); } } EditorGUILayout.EndHorizontal(); } return(newValue); }