public static object DrawGUI(object target, string label = "", Type targetType = null, FieldInfo fieldInfo = null, object context = null) { #if UNITY_EDITOR if (targetType == null && target == null && fieldInfo == null) { Debug.LogError("Insufficient information to determine type."); return(null); } if (targetType == null) { targetType = target != null?target.GetType() : fieldInfo.FieldType; } var drawer = GetDrawer(targetType); if (context != null && drawer != null) { target = drawer.DrawGUI(target, label, targetType, fieldInfo, context); } else { if (target != null) { var isInList = context != null && typeof(IList).IsAssignableFrom(context.GetType()); var isUnityObject = typeof(UnityEngine.Object).IsAssignableFrom(targetType); if (!isInList && !isUnityObject && !targetType.IsAssignableFrom(typeof(IList)) && !targetType.IsArray) { EditorGUILayout.BeginHorizontal(); if (string.IsNullOrEmpty(label) && fieldInfo != null) { label = fieldInfo.Name; } EditorGUILayout.LabelField(string.Format("{0} [{1}]", label, targetType)); if (GUILayout.Button(GenericEditor.DeleteContent, EditorStyles.label, GUILayout.Width(20))) { return(null); } EditorGUILayout.EndHorizontal(); } if (fieldInfo != null) { //Debug.Log(string.Format("FieldInfo for {0} wasn't null, so increased IndentLevel from {1} to {2}", fieldInfo.Name, EditorGUI.indentLevel, EditorGUI.indentLevel +1)); EditorGUI.indentLevel++; } var fields = GetFields(targetType); foreach (var field in fields) { var subObj = field.GetValue(target); subObj = DrawGUI(subObj, GetFriendlyName(field), subObj != null ? subObj.GetType() : field.FieldType, field, target); field.SetValue(target, subObj); } if (fieldInfo != null) { //Debug.Log(string.Format("FieldInfo for {0} wasn't null, so decreased IndentLevel from {1} to {2}", fieldInfo.Name, EditorGUI.indentLevel, EditorGUI.indentLevel -1)); EditorGUI.indentLevel--; } } else { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(label); if (targetType.IsAbstract || targetType.IsInterface) { EditorGUILayoutX.DerivedTypeSelectButton(targetType, (o) => { fieldInfo.SetValue(context, o); } ); } else if (EditorGUILayoutX.IndentedButton("Add " + targetType.Name)) { target = Activator.CreateInstance(targetType); } EditorGUILayout.EndHorizontal(); } } var unityObj = target as Object; if (!Application.isPlaying && unityObj) { EditorUtility.SetDirty(unityObj); EditorSceneManager.MarkAllScenesDirty(); } #endif return(target); }
protected override IList DrawGUIInternal(IList target, string label = "", Type targetType = null, FieldInfo fieldInfo = null, object context = null) { var expandedKey = fieldInfo != null ? fieldInfo.Name : context + "list"; var listType = targetType.IsArray ? targetType.GetElementType() : targetType.GetGenericArguments()[0]; ListGenericUIAttribute listAttribute = fieldInfo != null?fieldInfo.GetAttribute <ListGenericUIAttribute>() : null; if (!GenericEditor.ExpandedFieldCache.ContainsKey(expandedKey)) { GenericEditor.ExpandedFieldCache[expandedKey] = false; } if (fieldInfo != null) { GenericEditor.ExpandedFieldCache[expandedKey] = EditorGUILayout.Foldout(GenericEditor.ExpandedFieldCache[expandedKey], fieldInfo.Name, EditorStyles.boldFont); } if (fieldInfo == null || GenericEditor.ExpandedFieldCache[expandedKey]) { for (var i = 0; i < target.Count; i++) { EditorGUI.indentLevel++; var o = target[i]; if (!GenericEditor.ExpandedFieldCache.ContainsKey(expandedKey + i)) { GenericEditor.ExpandedFieldCache[expandedKey + i] = false; } if (typeof(UnityEngine.Object).IsAssignableFrom(listType)) { EditorGUILayout.BeginHorizontal(); o = EditorGUILayout.ObjectField((UnityEngine.Object)o, listType, true); if (GUILayout.Button(GenericEditor.DeleteContent, EditorStyles.label, GUILayout.Width(20))) { if (targetType.IsArray) { target = ((Array)target).Remove(i); } else { target.RemoveAt(i); } break; } EditorGUILayout.EndHorizontal(); } else { EditorGUILayout.BeginHorizontal(); string objectLabel = "NULL"; if (o != null) { objectLabel = o.ToString(); } EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GenericEditor.ExpandedFieldCache[expandedKey + i] = EditorGUILayout.Foldout(GenericEditor.ExpandedFieldCache[expandedKey + i], objectLabel); EditorGUILayout.EndHorizontal(); if (o != null && typeof(IHelpLinkProvider).IsAssignableFrom(listType)) { var helpURL = (o as IHelpLinkProvider).HelpURL; if (!string.IsNullOrEmpty(helpURL)) { EditorExtensions.HelpButton(helpURL); } } if (GUILayout.Button(GenericEditor.DeleteContent, EditorStyles.label, GUILayout.Width(20))) { target.RemoveAt(i); break; } var enableToggle = o as IShowEnableToggle; if (enableToggle != null) { var lastIndent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; enableToggle.Editor_Enabled = EditorGUILayout.Toggle(GUIContent.none, enableToggle.Editor_Enabled, GUILayout.Width(20)); EditorGUI.indentLevel = lastIndent; } EditorGUILayout.EndHorizontal(); if (GenericEditor.ExpandedFieldCache[expandedKey + i]) { if (o != null) { o = GenericEditor.DrawGUI(o, "", o.GetType(), fieldInfo, target); } else { o = GenericEditor.DrawGUI(null, "Null", listType, fieldInfo, target); } } } target[i] = o; EditorGUI.indentLevel--; EditorExtensions.Seperator(); } if (!typeof(UnityEngine.Object).IsAssignableFrom(listType) && (listType.IsAbstract || listType.IsInterface || (fieldInfo != null && listAttribute != null && listAttribute.AllowDerived))) { EditorGUILayoutX.DerivedTypeSelectButton(listType, (o) => target.Add(o)); } else if (EditorGUILayoutX.IndentedButton("Add " + listType.Name)) { if (typeof(UnityEngine.Object).IsAssignableFrom(listType)) { if (targetType.IsArray) { target = ((Array)target).Add(null); } else { target.Add(null); } } else { var newInstance = Activator.CreateInstance(listType); if (newInstance != null && !newInstance.Equals(null)) { if (targetType.IsArray) { target = ((Array)target).Add(newInstance); } else { target.Add(newInstance); } } } } } return(target); }