using UnityEditor;
using System;
using System.Collections.Generic;
using Cinemachine.Utility;
using System.Linq.Expressions;
namespace Cinemachine.Editor
{
///
/// A convenience base class for making inspector editors.
///
/// The class we're editing
public class BaseEditor : UnityEditor.Editor where T : class
{
///
/// The target object, cast as the same class as the object being edited
///
protected T Target { get { return target as T; } }
///
/// Return the Serialized property for a field, and exclude it from being automatically
/// displayed in the inspector. Call this when you need to provide a custom UX for a field.
///
/// Magic experssion code
/// Call format is FindAndExcludeProperty(x => x.myField)
/// The serialized property for the field
protected SerializedProperty FindAndExcludeProperty(Expression> expr)
{
SerializedProperty p = FindProperty(expr);
ExcludeProperty(p.name);
return p;
}
///
/// Return the Serialized property for a field.
///
/// Magic experssion code
/// Call format is FindProperty(x => x.myField)
/// The serialized property for the field
protected SerializedProperty FindProperty(Expression> expr)
{
return serializedObject.FindProperty(FieldPath(expr));
}
///
/// Magic code to get the string name of a field. Will not build if the field name changes.
///
/// Magic experssion code
/// Call format is FieldPath(x => x.myField)
/// The string name of the field
protected string FieldPath(Expression> expr)
{
return ReflectionHelpers.GetFieldPath(expr);
}
/// Obsolete, do not use. Use the overload, which is more performant
/// List of property names to exclude
protected virtual List GetExcludedPropertiesInInspector() { return mExcluded; }
/// Get the property names to exclude in the inspector.
/// Add the names to this list
protected virtual void GetExcludedPropertiesInInspector(List excluded)
{
excluded.Add("m_Script");
}
///
/// Exclude a property from automatic inclusion in the inspector
/// when DrawRemainingPropertiesInInspector() is called
///
/// The property to exclude
protected void ExcludeProperty(string propertyName)
{
mExcluded.Add(propertyName);
}
/// Check whenther a property is in the excluded list
/// The property to check
/// True if property is excluded from automatic inclusion in the inspector
/// when DrawRemainingPropertiesInInspector() is called
protected bool IsPropertyExcluded(string propertyName)
{
return mExcluded.Contains(propertyName);
}
///
/// Draw the inspector
///
public override void OnInspectorGUI()
{
BeginInspector();
DrawRemainingPropertiesInInspector();
}
List mExcluded = new List();
///
/// Clients should call this at the start of OnInspectorGUI.
/// Updates the serialized object and Sets up for excluded properties.
///
protected virtual void BeginInspector()
{
serializedObject.Update();
mExcluded.Clear();
GetExcludedPropertiesInInspector(mExcluded);
}
///
/// Draw a property in the inspector, if it is not excluded.
/// Property is marked as drawn, so will not be drawn again
/// by DrawRemainingPropertiesInInspector()
///
/// The property to draw
protected virtual void DrawPropertyInInspector(SerializedProperty p)
{
if (!IsPropertyExcluded(p.name))
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(p);
if (EditorGUI.EndChangeCheck())
serializedObject.ApplyModifiedProperties();
ExcludeProperty(p.name);
}
}
///
/// Draw all remaining unexcluded undrawn properties in the inspector.
///
protected void DrawRemainingPropertiesInInspector()
{
EditorGUI.BeginChangeCheck();
DrawPropertiesExcluding(serializedObject, mExcluded.ToArray());
if (EditorGUI.EndChangeCheck())
serializedObject.ApplyModifiedProperties();
}
}
}