using UnityEngine;
using UnityEditor;
using UnityEditor.VersionControl;
using System;
namespace Cinemachine.Editor
{
///
/// Helper for drawing embedded asset editors
///
internal class EmbeddeAssetEditor where T : ScriptableObject
{
///
/// Create in OnEnable()
///
public EmbeddeAssetEditor(string propertyName, UnityEditor.Editor owner)
{
m_PropertyName = propertyName;
m_Owner = owner;
m_CreateButtonGUIContent = new GUIContent(
"Create Asset", "Create a new shared settings asset");
}
///
/// Called after the asset editor is created, in case it needs
/// to be customized
///
public OnCreateEditorDelegate OnCreateEditor;
public delegate void OnCreateEditorDelegate(UnityEditor.Editor editor);
///
/// Called when the asset being edited was changed by the user.
///
public OnChangedDelegate OnChanged;
public delegate void OnChangedDelegate(T obj);
///
/// Free the resources in OnDisable()
///
public void OnDisable()
{
DestroyEditor();
m_Owner = null;
}
///
/// Customize this after creation if you want
///
public GUIContent m_CreateButtonGUIContent;
private string m_PropertyName;
private UnityEditor.Editor m_Editor = null;
private UnityEditor.Editor m_Owner = null;
const int kIndentOffset = 3;
///
/// Call this from OnInspectorGUI. Will draw the asset reference field, and
/// the embedded editor, or a Create Asset button, if no asset is set.
///
public void DrawEditorCombo(
string title, string defaultName, string extension, string message,
string showLabel, bool indent)
{
SerializedProperty property = m_Owner.serializedObject.FindProperty(m_PropertyName);
if (m_Editor == null)
UpdateEditor(property);
if (m_Editor == null)
AssetFieldWithCreateButton(property, title, defaultName, extension, message);
else
{
EditorGUILayout.BeginVertical(GUI.skin.box);
Rect rect = EditorGUILayout.GetControlRect(true);
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(rect, property);
if (EditorGUI.EndChangeCheck())
{
m_Owner.serializedObject.ApplyModifiedProperties();
UpdateEditor(property);
}
if (m_Editor != null)
{
Rect foldoutRect = new Rect(
rect.x - kIndentOffset, rect.y, rect.width + kIndentOffset, rect.height);
property.isExpanded = EditorGUI.Foldout(
foldoutRect, property.isExpanded, GUIContent.none, true);
bool canEditAsset = AssetDatabase.IsOpenForEdit(m_Editor.target, StatusQueryOptions.UseCachedIfPossible);
GUI.enabled = canEditAsset;
if (property.isExpanded)
{
EditorGUILayout.Separator();
EditorGUILayout.HelpBox(
"This is a shared asset. Changes made here will apply to all users of this asset.",
MessageType.Info);
EditorGUI.BeginChangeCheck();
if (indent)
++EditorGUI.indentLevel;
m_Editor.OnInspectorGUI();
if (indent)
--EditorGUI.indentLevel;
if (EditorGUI.EndChangeCheck() && (OnChanged != null))
OnChanged(property.objectReferenceValue as T);
}
GUI.enabled = true;
if (m_Editor.target != null)
{
if (!canEditAsset && GUILayout.Button("Check out"))
{
Task task = Provider.Checkout(AssetDatabase.GetAssetPath(m_Editor.target), CheckoutMode.Asset);
task.Wait();
}
}
}
EditorGUILayout.EndVertical();
}
}
private void AssetFieldWithCreateButton(
SerializedProperty property,
string title, string defaultName, string extension, string message)
{
EditorGUI.BeginChangeCheck();
float hSpace = 5;
float buttonWidth = GUI.skin.button.CalcSize(m_CreateButtonGUIContent).x;
Rect r = EditorGUILayout.GetControlRect(true);
r.width -= buttonWidth + hSpace;
EditorGUI.PropertyField(r, property);
r.x += r.width + hSpace; r.width = buttonWidth;
if (GUI.Button(r, m_CreateButtonGUIContent))
{
string newAssetPath = EditorUtility.SaveFilePanelInProject(
title, defaultName, extension, message);
if (!string.IsNullOrEmpty(newAssetPath))
{
T asset = ScriptableObjectUtility.CreateAt(newAssetPath);
property.objectReferenceValue = asset;
m_Owner.serializedObject.ApplyModifiedProperties();
}
}
if (EditorGUI.EndChangeCheck())
{
m_Owner.serializedObject.ApplyModifiedProperties();
UpdateEditor(property);
}
}
public void DestroyEditor()
{
if (m_Editor != null)
{
UnityEngine.Object.DestroyImmediate(m_Editor);
m_Editor = null;
}
}
public void UpdateEditor(SerializedProperty property)
{
var target = property.objectReferenceValue;
if (m_Editor != null && m_Editor.target != target)
DestroyEditor();
if (target != null)
{
m_Editor = UnityEditor.Editor.CreateEditor(target);
if (OnCreateEditor != null)
OnCreateEditor(m_Editor);
}
}
}
}