An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
9.6 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
public interface IListRenderer
{
void Render(IEnumerable<AssertionComponent> allAssertions, List<string> foldMarkers);
}
public abstract class AssertionListRenderer<T> : 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<AssertionComponent> allAssertions, List<string> 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<IGrouping<T, AssertionComponent>> GroupResult(IEnumerable<AssertionComponent> 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);
}
}
}