private int SortFields(FieldInfo field1, FieldInfo field2, string[] groups) { UTInspectorHint hint1 = UTInspectorHint.GetFor(field1); UTInspectorHint hint2 = UTInspectorHint.GetFor(field2); var group1Idx = Array.IndexOf(groups, hint1.group); var group2Idx = Array.IndexOf(groups, hint2.group); if (group1Idx != -1 && group2Idx != -1) { if (group1Idx == group2Idx) { return(hint1.order - hint2.order); } else { return(group1Idx - group2Idx); } } if (group1Idx == -1 && group2Idx == -1) { int groupOrder = string.Compare(hint1.group, hint2.group, StringComparison.InvariantCultureIgnoreCase); if (groupOrder == 0) { // same group or no group at all return(hint1.order - hint2.order); } // different groups // change priority of empty group if (string.IsNullOrEmpty(hint1.group)) { return(1); } else if (string.IsNullOrEmpty(hint2.group)) { return(-1); } else { return(groupOrder); } } else if (group1Idx == -1) { return(1); } else { return(-1); } }
protected virtual void DrawAll() { var type = target.GetType(); var fields = type.GetFields(); var groups = UTInspectorGroups.GetFor(type).groups; Array.Sort(fields, delegate(FieldInfo field1, FieldInfo field2) { return(SortFields(field1, field2, groups)); }); bool firstGroup = true; string currentGroup = ""; RenderActionHead(type); foreach (var field in fields) { if (field.IsPublic && !field.IsStatic) { if (!IsVisible(field)) { continue; // skip it. } var utDoc = UTDoc.GetFor(field); UTInspectorHint utHint = UTInspectorHint.GetFor(field); GUIContent label = new GUIContent(utDoc.title + (utHint.required || utHint.arrayNotEmpty ? " *" : ""), utDoc.description); if (utHint.group != currentGroup || firstGroup) { firstGroup = false; currentGroup = utHint.group; EditorGUILayout.Space(); if (!string.IsNullOrEmpty(currentGroup)) { GUILayout.Label(currentGroup, UTEditorResources.GroupStyle); } } string msg; if (!UTRequiresLicenseAttribute.HasRequiredLicense(field, out msg)) { // disable fields which require licenses that are not currently installed GUI.enabled = false; } DrawProperty(label, field); GUI.enabled = true; } } }
protected virtual void DrawProperty(GUIContent label, FieldInfo field) { var fieldValue = field.GetValue(target); if (field.FieldType.IsArray) { var objArray = (object[])fieldValue; var elementType = field.FieldType.GetElementType(); // initialize array fields with empty arrays. if (objArray == null) { objArray = (object[])Array.CreateInstance(elementType, 0); field.SetValue(target, objArray); EditorUtility.SetDirty(target); } EditorGUILayout.BeginHorizontal(); GUIContent arrayInfo = new GUIContent(objArray.Length + (objArray.Length == 1 ? " item" : " items")); EditorGUILayout.LabelField(label, arrayInfo, UTEditorResources.ArrayLabelStyle); if (GUILayout.Button("Add", UTEditorResources.ExpressionButtonStyle)) { var newArray = (object[])Array.CreateInstance(elementType, objArray.Length + 1); Array.Copy(objArray, newArray, objArray.Length); if (elementType.IsSubclassOf(typeof(UTPropertyBase))) { newArray [newArray.Length - 1] = Activator.CreateInstance(elementType); } field.SetValue(target, newArray); GUI.changed = true; objArray = newArray; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginVertical(); // the index of the element that should be deleted. // since the user cannot click multiple buttons at once // a single int is enough here. int deleteIndex = -1; for (int i = 0; i < objArray.Length; i++) { if (elementType.IsSubclassOf(typeof(UTPropertyBase))) { propertyFieldWrapper.SetUp(emptyLabel, field, (UTPropertyBase)objArray [i]); if (DrawPropertyArrayMember(propertyFieldWrapper)) { deleteIndex = i; } } else { arrayMemberWrapper.SetUp(emptyLabel, field, objArray, i); if (DrawPropertyArrayMember(arrayMemberWrapper)) { deleteIndex = i; } } } if (deleteIndex != -1) { var newArray = (object[])Array.CreateInstance(elementType, objArray.Length - 1); // no copy before index if the index was first element if (deleteIndex > 0) { Array.Copy(objArray, 0, newArray, 0, deleteIndex); } // no copy after index if the index was last element if (deleteIndex + 1 < objArray.Length) { Array.Copy(objArray, deleteIndex + 1, newArray, deleteIndex, objArray.Length - deleteIndex - 1); } field.SetValue(target, newArray); GUI.changed = true; } // add space only if array isn't empty, looks weird otherwise. if (objArray.Length > 0) { EditorGUILayout.Space(); } else { var hint = UTInspectorHint.GetFor(field); if (hint.arrayNotEmpty) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" "); EditorGUILayout.HelpBox("At least one element is required.", MessageType.Error); EditorGUILayout.EndHorizontal(); } } EditorGUILayout.EndVertical(); } else { EditorGUILayout.BeginHorizontal(); if (field.FieldType.IsSubclassOf(typeof(UTPropertyBase))) { if (fieldValue == null) { fieldValue = Activator.CreateInstance(field.FieldType); // make an empty instance field.SetValue(target, fieldValue); EditorUtility.SetDirty(target); } propertyFieldWrapper.SetUp(label, field, (UTPropertyBase)fieldValue); DrawProperty(propertyFieldWrapper, false); } else { plainFieldWrapper.SetUp(label, field, target); DrawProperty(plainFieldWrapper, false); } EditorGUILayout.EndHorizontal(); } }