using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; namespace UnityTest { public interface IListRenderer { void Render(IEnumerable allAssertions, List foldMarkers); } public abstract class AssertionListRenderer : IListRenderer { private static class Styles { public static readonly GUIStyle redLabel; static Styles() { redLabel = new GUIStyle(EditorStyles.label); redLabel.normal.textColor = Color.red; } } public void Render(IEnumerable allAssertions, List foldMarkers) { foreach (var grouping in GroupResult(allAssertions)) { var key = GetStringKey(grouping.Key); bool isFolded = foldMarkers.Contains(key); if (key != "") { EditorGUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); isFolded = PrintFoldout(isFolded, grouping.Key); if (EditorGUI.EndChangeCheck()) { if (isFolded) foldMarkers.Add(key); else foldMarkers.Remove(key); } EditorGUILayout.EndHorizontal(); if (isFolded) continue; } foreach (var assertionComponent in grouping) { EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); if (key != "") GUILayout.Space(15); var assertionKey = assertionComponent.GetHashCode().ToString(); bool isDetailsFolded = foldMarkers.Contains(assertionKey); EditorGUI.BeginChangeCheck(); if (GUILayout.Button("", EditorStyles.foldout, GUILayout.Width(15))) { isDetailsFolded = !isDetailsFolded; } if (EditorGUI.EndChangeCheck()) { if (isDetailsFolded) foldMarkers.Add(assertionKey); else foldMarkers.Remove(assertionKey); } PrintFoldedAssertionLine(assertionComponent); EditorGUILayout.EndHorizontal(); if (isDetailsFolded) { EditorGUILayout.BeginHorizontal(); if (key != "") GUILayout.Space(15); PrintAssertionLineDetails(assertionComponent); EditorGUILayout.EndHorizontal(); } GUILayout.Box("", new[] {GUILayout.ExpandWidth(true), GUILayout.Height(1)}); EditorGUILayout.EndVertical(); } } } protected abstract IEnumerable> GroupResult(IEnumerable assertionComponents); protected virtual string GetStringKey(T key) { return key.GetHashCode().ToString(); } protected virtual bool PrintFoldout(bool isFolded, T key) { var content = new GUIContent(GetFoldoutDisplayName(key)); var size = EditorStyles.foldout.CalcSize(content); var rect = GUILayoutUtility.GetRect(content, EditorStyles.foldout, GUILayout.MaxWidth(size.x)); var res = EditorGUI.Foldout(rect, !isFolded, content, true); return !res; } protected virtual string GetFoldoutDisplayName(T key) { return key.ToString(); } protected virtual void PrintFoldedAssertionLine(AssertionComponent assertionComponent) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(GUILayout.MaxWidth(300)); EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(300)); PrintPath(assertionComponent.Action.go, assertionComponent.Action.thisPropertyPath); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(GUILayout.MaxWidth(250)); var labelStr = assertionComponent.Action.GetType().Name; var labelStr2 = assertionComponent.Action.GetConfigurationDescription(); if (labelStr2 != "") labelStr += "( " + labelStr2 + ")"; EditorGUILayout.LabelField(labelStr); EditorGUILayout.EndVertical(); if (assertionComponent.Action is ComparerBase) { var comparer = assertionComponent.Action as ComparerBase; var otherStrVal = "(no value selected)"; EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(300)); switch (comparer.compareToType) { case ComparerBase.CompareToType.CompareToObject: if (comparer.other != null) { PrintPath(comparer.other, comparer.otherPropertyPath); } else { EditorGUILayout.LabelField(otherStrVal, Styles.redLabel); } break; case ComparerBase.CompareToType.CompareToConstantValue: otherStrVal = comparer.ConstValue.ToString(); EditorGUILayout.LabelField(otherStrVal); break; case ComparerBase.CompareToType.CompareToNull: otherStrVal = "null"; EditorGUILayout.LabelField(otherStrVal); break; } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } else { EditorGUILayout.LabelField(""); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); } protected virtual void PrintAssertionLineDetails(AssertionComponent assertionComponent) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(GUILayout.MaxWidth(320)); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Attached to", GUILayout.Width(70)); var sss = EditorStyles.objectField.CalcSize(new GUIContent(assertionComponent.gameObject.name)); EditorGUILayout.ObjectField(assertionComponent.gameObject, typeof(GameObject), true, GUILayout.Width(sss.x)); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(GUILayout.MaxWidth(250)); EditorGUILayout.EnumMaskField(assertionComponent.checkMethods, EditorStyles.popup, GUILayout.MaxWidth(150)); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Disabled", GUILayout.Width(55)); assertionComponent.enabled = !EditorGUILayout.Toggle(!assertionComponent.enabled, GUILayout.Width(15)); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); } private void PrintPath(GameObject go, string propertyPath) { string contentString = ""; GUIStyle styleThisPath = EditorStyles.label; if (go != null) { var sss = EditorStyles.objectField.CalcSize(new GUIContent(go.name)); EditorGUILayout.ObjectField( go, typeof(GameObject), true, GUILayout.Width(sss.x)); if (!string.IsNullOrEmpty(propertyPath)) contentString = "." + propertyPath; } else { contentString = "(no value selected)"; styleThisPath = Styles.redLabel; } var content = new GUIContent(contentString, contentString); var rect = GUILayoutUtility.GetRect(content, EditorStyles.label, GUILayout.MaxWidth(200)); EditorGUI.LabelField(rect, content, styleThisPath); } } }