using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Scripting.APIUpdating;
using UnityEngine.U2D.Animation;
namespace UnityEditor.U2D.Animation
{
[CustomEditor(typeof(SpriteLibrary))]
[CanEditMultipleObjects]
[MovedFrom("UnityEditor.Experimental.U2D.Animation")]
internal class SpriteLibraryInspector : Editor
{
static class Style
{
public static readonly string createNew = L10n.Tr("New");
public static readonly string exportToAssetInfo = L10n.Tr($"There are overrides in this Sprite Library. To save the override data, select 'Export to Sprite Library Asset'. Learn mode about creating and modifying overrides here .");
public static readonly string exportToAsset = L10n.Tr("Export to Sprite Library Asset");
public static readonly string selectSaveLocation = L10n.Tr("Select save location");
public static readonly string selectSaveLocationMessage = L10n.Tr("Select save location for the Sprite Library Asset in your project.");
public static readonly string openInSpriteLibraryEditor = L10n.Tr("Open Sprite Library Editor");
public static readonly string exportIncorrectSavePath = L10n.Tr("Asset save path must be inside the Assets folder.");
}
SerializedProperty m_MasterLibraryProperty;
SpriteLibraryAsset m_MasterLibraryObject;
Dictionary m_CachedSerializedObjects;
List m_CachedResolvers;
const string k_RootFolderName = "Assets";
const string k_OverrideEntriesDocsLink = "\"https://docs.unity3d.com/Packages/com.unity.2d.animation@latest/index.html?subfolder=/manual/SL-component.html%23overriding-entries\"";
public void OnEnable()
{
m_MasterLibraryProperty = serializedObject.FindProperty(SpriteLibraryComponentPropertyString.spriteLibraryAsset);
UpdateMasterLibraryReference();
CacheSerializedObjects();
CacheResolvers();
}
public override void OnInspectorGUI()
{
serializedObject.Update();
UpdateMasterLibraryReference();
EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_MasterLibraryProperty);
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
UpdateMasterLibraryReference();
UpdateSpriteResolvers();
}
if (m_MasterLibraryObject == null && !m_MasterLibraryProperty.hasMultipleDifferentValues)
{
if (GUILayout.Button(Style.createNew) && HandleCreateNewAsset())
{
UpdateMasterLibraryReference();
UpdateSpriteResolvers();
}
}
EditorGUILayout.EndHorizontal();
EditorGUI.BeginDisabledGroup(m_MasterLibraryObject == null || m_MasterLibraryProperty.hasMultipleDifferentValues);
if (GUILayout.Button(Style.openInSpriteLibraryEditor))
{
Selection.objects = new Object[] { m_MasterLibraryObject };
SpriteLibraryEditor.SpriteLibraryEditorWindow.OpenWindow();
}
EditorGUI.EndDisabledGroup();
if (targets.Any(t => HasLocalOverride(m_CachedSerializedObjects[t])))
{
EditorStyles.helpBox.richText = true;
EditorGUILayout.HelpBox(Style.exportToAssetInfo, MessageType.Info);
if (GUILayout.Button(Style.exportToAsset) && HandleExportOverrides())
{
UpdateMasterLibraryReference();
UpdateSpriteResolvers();
}
}
}
void CacheSerializedObjects()
{
m_CachedSerializedObjects = new Dictionary();
foreach (var t in targets)
m_CachedSerializedObjects[t] = new SerializedObject(t);
}
void CacheResolvers()
{
m_CachedResolvers = new List();
foreach (var t in targets)
{
var sl = (SpriteLibrary)t;
var resolvers = sl.GetComponentsInChildren();
m_CachedResolvers.AddRange(resolvers);
}
}
void UpdateMasterLibraryReference()
{
serializedObject.Update();
m_MasterLibraryObject = (SpriteLibraryAsset)m_MasterLibraryProperty.objectReferenceValue;
}
void UpdateSpriteResolvers()
{
foreach (var resolver in m_CachedResolvers)
{
resolver.ResolveSpriteToSpriteRenderer();
resolver.spriteLibChanged = true;
}
}
bool HandleCreateNewAsset()
{
var createPath = GetFileSavePath(target.name);
if (!string.IsNullOrEmpty(createPath))
{
var emptyLibrary = CreateInstance();
SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(emptyLibrary, createPath);
DestroyImmediate(emptyLibrary);
AssetDatabase.ImportAsset(createPath);
var newLibraryAsset = AssetDatabase.LoadAssetAtPath(createPath);
if (newLibraryAsset != null)
{
m_MasterLibraryProperty.objectReferenceValue = newLibraryAsset;
serializedObject.ApplyModifiedProperties();
return true;
}
}
return false;
}
bool HandleExportOverrides()
{
if (targets.Length == 1)
{
var exportPath = GetFileSavePath(target.name);
if (!string.IsNullOrEmpty(exportPath))
{
SpriteLibraryUtilitiesEditor.ExportSpriteLibraryToAssetFile(target as SpriteLibrary, exportPath);
return true;
}
}
else
{
var exportDirectory = GetSaveDirectory();
if (!string.IsNullOrEmpty(exportDirectory))
{
foreach (var t in targets)
{
if (HasLocalOverride(m_CachedSerializedObjects[t]))
{
var exportPath = $"{exportDirectory}/{t.name}{SpriteLibrarySourceAsset.extension}";
exportPath = AssetDatabase.GenerateUniqueAssetPath(exportPath);
SpriteLibraryUtilitiesEditor.ExportSpriteLibraryToAssetFile(t as SpriteLibrary, exportPath);
}
}
return true;
}
}
return false;
}
static string GetFileSavePath(string suggestedFileName)
{
var title = $"{Style.selectSaveLocation} ({suggestedFileName})";
var defaultName = suggestedFileName + SpriteLibrarySourceAsset.extension;
var extension = SpriteLibrarySourceAsset.extension.Substring(1);
var path = EditorUtility.SaveFilePanelInProject(title, defaultName, extension, Style.selectSaveLocationMessage);
return path;
}
static string GetSaveDirectory()
{
var saveDirectory = EditorUtility.SaveFolderPanel(Style.selectSaveLocation, k_RootFolderName, "");
if (string.IsNullOrEmpty(saveDirectory))
return string.Empty;
saveDirectory = GetPathRelativeToAssetsRoot(saveDirectory);
if (string.IsNullOrEmpty(saveDirectory))
{
Debug.Log(Style.exportIncorrectSavePath);
return string.Empty;
}
return saveDirectory;
}
static string GetPathRelativeToAssetsRoot(string path)
{
if (string.IsNullOrWhiteSpace(path) || !path.StartsWith(Application.dataPath))
return string.Empty;
var pathStartIndex = path.IndexOf(k_RootFolderName);
return pathStartIndex == -1 ? string.Empty : path.Substring(pathStartIndex);
}
static bool HasLocalOverride(SerializedObject serializedObject)
{
serializedObject.Update();
var library = serializedObject.FindProperty(SpriteLibraryComponentPropertyString.library);
return library != null && library.arraySize > 0;
}
}
}