testss
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Scripting.APIUpdating;
|
||||
using UnityEngine.U2D.Animation;
|
||||
|
||||
namespace UnityEditor.U2D.Animation
|
||||
{
|
||||
[CustomEditor(typeof(SpriteLibraryAsset))]
|
||||
[MovedFrom("UnityEditor.Experimental.U2D.Animation")]
|
||||
internal class SpriteLibraryAssetInspector : Editor
|
||||
{
|
||||
static class Style
|
||||
{
|
||||
public static GUIContent duplicateWarningText = EditorGUIUtility.TrTextContent("Duplicate name found or name hash clashes. Please use a different name");
|
||||
public static GUIContent duplicateWarning = EditorGUIUtility.TrIconContent("console.warnicon.sml", duplicateWarningText.text);
|
||||
public static GUIContent nameLabel = new GUIContent(TextContent.label);
|
||||
public static string categoryListLabel = L10n.Tr("Category List");
|
||||
public static int lineSpacing = 3;
|
||||
}
|
||||
|
||||
private SerializedProperty m_Labels;
|
||||
private ReorderableList m_LabelReorderableList;
|
||||
|
||||
private bool m_UpdateHash = false;
|
||||
|
||||
private readonly float kElementHeight = EditorGUIUtility.singleLineHeight * 3;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
m_Labels = serializedObject.FindProperty("m_Labels");
|
||||
|
||||
m_LabelReorderableList = new ReorderableList(serializedObject, m_Labels, true, false, true, true);
|
||||
SetupOrderList();
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
var sla = target as SpriteLibraryAsset;
|
||||
if (sla != null)
|
||||
sla.UpdateHashes();
|
||||
}
|
||||
|
||||
float GetElementHeight(int index)
|
||||
{
|
||||
var property = m_Labels.GetArrayElementAtIndex(index);
|
||||
var spriteListProp = property.FindPropertyRelative("m_CategoryList");
|
||||
if (spriteListProp.isExpanded)
|
||||
return (spriteListProp.arraySize + 1) * (EditorGUIUtility.singleLineHeight + Style.lineSpacing) + kElementHeight;
|
||||
|
||||
return kElementHeight;
|
||||
}
|
||||
|
||||
void DrawElement(Rect rect, int index, bool selected, bool focused)
|
||||
{
|
||||
var property = m_Labels.GetArrayElementAtIndex(index);
|
||||
|
||||
var catRect = new Rect(rect.x, rect.y, rect.width - kElementHeight, EditorGUIUtility.singleLineHeight);
|
||||
var vaRect = new Rect(rect.x, rect.y + EditorGUIUtility.singleLineHeight, rect.width - kElementHeight, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
var categoryProp = property.FindPropertyRelative("m_Name");
|
||||
|
||||
var spriteListProp = property.FindPropertyRelative("m_CategoryList");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newCatName = EditorGUI.DelayedTextField(catRect, categoryProp.stringValue);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
newCatName = newCatName.Trim();
|
||||
m_UpdateHash = true;
|
||||
if (categoryProp.stringValue != newCatName)
|
||||
{
|
||||
// Check if this nameLabel is already taken
|
||||
if (!IsNameInUsed(newCatName, m_Labels, "m_Name", 0))
|
||||
categoryProp.stringValue = newCatName;
|
||||
else
|
||||
Debug.LogWarning(Style.duplicateWarningText.text);
|
||||
}
|
||||
}
|
||||
|
||||
spriteListProp.isExpanded = EditorGUI.Foldout(vaRect, spriteListProp.isExpanded, Style.categoryListLabel);
|
||||
if (spriteListProp.isExpanded)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
var indentedRect = EditorGUI.IndentedRect(vaRect);
|
||||
var labelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 40 + indentedRect.x - vaRect.x;
|
||||
indentedRect.y += EditorGUIUtility.singleLineHeight + Style.lineSpacing;
|
||||
var sizeRect = indentedRect;
|
||||
int size = EditorGUI.IntField(sizeRect, TextContent.size, spriteListProp.arraySize);
|
||||
if (size != spriteListProp.arraySize && size >= 0)
|
||||
spriteListProp.arraySize = size;
|
||||
indentedRect.y += EditorGUIUtility.singleLineHeight + Style.lineSpacing;
|
||||
DrawSpriteListProperty(indentedRect, spriteListProp);
|
||||
EditorGUIUtility.labelWidth = labelWidth;
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSpriteListProperty(Rect rect, SerializedProperty spriteListProp)
|
||||
{
|
||||
for (int i = 0; i < spriteListProp.arraySize; ++i)
|
||||
{
|
||||
var element = spriteListProp.GetArrayElementAtIndex(i);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var oldName = element.FindPropertyRelative("m_Name").stringValue;
|
||||
var nameRect = new Rect(rect.x, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight);
|
||||
bool nameDuplicate = IsNameInUsed(oldName, spriteListProp, "m_Name", 1);
|
||||
if (nameDuplicate)
|
||||
{
|
||||
nameRect.width -= 20;
|
||||
}
|
||||
var newName = EditorGUI.DelayedTextField(
|
||||
nameRect,
|
||||
Style.nameLabel,
|
||||
oldName);
|
||||
if (nameDuplicate)
|
||||
{
|
||||
nameRect.x += nameRect.width;
|
||||
nameRect.width = 20;
|
||||
GUI.Label(nameRect, Style.duplicateWarning);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
newName = newName.Trim();
|
||||
element.FindPropertyRelative("m_Name").stringValue = newName;
|
||||
}
|
||||
|
||||
EditorGUI.PropertyField(new Rect(rect.x + rect.width / 2 + 5, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight),
|
||||
element.FindPropertyRelative("m_Sprite"));
|
||||
rect.y += EditorGUIUtility.singleLineHeight + Style.lineSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
SetupOrderList();
|
||||
|
||||
m_UpdateHash = false;
|
||||
m_LabelReorderableList.DoLayoutList();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (m_UpdateHash)
|
||||
(target as SpriteLibraryAsset).UpdateHashes();
|
||||
}
|
||||
|
||||
bool IsNameInUsed(string name, SerializedProperty property, string propertyField, int threshold)
|
||||
{
|
||||
int count = 0;
|
||||
var nameHash = SpriteLibraryAsset.GetStringHash(name);
|
||||
for (int i = 0; i < property.arraySize; ++i)
|
||||
{
|
||||
var sp = property.GetArrayElementAtIndex(i);
|
||||
var otherName = sp.FindPropertyRelative(propertyField).stringValue;
|
||||
var otherNameHash = SpriteLibraryAsset.GetStringHash(otherName);
|
||||
if (otherName == name || nameHash == otherNameHash)
|
||||
{
|
||||
count++;
|
||||
if (count > threshold)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnAddCallback(ReorderableList list)
|
||||
{
|
||||
var oldSize = m_Labels.arraySize;
|
||||
m_Labels.arraySize += 1;
|
||||
const string kNewCatName = "New Category";
|
||||
string newCatName = kNewCatName;
|
||||
int catNameIncrement = 1;
|
||||
while (true)
|
||||
{
|
||||
if (IsNameInUsed(newCatName, m_Labels, "m_Name", 0))
|
||||
newCatName = string.Format("{0} {1}", kNewCatName, catNameIncrement++);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
var sp = m_Labels.GetArrayElementAtIndex(oldSize);
|
||||
sp.FindPropertyRelative("m_Name").stringValue = newCatName;
|
||||
sp.FindPropertyRelative("m_Hash").intValue = SpriteLibraryAsset.GetStringHash(newCatName);
|
||||
}
|
||||
|
||||
private void SetupOrderList()
|
||||
{
|
||||
m_LabelReorderableList.drawElementCallback = DrawElement;
|
||||
m_LabelReorderableList.elementHeight = kElementHeight;
|
||||
m_LabelReorderableList.elementHeightCallback = GetElementHeight;
|
||||
m_LabelReorderableList.onAddCallback = OnAddCallback;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace UnityEditor.U2D.Animation
|
||||
{
|
||||
/// <summary>
|
||||
/// Structure that defines a Sprite Library Category Label
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct SpriteCategoryLabel
|
||||
{
|
||||
[SerializeField]
|
||||
string m_Name;
|
||||
[SerializeField]
|
||||
string m_SpriteId;
|
||||
|
||||
/// <summary>
|
||||
/// Get and set the name for the Sprite label
|
||||
/// </summary>
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
set { m_Name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get and set the Sprite Id.
|
||||
/// </summary>
|
||||
public string spriteId
|
||||
{
|
||||
get { return m_SpriteId; }
|
||||
set { m_SpriteId = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Structure that defines a Sprite Library Category.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct SpriteCategory
|
||||
{
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("name")]
|
||||
string m_Name;
|
||||
[SerializeField]
|
||||
List<SpriteCategoryLabel> m_Labels;
|
||||
|
||||
/// <summary>
|
||||
/// Get and set the name for the Sprite Category
|
||||
/// </summary>
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
set { m_Name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get and set the Sprites registered to this category.
|
||||
/// </summary>
|
||||
public List<SpriteCategoryLabel> labels
|
||||
{
|
||||
get { return m_Labels; }
|
||||
set { m_Labels = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A structure to hold a collection of SpriteCategory
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct SpriteCategoryList
|
||||
{
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("categories")]
|
||||
List<SpriteCategory> m_Categories;
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the a list of SpriteCategory
|
||||
/// </summary>
|
||||
public List<SpriteCategory> categories
|
||||
{
|
||||
get { return m_Categories; }
|
||||
set { m_Categories = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>An interface that allows Sprite Editor Modules to edit Sprite Library data for user custom importer.</summary>
|
||||
/// <remarks>Implement this interface for [[ScriptedImporter]] to leverage on Sprite Editor Modules to edit Sprite Library data.</remarks>
|
||||
[Obsolete("The interface is no longer used")]
|
||||
public interface ISpriteLibDataProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the SpriteCategoryList structure that represents the Sprite Library data.
|
||||
/// </summary>
|
||||
/// <returns>SpriteCategoryList data</returns>
|
||||
SpriteCategoryList GetSpriteCategoryList();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the SpriteCategoryList structure that represents the Sprite Library data to the data provider
|
||||
/// </summary>
|
||||
/// <param name="spriteCategoryList">Data to set</param>
|
||||
void SetSpriteCategoryList(SpriteCategoryList spriteCategoryList);
|
||||
}
|
||||
}
|
@@ -0,0 +1,183 @@
|
||||
using System.Collections.Generic;
|
||||
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
|
||||
{
|
||||
class SpriteLibCombineCache : ScriptableObject
|
||||
{
|
||||
[SerializeField]
|
||||
List<SpriteLibCategoryOverride> m_Library = new List<SpriteLibCategoryOverride>();
|
||||
|
||||
public List<SpriteLibCategoryOverride> library
|
||||
{
|
||||
get => m_Library;
|
||||
}
|
||||
}
|
||||
|
||||
static class Style
|
||||
{
|
||||
public static string libraryDifferentValue = L10n.Tr("Sprite Library has different values.");
|
||||
}
|
||||
|
||||
private SpriteLibCombineCache m_SpriteLibCombineCache;
|
||||
private SerializedObject m_InternalCombineCacheSO;
|
||||
private SerializedProperty m_SpriteLibraryAsset;
|
||||
private SerializedProperty m_Library;
|
||||
private SerializedProperty m_LibraryOverride;
|
||||
private SpriteLibraryDataInspector m_SpriteLibraryDataInspector;
|
||||
public void OnEnable()
|
||||
{
|
||||
m_SpriteLibCombineCache = ScriptableObject.CreateInstance<SpriteLibCombineCache>();
|
||||
m_InternalCombineCacheSO = new SerializedObject(m_SpriteLibCombineCache);
|
||||
|
||||
m_SpriteLibraryAsset = serializedObject.FindProperty("m_SpriteLibraryAsset");
|
||||
m_Library = serializedObject.FindProperty("m_Library");
|
||||
m_LibraryOverride = m_InternalCombineCacheSO.FindProperty("m_Library");
|
||||
InitSpriteLibraryDataCache();
|
||||
}
|
||||
|
||||
void InitSpriteLibraryDataCache()
|
||||
{
|
||||
if (!m_Library.hasMultipleDifferentValues && !m_SpriteLibraryAsset.hasMultipleDifferentValues)
|
||||
{
|
||||
ConvertSpriteLibraryToOverride(m_SpriteLibCombineCache.library, m_Library);
|
||||
m_InternalCombineCacheSO.Update();
|
||||
SpriteLibraryDataInspector.UpdateLibraryWithNewMainLibrary((SpriteLibraryAsset)m_SpriteLibraryAsset.objectReferenceValue, m_LibraryOverride);
|
||||
m_SpriteLibraryDataInspector = new SpriteLibraryDataInspector(serializedObject, m_LibraryOverride);
|
||||
m_InternalCombineCacheSO.ApplyModifiedPropertiesWithoutUndo();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
m_InternalCombineCacheSO.Update();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(m_SpriteLibraryAsset);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
InitSpriteLibraryDataCache();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
foreach (var t in targets)
|
||||
{
|
||||
var srs = (t as SpriteLibrary).GetComponentsInChildren<SpriteResolver>();
|
||||
foreach (var sr in srs)
|
||||
{
|
||||
sr.ResolveSpriteToSpriteRenderer();
|
||||
sr.spriteLibChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_SpriteLibraryDataInspector != null)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_SpriteLibraryDataInspector.OnGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
m_InternalCombineCacheSO.ApplyModifiedProperties();
|
||||
ConvertOverrideToSpriteLibrary(m_SpriteLibCombineCache.library, m_Library);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
foreach (var t in targets)
|
||||
{
|
||||
var spriteLib = (SpriteLibrary) t;
|
||||
spriteLib.CacheOverrides();
|
||||
var srs = spriteLib.GetComponentsInChildren<SpriteResolver>();
|
||||
foreach (var sr in srs)
|
||||
{
|
||||
sr.ResolveSpriteToSpriteRenderer();
|
||||
sr.spriteLibChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox(Style.libraryDifferentValue, MessageType.Info);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertSpriteLibraryToOverride(List<SpriteLibCategoryOverride> libOverride, SerializedProperty lib)
|
||||
{
|
||||
libOverride.Clear();
|
||||
if (lib.arraySize > 0)
|
||||
{
|
||||
var categoryEntries = lib.GetArrayElementAtIndex(0);
|
||||
for (int i = 0; i < lib.arraySize; ++i)
|
||||
{
|
||||
var overrideCategory = new SpriteLibCategoryOverride()
|
||||
{
|
||||
categoryList = new List<SpriteCategoryEntry>(),
|
||||
entryOverrideCount = 0,
|
||||
fromMain = false,
|
||||
name = categoryEntries.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue,
|
||||
overrideEntries = new List<SpriteCategoryEntryOverride>()
|
||||
};
|
||||
var entries = categoryEntries.FindPropertyRelative(SpriteLibraryPropertyString.categoryList);
|
||||
var overrideCategoryEntries = overrideCategory.overrideEntries;
|
||||
if (entries.arraySize > 0)
|
||||
{
|
||||
var entry = entries.GetArrayElementAtIndex(0);
|
||||
for (int j = 0; j < entries.arraySize; ++j)
|
||||
{
|
||||
overrideCategoryEntries.Add(new SpriteCategoryEntryOverride()
|
||||
{
|
||||
fromMain = false,
|
||||
name = entry.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue,
|
||||
sprite = (Sprite)entry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue,
|
||||
spriteOverride = (Sprite)entry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue
|
||||
});
|
||||
entry.Next(false);
|
||||
}
|
||||
}
|
||||
libOverride.Add(overrideCategory);
|
||||
categoryEntries.Next(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertOverrideToSpriteLibrary(List<SpriteLibCategoryOverride> libOverride, SerializedProperty lib)
|
||||
{
|
||||
lib.arraySize = 0;
|
||||
if (libOverride.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < libOverride.Count; ++i)
|
||||
{
|
||||
var libOverrideElement = libOverride[i];
|
||||
if (!libOverrideElement.fromMain || libOverrideElement.entryOverrideCount > 0)
|
||||
{
|
||||
lib.arraySize += 1;
|
||||
var libElement = lib.GetArrayElementAtIndex(lib.arraySize - 1);
|
||||
libElement.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = libOverrideElement.name;
|
||||
var overrideEntries = libOverrideElement.overrideEntries;
|
||||
var entries = libElement.FindPropertyRelative(SpriteLibraryPropertyString.categoryList);
|
||||
entries.arraySize = 0;
|
||||
if (overrideEntries.Count > 0)
|
||||
{
|
||||
for (int j = 0; j < overrideEntries.Count; ++j)
|
||||
{
|
||||
var overrideEntry = overrideEntries[j];
|
||||
if (!overrideEntry.fromMain ||
|
||||
overrideEntry.sprite != overrideEntry.spriteOverride)
|
||||
{
|
||||
entries.arraySize += 1;
|
||||
var entry = entries.GetArrayElementAtIndex(entries.arraySize - 1);
|
||||
entry.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = overrideEntry.name;
|
||||
entry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue = overrideEntry.spriteOverride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
namespace UnityEditor.U2D.Animation
|
||||
{
|
||||
internal static class SpriteLibraryPropertyString
|
||||
{
|
||||
public static string overrideEntries = "m_OverrideEntries";
|
||||
public static string fromMain = "m_FromMain";
|
||||
public static string spriteOverride = "m_SpriteOverride";
|
||||
public static string sprite = "m_Sprite";
|
||||
public static string overrideEntryCount = "m_EntryOverrideCount";
|
||||
public static string name = "m_Name";
|
||||
public static string categoryList = "m_CategoryList";
|
||||
}
|
||||
}
|
@@ -0,0 +1,676 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.U2D.Animation;
|
||||
|
||||
namespace UnityEditor.U2D.Animation
|
||||
{
|
||||
internal class SpriteLibraryDataInspector
|
||||
{
|
||||
class Style
|
||||
{
|
||||
public GUIContent duplicateWarningText = EditorGUIUtility.TrTextContent("Duplicate name found or name hash clashes. Please use a different name");
|
||||
public GUIContent duplicateWarning;
|
||||
public int lineSpacing = 3;
|
||||
public int spriteGridSize = 64;
|
||||
public float gridPadding = EditorGUIUtility.standardVerticalSpacing * 2;
|
||||
public int gridHeaderSize = 20;
|
||||
public int gridFooterSize = 20;
|
||||
public float gridHeight;
|
||||
public Vector2 gridSize;
|
||||
public GUIStyle footerBackground;
|
||||
public GUIStyle boxBackground;
|
||||
public GUIStyle preButton;
|
||||
public GUIStyle headerBackground;
|
||||
public GUIStyle gridList;
|
||||
public GUIContent iconToolbarPlus = EditorGUIUtility.TrIconContent("Toolbar Plus", "Add to list");
|
||||
public GUIContent iconToolbarMinus = EditorGUIUtility.TrIconContent("Toolbar Minus", "Remove selection or last element from list");
|
||||
public GUIContent overrideIcon = EditorGUIUtility.TrIconContent("PrefabOverlayAdded Icon");
|
||||
public string newCategoryText = L10n.Tr("New Category");
|
||||
public string categoryLabel = L10n.Tr("Category");
|
||||
public float categoryElementHeight;
|
||||
public float categoryTextFieldHeight;
|
||||
public string newEntryText = L10n.Tr("Entry");
|
||||
public float categoryLabelWidth = 100;
|
||||
|
||||
public Style()
|
||||
{
|
||||
gridSize = new Vector2(spriteGridSize + gridPadding * 2,
|
||||
spriteGridSize + lineSpacing + EditorGUIUtility.singleLineHeight + gridPadding * 2);
|
||||
duplicateWarning = EditorGUIUtility.TrIconContent("console.warnicon.sml", duplicateWarningText.text);
|
||||
gridHeight = gridSize.y +gridPadding + gridFooterSize;
|
||||
categoryTextFieldHeight = EditorGUIUtility.singleLineHeight + lineSpacing;
|
||||
categoryElementHeight = gridHeight + categoryTextFieldHeight + gridHeaderSize;
|
||||
|
||||
}
|
||||
|
||||
public void InitStyle(Event currentEvent)
|
||||
{
|
||||
if (footerBackground == null && currentEvent.type == EventType.Repaint)
|
||||
{
|
||||
footerBackground = "RL Footer";
|
||||
boxBackground = "RL Background";
|
||||
preButton = "RL FooterButton";
|
||||
headerBackground = "RL Header";
|
||||
gridList = "GridList";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SpriteCategoryGridState
|
||||
{
|
||||
public Vector2 scrollPos;
|
||||
public int selectedIndex;
|
||||
|
||||
public static SpriteCategoryGridState Default =>
|
||||
new SpriteCategoryGridState()
|
||||
{
|
||||
scrollPos = Vector2.zero,
|
||||
selectedIndex = 0
|
||||
};
|
||||
}
|
||||
|
||||
private Style m_Style;
|
||||
private SerializedProperty m_Library;
|
||||
private List<SpriteCategoryGridState> m_GridStates = new List<SpriteCategoryGridState>();
|
||||
private ReorderableList m_LabelReorderableList;
|
||||
|
||||
public SpriteLibraryDataInspector(SerializedObject so,
|
||||
SerializedProperty library)
|
||||
{
|
||||
m_Style = new Style();
|
||||
m_Library = library;
|
||||
m_LabelReorderableList = new ReorderableList(so, library, true, false,
|
||||
true, true);
|
||||
m_LabelReorderableList.drawElementCallback = DrawElement;
|
||||
m_LabelReorderableList.elementHeight = m_Style.categoryTextFieldHeight;
|
||||
m_LabelReorderableList.elementHeightCallback = delegate(int index) { return m_Style.categoryElementHeight; };
|
||||
m_LabelReorderableList.onAddCallback = OnAddCallback;
|
||||
m_LabelReorderableList.onCanRemoveCallback = OnCanRemoveCallback;
|
||||
}
|
||||
|
||||
public static void UpdateLibraryWithNewMainLibrary(SpriteLibraryAsset spriteLib, SerializedProperty library)
|
||||
{
|
||||
var emptyStringArray = new string[0];
|
||||
var categories = spriteLib != null ? spriteLib.GetCategoryNames() : emptyStringArray;
|
||||
|
||||
// populate new primary
|
||||
int newCatgoryIndex = 0;
|
||||
foreach (var newCategory in categories)
|
||||
{
|
||||
SerializedProperty existingCategory = null;
|
||||
if (library.arraySize > 0)
|
||||
{
|
||||
var cat = library.GetArrayElementAtIndex(0);
|
||||
for (int i = 0; i < library.arraySize; ++i)
|
||||
{
|
||||
if (cat.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue == newCategory)
|
||||
{
|
||||
existingCategory = cat;
|
||||
if(i != newCatgoryIndex)
|
||||
library.MoveArrayElement(i, newCatgoryIndex);
|
||||
break;
|
||||
}
|
||||
cat.Next(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (existingCategory != null)
|
||||
{
|
||||
if(!existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue)
|
||||
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
library.InsertArrayElementAtIndex(newCatgoryIndex);
|
||||
existingCategory = library.GetArrayElementAtIndex(newCatgoryIndex);
|
||||
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true;
|
||||
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newCategory;
|
||||
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue = 0;
|
||||
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries).arraySize = 0;
|
||||
}
|
||||
newCatgoryIndex++;
|
||||
|
||||
var newEntries = spriteLib.GetCategoryLabelNames(newCategory);
|
||||
var entries = existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
|
||||
int newEntryIndex = 0;
|
||||
foreach (var newEntry in newEntries)
|
||||
{
|
||||
SerializedProperty cacheEntry = null;
|
||||
if (entries.arraySize > 0)
|
||||
{
|
||||
var ent = entries.GetArrayElementAtIndex(0);
|
||||
for (int j = 0; j < entries.arraySize; ++j)
|
||||
{
|
||||
if (ent.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue == newEntry)
|
||||
{
|
||||
cacheEntry = ent;
|
||||
if(j != newEntryIndex)
|
||||
entries.MoveArrayElement(j, newEntryIndex);
|
||||
break;
|
||||
}
|
||||
ent.Next(false);
|
||||
}
|
||||
}
|
||||
var mainSprite = spriteLib.GetSprite(newCategory, newEntry);
|
||||
if (cacheEntry == null)
|
||||
{
|
||||
entries.InsertArrayElementAtIndex(newEntryIndex);
|
||||
cacheEntry = entries.GetArrayElementAtIndex(newEntryIndex);
|
||||
cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newEntry;
|
||||
cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride)
|
||||
.objectReferenceValue = mainSprite;
|
||||
}
|
||||
|
||||
++newEntryIndex;
|
||||
if(!cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue)
|
||||
cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true;
|
||||
if(cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue != mainSprite)
|
||||
cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue = mainSprite;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any library or entry that is not in primary and not overridden
|
||||
for (int i = 0; i < library.arraySize; ++i)
|
||||
{
|
||||
var categoryProperty = library.GetArrayElementAtIndex(i);
|
||||
var categoryEntriesProperty = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
|
||||
var categoryFromMainProperty = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.fromMain);
|
||||
|
||||
var categoryName = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
|
||||
var categoryInPrimary = categories.Contains(categoryName);
|
||||
var entriesInPrimary = categoryInPrimary ? spriteLib.GetCategoryLabelNames(categoryName) : emptyStringArray;
|
||||
|
||||
var categoryOverride = 0;
|
||||
for (int j = 0; j < categoryEntriesProperty.arraySize; ++j)
|
||||
{
|
||||
var entry = categoryEntriesProperty.GetArrayElementAtIndex(j);
|
||||
var entryName = entry.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
|
||||
var entryInPrimary = entriesInPrimary.Contains(entryName);
|
||||
var entryFromMainProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain);
|
||||
var overrideSpriteProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride);
|
||||
var spriteProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.sprite);
|
||||
if (!entryInPrimary)
|
||||
{
|
||||
// Entry no longer in new primary.
|
||||
// Check for override and set it to us
|
||||
if (entryFromMainProperty.boolValue)
|
||||
{
|
||||
if (overrideSpriteProperty.objectReferenceValue == spriteProperty.objectReferenceValue)
|
||||
{
|
||||
categoryEntriesProperty.DeleteArrayElementAtIndex(j);
|
||||
--j;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(entryFromMainProperty.boolValue)
|
||||
entryFromMainProperty.boolValue = false;
|
||||
if(spriteProperty.objectReferenceValue != overrideSpriteProperty.objectReferenceValue)
|
||||
spriteProperty.objectReferenceValue = overrideSpriteProperty.objectReferenceValue;
|
||||
++categoryOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if sprite has been override
|
||||
if(spriteProperty.objectReferenceValue != overrideSpriteProperty.objectReferenceValue)
|
||||
++categoryOverride;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!categoryInPrimary && categoryEntriesProperty.arraySize == 0 && categoryFromMainProperty.boolValue)
|
||||
{
|
||||
library.DeleteArrayElementAtIndex(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
// since there is override, and we removed the main. This category now
|
||||
// belows to the library
|
||||
if (!categoryInPrimary)
|
||||
{
|
||||
if(categoryFromMainProperty.boolValue)
|
||||
categoryFromMainProperty.boolValue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue != categoryOverride)
|
||||
categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue = categoryOverride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
m_Style.InitStyle(Event.current);
|
||||
m_LabelReorderableList.DoLayoutList();
|
||||
HandleCategoryCreateSpriteDragAndDrop();
|
||||
}
|
||||
|
||||
void HandleCategoryCreateSpriteDragAndDrop()
|
||||
{
|
||||
bool dragAccepted = false;
|
||||
switch (Event.current.type)
|
||||
{
|
||||
case EventType.DragPerform:
|
||||
foreach (var obj in DragAndDrop.objectReferences)
|
||||
{
|
||||
if (obj is Sprite || obj is Texture2D)
|
||||
{
|
||||
dragAccepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dragAccepted)
|
||||
{
|
||||
DragAndDrop.AcceptDrag();
|
||||
foreach (var obj in DragAndDrop.objectReferences)
|
||||
{
|
||||
if (obj is Sprite)
|
||||
{
|
||||
var category = AddCategory(obj.name, false);
|
||||
AddSpriteToCategory(category, (Sprite)obj);
|
||||
}
|
||||
else if (obj is Texture2D)
|
||||
{
|
||||
var sprites = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(obj))
|
||||
.Where(x => x is Sprite);
|
||||
foreach (var s in sprites)
|
||||
{
|
||||
var category = AddCategory(s.name, false);
|
||||
AddSpriteToCategory(category, (Sprite)s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Event.current.Use();
|
||||
break;
|
||||
case EventType.DragUpdated:
|
||||
if (DragAndDrop.objectReferences.Count(x => x is Sprite || x is Texture2D) > 0)
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||
else
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
|
||||
Event.current.Use();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SerializedProperty IsCategoryNameInUsed(string name)
|
||||
{
|
||||
if (m_Library.arraySize == 0)
|
||||
return null;
|
||||
var nameHash = SpriteLibraryAsset.GetStringHash(name);
|
||||
var sp = m_Library.GetArrayElementAtIndex(0);
|
||||
for (int i = 0; i < m_Library.arraySize; ++i)
|
||||
{
|
||||
var nameProperty = sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
|
||||
var hash = SpriteLibraryAsset.GetStringHash(nameProperty);
|
||||
if (nameProperty == name || nameHash == hash)
|
||||
return sp;
|
||||
sp.Next(false);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void DrawElement(Rect rect, int index, bool selected, bool focused)
|
||||
{
|
||||
var categorySerializedProperty = m_Library.GetArrayElementAtIndex(index);
|
||||
|
||||
var catRect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
|
||||
var vaRect = new Rect(rect.x, rect.y + m_Style.categoryTextFieldHeight, rect.width, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
var categoryName = categorySerializedProperty.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
|
||||
var fromMain = categorySerializedProperty.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue;
|
||||
using (new EditorGUI.DisabledScope(fromMain))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var oldLabelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = m_Style.categoryLabelWidth;
|
||||
var newCatName = EditorGUI.DelayedTextField(catRect, m_Style.categoryLabel, categoryName);
|
||||
EditorGUIUtility.labelWidth = oldLabelWidth;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
newCatName = newCatName.Trim();
|
||||
if (categoryName != newCatName)
|
||||
{
|
||||
// Check if this nameLabel is already taken
|
||||
if (IsCategoryNameInUsed(newCatName) == null)
|
||||
categorySerializedProperty.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newCatName;
|
||||
else
|
||||
Debug.LogWarning(m_Style.duplicateWarningText.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(m_GridStates.Count <= index)
|
||||
m_GridStates.Add(new SpriteCategoryGridState());
|
||||
|
||||
DrawCategorySpriteListHeader(vaRect, m_Style.newEntryText);
|
||||
vaRect.y += vaRect.height;
|
||||
vaRect.height = m_Style.gridHeight;
|
||||
DrawCategorySpriteList(vaRect, index, categorySerializedProperty);
|
||||
|
||||
HandleSpriteDragAndDropToCategory(vaRect, categorySerializedProperty);
|
||||
}
|
||||
|
||||
void OnAddCallback(ReorderableList list)
|
||||
{
|
||||
AddCategory(m_Style.newCategoryText, true);
|
||||
}
|
||||
|
||||
SerializedProperty AddCategory(string categoryName, bool createNew)
|
||||
{
|
||||
var intendedCategoryName = categoryName;
|
||||
int catNameIncrement = 1;
|
||||
while (true)
|
||||
{
|
||||
var catOverride = IsCategoryNameInUsed(categoryName);
|
||||
if (catOverride != null)
|
||||
{
|
||||
if (!createNew)
|
||||
return catOverride;
|
||||
categoryName = string.Format("{0} {1}", intendedCategoryName, catNameIncrement++);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
var oldSize = m_Library.arraySize;
|
||||
m_Library.arraySize += 1;
|
||||
var sp = m_Library.GetArrayElementAtIndex(oldSize);
|
||||
sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = categoryName;
|
||||
sp.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = false;
|
||||
sp.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries).arraySize = 0;
|
||||
return sp;
|
||||
}
|
||||
|
||||
bool HandleSpriteDragAndDropToCategory(Rect rect, SerializedProperty category)
|
||||
{
|
||||
bool dragAccepted = false;
|
||||
if (rect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
switch (Event.current.type)
|
||||
{
|
||||
case EventType.DragPerform:
|
||||
foreach (var obj in DragAndDrop.objectReferences)
|
||||
{
|
||||
if (obj is Sprite)
|
||||
{
|
||||
AddSpriteToCategory(category, (Sprite)obj);
|
||||
dragAccepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dragAccepted)
|
||||
{
|
||||
DragAndDrop.AcceptDrag();
|
||||
}
|
||||
Event.current.Use();
|
||||
break;
|
||||
case EventType.DragUpdated:
|
||||
if (DragAndDrop.objectReferences.Count(x => x is Sprite) > 0)
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||
else
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
|
||||
Event.current.Use();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dragAccepted;
|
||||
}
|
||||
|
||||
static void GetRowColumnCount(float drawWidth, float size, int contentCount, out int column, out int row, out float columnf)
|
||||
{
|
||||
columnf = (drawWidth) / size;
|
||||
column = (int)Mathf.Floor(columnf);
|
||||
if (column == 0)
|
||||
row = 0;
|
||||
else
|
||||
row = (int)Mathf.Ceil((contentCount + column-1) / column);
|
||||
}
|
||||
|
||||
public void DrawCategorySpriteList(Rect rect, int index, SerializedProperty category)
|
||||
{
|
||||
var spriteListProp = category.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
|
||||
var footerRect = rect;
|
||||
var gridState = m_GridStates[index];
|
||||
gridState.selectedIndex = (gridState.selectedIndex > spriteListProp.arraySize) ? 0 : gridState.selectedIndex;
|
||||
rect.height -= m_Style.gridFooterSize;
|
||||
if(Event.current.type == EventType.Repaint)
|
||||
m_Style.boxBackground.Draw(rect, "", false, false, false, false);
|
||||
|
||||
rect.x += m_Style.gridPadding;
|
||||
rect.y += m_Style.gridPadding;
|
||||
rect.width -= m_Style.gridPadding * 2;
|
||||
rect.height -= m_Style.gridPadding * 2;
|
||||
|
||||
float columnF;
|
||||
int columnCount, rowCount;
|
||||
GetRowColumnCount(rect.width, m_Style.gridSize.x, spriteListProp.arraySize, out columnCount, out rowCount, out columnF);
|
||||
bool canRemoveSelectedEntry = true;
|
||||
bool selectedEntryIsOverwrite = false;
|
||||
|
||||
var overrideCountProperty = category.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount);
|
||||
if (spriteListProp.arraySize <= 0 && overrideCountProperty.intValue != 0)
|
||||
overrideCountProperty.intValue = 0;
|
||||
if (columnCount > 0 && rowCount > 0)
|
||||
{
|
||||
var spriteOverwrite = 0;
|
||||
var scrollViewRect = new Rect(rect.x, rect.y, columnCount * m_Style.gridSize.x,
|
||||
rowCount * m_Style.gridSize.y);
|
||||
if (rowCount >= 2)
|
||||
gridState.scrollPos = GUI.BeginScrollView(new Rect(rect.x, rect.y, rect.width, rect.height),gridState.scrollPos, scrollViewRect, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar);
|
||||
|
||||
var spriteObjectFieldRect = new Rect(rect.x, rect.y, m_Style.spriteGridSize, m_Style.spriteGridSize);
|
||||
var labelTextfieldRect = new Rect(rect.x, rect.y + m_Style.spriteGridSize + m_Style.lineSpacing, m_Style.spriteGridSize, EditorGUIUtility.singleLineHeight);
|
||||
var backgroundSelectedRect = new Rect(rect.x, rect.y, m_Style.gridSize.x, m_Style.gridSize.y);
|
||||
for (int i = 0, row = 0, column = 0; i < spriteListProp.arraySize; ++i, ++column)
|
||||
{
|
||||
var element = spriteListProp.GetArrayElementAtIndex(i);
|
||||
|
||||
var spriteProperty = element.FindPropertyRelative(SpriteLibraryPropertyString.sprite);
|
||||
var spriteOverrideProperty = element.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride);
|
||||
var spriteOverride = spriteProperty.objectReferenceValue != spriteOverrideProperty.objectReferenceValue;
|
||||
var entryFromMain = element.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue;
|
||||
|
||||
if (column >= columnCount)
|
||||
{
|
||||
column = 0;
|
||||
++row;
|
||||
}
|
||||
|
||||
backgroundSelectedRect.x = column * m_Style.gridSize.x + rect.x;
|
||||
backgroundSelectedRect.y = row * m_Style.gridSize.y + rect.y;
|
||||
spriteObjectFieldRect.x = column * m_Style.gridSize.x + rect.x + m_Style.gridPadding;
|
||||
spriteObjectFieldRect.y = row * m_Style.gridSize.y + rect.y + m_Style.gridPadding;
|
||||
labelTextfieldRect.x = column * m_Style.gridSize.x +rect.x + m_Style.gridPadding;
|
||||
labelTextfieldRect.y = row * m_Style.gridSize.y + m_Style.spriteGridSize +rect.y + m_Style.gridPadding;
|
||||
if (gridState.selectedIndex == i)
|
||||
{
|
||||
canRemoveSelectedEntry = entryFromMain && spriteOverride || !entryFromMain;
|
||||
selectedEntryIsOverwrite = entryFromMain && spriteOverride;
|
||||
if(Event.current.type == EventType.Repaint)
|
||||
m_Style.gridList.Draw(backgroundSelectedRect, true, true, true, false);
|
||||
}
|
||||
spriteOverrideProperty.objectReferenceValue = EditorGUI.ObjectField(spriteObjectFieldRect, spriteOverrideProperty.objectReferenceValue, typeof(Sprite), false) as Sprite;
|
||||
if (Event.current.type == EventType.MouseUp &&
|
||||
backgroundSelectedRect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
gridState.selectedIndex = i;
|
||||
}
|
||||
|
||||
if (!entryFromMain || spriteOverride)
|
||||
{
|
||||
var overrideIconRect = spriteObjectFieldRect;
|
||||
overrideIconRect.x -= 12;
|
||||
overrideIconRect.y -= 12;
|
||||
overrideIconRect.width = 20;
|
||||
overrideIconRect.height = 20;
|
||||
GUI.Label(overrideIconRect, m_Style.overrideIcon);
|
||||
++spriteOverwrite;
|
||||
}
|
||||
|
||||
//disable m_Name editing if the entry is from main
|
||||
using (new EditorGUI.DisabledScope(entryFromMain))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var oldName = element.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
|
||||
if (string.IsNullOrEmpty(oldName) && spriteOverrideProperty.objectReferenceValue != null && entryFromMain)
|
||||
{
|
||||
oldName = spriteOverrideProperty.name;
|
||||
element.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = oldName;
|
||||
}
|
||||
var nameRect = labelTextfieldRect;
|
||||
bool nameDuplicate = IsEntryNameUsed(oldName, spriteListProp, 1);
|
||||
if (nameDuplicate)
|
||||
{
|
||||
nameRect.width -= 20;
|
||||
}
|
||||
|
||||
var newName = EditorGUI.DelayedTextField(
|
||||
nameRect,
|
||||
GUIContent.none,
|
||||
oldName);
|
||||
|
||||
if (nameDuplicate)
|
||||
{
|
||||
nameRect.x += nameRect.width;
|
||||
nameRect.width = 20;
|
||||
GUI.Label(nameRect, m_Style.duplicateWarning);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck() && !string.IsNullOrEmpty(newName))
|
||||
{
|
||||
newName = newName.Trim();
|
||||
element.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newName;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (overrideCountProperty.intValue != spriteOverwrite)
|
||||
{
|
||||
overrideCountProperty.intValue = spriteOverwrite;
|
||||
GUI.changed = true;
|
||||
}
|
||||
if (rowCount >= 2)
|
||||
GUI.EndScrollView();
|
||||
}
|
||||
|
||||
|
||||
footerRect = new Rect(footerRect.x, footerRect.y + footerRect.height - m_Style.gridFooterSize, footerRect.width, m_Style.gridFooterSize);
|
||||
|
||||
Action<SerializedProperty , SpriteCategoryGridState> removeCallback = DeleteSpriteEntry;
|
||||
if (selectedEntryIsOverwrite)
|
||||
removeCallback = DeleteSpriteEntryOverride;
|
||||
DrawCategorySpriteListFooter(footerRect, category, gridState,canRemoveSelectedEntry, removeCallback);
|
||||
}
|
||||
|
||||
bool IsEntryNameUsed(string name, SerializedProperty spriteList, int duplicateAllow)
|
||||
{
|
||||
if (spriteList.arraySize == 0)
|
||||
return false;
|
||||
var sp = spriteList.GetArrayElementAtIndex(0);
|
||||
var nameHash = SpriteLibraryAsset.GetStringHash(name);
|
||||
int count = 0;
|
||||
for (int i = 0; i < spriteList.arraySize; ++i, sp.Next(false))
|
||||
{
|
||||
var stringValue = sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
|
||||
var hash = SpriteLibraryAsset.GetStringHash(stringValue);
|
||||
if (stringValue == name || hash == nameHash)
|
||||
{
|
||||
++count;
|
||||
if(count > duplicateAllow)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void DeleteSpriteEntryOverride(SerializedProperty spriteList, SpriteCategoryGridState gridState)
|
||||
{
|
||||
var sp = spriteList.GetArrayElementAtIndex(gridState.selectedIndex);
|
||||
sp.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride).objectReferenceValue = sp.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue;
|
||||
}
|
||||
|
||||
static void DeleteSpriteEntry(SerializedProperty spriteList, SpriteCategoryGridState gridState)
|
||||
{
|
||||
spriteList.DeleteArrayElementAtIndex(gridState.selectedIndex);
|
||||
var count = spriteList.arraySize;
|
||||
gridState.selectedIndex = (gridState.selectedIndex >= count) ? count - 1 : gridState.selectedIndex;
|
||||
}
|
||||
|
||||
void DrawCategorySpriteListHeader(Rect rect, string text)
|
||||
{
|
||||
if (Event.current.type == UnityEngine.EventType.Repaint)
|
||||
m_Style.headerBackground.Draw(rect, false, false, false, false);
|
||||
rect.x += 10;
|
||||
EditorGUI.LabelField(rect, text);
|
||||
}
|
||||
|
||||
void DrawCategorySpriteListFooter(Rect rect, SerializedProperty category, SpriteCategoryGridState gridState, bool canRemove, Action<SerializedProperty, SpriteCategoryGridState> onRemove)
|
||||
{
|
||||
float num = rect.xMax - 10f;
|
||||
float x = num - 8f;
|
||||
x -= 25f;
|
||||
x -= 25f;
|
||||
rect = new Rect(x, rect.y, num - x, rect.height);
|
||||
Rect rect1 = new Rect(x + 4f, rect.y, 25f, 16f);
|
||||
Rect position = new Rect(num - 29f, rect.y, 25f, 16f);
|
||||
|
||||
|
||||
if (Event.current.type == UnityEngine.EventType.Repaint)
|
||||
m_Style.footerBackground.Draw(rect, false, false, false, false);
|
||||
|
||||
if (GUI.Button(rect1, m_Style.iconToolbarPlus, m_Style.preButton))
|
||||
AddSpriteToCategory(category, null);
|
||||
|
||||
var spriteList = category.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
|
||||
using (new EditorGUI.DisabledScope(!canRemove || gridState.selectedIndex < 0 || spriteList.arraySize <= gridState.selectedIndex))
|
||||
{
|
||||
if (GUI.Button(position, m_Style.iconToolbarMinus, m_Style.preButton))
|
||||
onRemove(spriteList, gridState);
|
||||
}
|
||||
}
|
||||
|
||||
string GetUniqueEntryName(SerializedProperty list, string name)
|
||||
{
|
||||
var newName = name;
|
||||
var count = 0;
|
||||
while (IsEntryNameUsed(newName, list, 0))
|
||||
{
|
||||
newName = string.Format("{0}_{1}", name, count);
|
||||
++count;
|
||||
}
|
||||
return newName;
|
||||
}
|
||||
|
||||
void AddSpriteToCategory(SerializedProperty category, Sprite sprite)
|
||||
{
|
||||
var name = sprite == null ? m_Style.newEntryText : sprite.name;
|
||||
var spriteList = category.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
|
||||
name = GetUniqueEntryName(spriteList, name);
|
||||
spriteList.arraySize += 1;
|
||||
var sp = spriteList.GetArrayElementAtIndex(spriteList.arraySize - 1);
|
||||
sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = name;
|
||||
sp.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue = sprite;
|
||||
sp.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride).objectReferenceValue = sprite;
|
||||
sp.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = false;
|
||||
}
|
||||
|
||||
bool OnCanRemoveCallback(ReorderableList list)
|
||||
{
|
||||
bool canDelete = true;
|
||||
if (list.index >= 0 && list.index < list.count)
|
||||
{
|
||||
var item = list.serializedProperty.GetArrayElementAtIndex(list.index);
|
||||
canDelete = !item.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue;
|
||||
}
|
||||
|
||||
return canDelete;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,155 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor.AssetImporters;
|
||||
using UnityEngine;
|
||||
using UnityEngine.U2D.Animation;
|
||||
|
||||
namespace UnityEditor.U2D.Animation
|
||||
{
|
||||
/// <summary>
|
||||
/// A ScriptedImporter that imports .spriteLib extension file to generate
|
||||
/// SpriteLibraryAsset
|
||||
/// </summary>
|
||||
[ScriptedImporter(1, "spriteLib")]
|
||||
public class SpriteLibrarySourceAssetImporter : ScriptedImporter
|
||||
{
|
||||
[SerializeField]
|
||||
private SpriteLibraryAsset m_PrimaryLibrary;
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of ScriptedImporter.OnImportAsset
|
||||
/// </summary>
|
||||
/// <param name="ctx">
|
||||
/// This argument contains all the contextual information needed to process the import
|
||||
/// event and is also used by the custom importer to store the resulting Unity Asset.
|
||||
/// </param>
|
||||
public override void OnImportAsset(AssetImportContext ctx)
|
||||
{
|
||||
var spriteLib = ScriptableObject.CreateInstance<SpriteLibraryAsset>();
|
||||
spriteLib.name = System.IO.Path.GetFileNameWithoutExtension(assetPath);
|
||||
var sourceAsset = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(assetPath);
|
||||
if (sourceAsset?.Length > 0)
|
||||
{
|
||||
var sourceLibraryAsset = sourceAsset[0] as SpriteLibrarySourceAsset;
|
||||
if (sourceLibraryAsset != null)
|
||||
{
|
||||
foreach (var cat in sourceLibraryAsset.library)
|
||||
{
|
||||
spriteLib.AddCategoryLabel(null, cat.name, null);
|
||||
foreach (var entry in cat.overrideEntries)
|
||||
{
|
||||
spriteLib.AddCategoryLabel(entry.spriteOverride, cat.name, entry.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(sourceLibraryAsset.primaryLibraryID))
|
||||
{
|
||||
var primaryAssetPath = AssetDatabase.GUIDToAssetPath(sourceLibraryAsset.primaryLibraryID);
|
||||
if (primaryAssetPath != assetPath)
|
||||
{
|
||||
ctx.DependsOnArtifact(AssetDatabase.GUIDToAssetPath(sourceLibraryAsset.primaryLibraryID));
|
||||
m_PrimaryLibrary = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(primaryAssetPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.AddObjectToAsset("SpriteLib", spriteLib, IconUtility.LoadIconResource("Sprite Library", "Icons/Light", "Icons/Dark"));
|
||||
}
|
||||
|
||||
internal static SpriteLibrarySourceAsset LoadSpriteLibrarySourceAsset(string path)
|
||||
{
|
||||
var loadedObjects = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(path);
|
||||
foreach (var obj in loadedObjects)
|
||||
{
|
||||
if (obj is SpriteLibrarySourceAsset)
|
||||
return (SpriteLibrarySourceAsset)obj;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static void SaveSpriteLibrarySourceAsset(SpriteLibrarySourceAsset obj, string path)
|
||||
{
|
||||
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new [] {obj}, path, true);
|
||||
}
|
||||
|
||||
[MenuItem("internal:Assets/Convert to SpriteLibrarySourceAsset", true)]
|
||||
static bool ConvertToSpriteLibrarySourceAssetValidate()
|
||||
{
|
||||
foreach (var obj in Selection.objects)
|
||||
{
|
||||
if (obj is SpriteLibraryAsset)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[MenuItem("internal:Assets/Convert to SpriteLibrarySourceAsset")]
|
||||
static void ConvertToSourceAsset()
|
||||
{
|
||||
|
||||
foreach (var obj in Selection.objects)
|
||||
{
|
||||
if (obj is SpriteLibraryAsset)
|
||||
{
|
||||
var asset = (SpriteLibraryAsset) obj;
|
||||
var path = AssetDatabase.GetAssetPath(asset);
|
||||
var currentAssetPath = Path.GetDirectoryName(path);
|
||||
var fileName = Path.GetFileNameWithoutExtension(path);
|
||||
var convertFileName = fileName + ".spriteLib";
|
||||
convertFileName = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(currentAssetPath, convertFileName));
|
||||
var convertAsset = ScriptableObject.CreateInstance<SpriteLibrarySourceAsset>();
|
||||
convertAsset.library = new List<SpriteLibCategoryOverride>(asset.categories.Count);
|
||||
for (int i = 0; i < asset.categories.Count; ++i)
|
||||
{
|
||||
var category = asset.categories[i];
|
||||
var newCategory = new SpriteLibCategoryOverride()
|
||||
{
|
||||
overrideEntries = new List<SpriteCategoryEntryOverride>(category.categoryList.Count),
|
||||
name = category.name,
|
||||
entryOverrideCount = 0,
|
||||
fromMain = false
|
||||
};
|
||||
convertAsset.library.Add(newCategory);
|
||||
for (int j = 0; j < category.categoryList.Count; ++j)
|
||||
{
|
||||
newCategory.overrideEntries.Add(new SpriteCategoryEntryOverride()
|
||||
{
|
||||
name = category.categoryList[j].name,
|
||||
sprite = null,
|
||||
fromMain = false,
|
||||
spriteOverride = category.categoryList[j].sprite
|
||||
});
|
||||
}
|
||||
}
|
||||
SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(convertAsset, convertFileName);
|
||||
}
|
||||
}
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
internal class SpriteLibrarySourceAssetPostProcessor: AssetPostprocessor
|
||||
{
|
||||
void OnPreprocessAsset()
|
||||
{
|
||||
if (assetImporter is SpriteLibrarySourceAssetImporter)
|
||||
{
|
||||
var obj = SpriteLibrarySourceAssetImporter.LoadSpriteLibrarySourceAsset(assetPath);
|
||||
if (obj != null)
|
||||
{
|
||||
SpriteLibraryAsset mainLibraryAsset = null;
|
||||
var mainLibraryAssetAssetPath = AssetDatabase.GUIDToAssetPath(obj.primaryLibraryID);
|
||||
mainLibraryAsset = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(mainLibraryAssetAssetPath);
|
||||
var so = new SerializedObject(obj);
|
||||
var library = so.FindProperty("m_Library");
|
||||
SpriteLibraryDataInspector.UpdateLibraryWithNewMainLibrary(mainLibraryAsset, library);
|
||||
if (so.hasModifiedProperties)
|
||||
{
|
||||
so.ApplyModifiedPropertiesWithoutUndo();
|
||||
SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(obj, assetPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using UnityEditor.AssetImporters;
|
||||
using UnityEngine;
|
||||
using UnityEngine.U2D.Animation;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace UnityEditor.U2D.Animation
|
||||
{
|
||||
[CustomEditor(typeof(SpriteLibrarySourceAssetImporter))]
|
||||
internal class SpriteLibrarySourceAssetImporterInspector : ScriptedImporterEditor
|
||||
{
|
||||
private SerializedProperty m_PrimaryLibraryGUID;
|
||||
private SerializedProperty m_Library;
|
||||
private SpriteLibraryAsset m_MainSpriteLibraryAsset;
|
||||
private SpriteLibraryDataInspector m_SpriteLibraryDataInspector;
|
||||
public override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
m_PrimaryLibraryGUID = extraDataSerializedObject.FindProperty("m_PrimaryLibraryGUID");
|
||||
if (!m_PrimaryLibraryGUID.hasMultipleDifferentValues && !string.IsNullOrEmpty(m_PrimaryLibraryGUID.stringValue))
|
||||
{
|
||||
var assetPath = AssetDatabase.GUIDToAssetPath(m_PrimaryLibraryGUID.stringValue);
|
||||
m_MainSpriteLibraryAsset = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(assetPath);
|
||||
}
|
||||
m_Library = extraDataSerializedObject.FindProperty("m_Library");
|
||||
m_SpriteLibraryDataInspector = new SpriteLibraryDataInspector(extraDataSerializedObject, m_Library);
|
||||
|
||||
}
|
||||
|
||||
protected override Type extraDataType => typeof(SpriteLibrarySourceAsset);
|
||||
|
||||
protected override void InitializeExtraDataInstance(Object extraTarget, int targetIndex)
|
||||
{
|
||||
var obj = SpriteLibrarySourceAssetImporter.LoadSpriteLibrarySourceAsset(((AssetImporter) targets[targetIndex]).assetPath);
|
||||
if (obj != null)
|
||||
{
|
||||
var extraTargetSourceAsset = extraTarget as SpriteLibrarySourceAsset;
|
||||
extraTargetSourceAsset.library = obj.library;
|
||||
extraTargetSourceAsset.primaryLibraryID = obj.primaryLibraryID;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
extraDataSerializedObject.Update();
|
||||
DoMainAssetGUI();
|
||||
DoLibraryGUI();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
extraDataSerializedObject.ApplyModifiedProperties();
|
||||
ApplyRevertGUI();
|
||||
}
|
||||
|
||||
protected override void Apply()
|
||||
{
|
||||
base.Apply();
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
{
|
||||
string path = ((AssetImporter)targets[i]).assetPath;
|
||||
var sourceAsset = (SpriteLibrarySourceAsset) extraDataTargets[i];
|
||||
SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(sourceAsset, path);
|
||||
}
|
||||
}
|
||||
|
||||
void DoMainAssetGUI()
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (m_PrimaryLibraryGUID.hasMultipleDifferentValues)
|
||||
EditorGUI.showMixedValue = true;
|
||||
m_MainSpriteLibraryAsset = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(AssetDatabase.GUIDToAssetPath(m_PrimaryLibraryGUID.stringValue));
|
||||
m_MainSpriteLibraryAsset = EditorGUILayout.ObjectField(Style.mainAssetLabel, m_MainSpriteLibraryAsset, typeof(SpriteLibraryAsset), false) as SpriteLibraryAsset;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
m_PrimaryLibraryGUID.stringValue = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_MainSpriteLibraryAsset));
|
||||
SpriteLibraryDataInspector.UpdateLibraryWithNewMainLibrary(m_MainSpriteLibraryAsset, m_Library);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
EditorGUI.showMixedValue = false;
|
||||
}
|
||||
|
||||
void DoLibraryGUI()
|
||||
{
|
||||
m_SpriteLibraryDataInspector.OnGUI();
|
||||
}
|
||||
|
||||
public override bool showImportedObject
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
static class Style
|
||||
{
|
||||
public static GUIContent mainAssetLabel = new GUIContent("Main Library");
|
||||
}
|
||||
}
|
||||
|
||||
internal class CreateSpriteLibrarySourceAsset : ProjectWindowCallback.EndNameEditAction
|
||||
{
|
||||
public override void Action(int instanceId, string pathName, string resourceFile)
|
||||
{
|
||||
var asset = ScriptableObject.CreateInstance<SpriteLibrarySourceAsset>();
|
||||
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new Object[] { asset }, pathName, true);
|
||||
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Create/2D/Sprite Library Asset", priority = 9)]
|
||||
static private void CreateSpriteLibrarySourceAssetMenu()
|
||||
{
|
||||
var action = ScriptableObject.CreateInstance<CreateSpriteLibrarySourceAsset>();
|
||||
var icon = IconUtility.LoadIconResource("Sprite Library", "Icons/Light", "Icons/Dark");
|
||||
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, action, "SpriteLib.spriteLib", icon, null);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,252 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Scripting.APIUpdating;
|
||||
using UnityEngine.U2D.Animation;
|
||||
|
||||
namespace UnityEditor.U2D.Animation
|
||||
{
|
||||
[CustomEditor(typeof(SpriteResolver))]
|
||||
[MovedFrom("UnityEditor.Experimental.U2D.Animation")]
|
||||
internal class SpriteResolverInspector : Editor
|
||||
{
|
||||
static class Style
|
||||
{
|
||||
public static GUIContent categoryLabel = EditorGUIUtility.TrTextContent("Category");
|
||||
public static GUIContent labelLabel = EditorGUIUtility.TrTextContent("Label");
|
||||
public static GUIContent categoryIsEmptyLabel = EditorGUIUtility.TrTextContent("Category is Empty");
|
||||
public static GUIContent noCategory = EditorGUIUtility.TrTextContent("No Category");
|
||||
public static string[] emptyCategoryDropDownOption = new[] {Style.categoryIsEmptyLabel.text};
|
||||
}
|
||||
|
||||
struct SpriteCategorySelectionList
|
||||
{
|
||||
public string categoryName;
|
||||
public string[] entryNames;
|
||||
public Sprite[] sprites;
|
||||
}
|
||||
|
||||
private SerializedProperty m_SpriteKey;
|
||||
private SerializedProperty m_LabelHash;
|
||||
private SerializedProperty m_CategoryHash;
|
||||
private SpriteSkin m_SpriteSkin;
|
||||
Dictionary<string, SpriteCategorySelectionList> m_SpriteLibSelection = new Dictionary<string, SpriteCategorySelectionList>();
|
||||
string[] m_CategorySelection;
|
||||
int m_CategorySelectionIndex = 0;
|
||||
int m_LabelSelectionIndex = 0;
|
||||
private string m_PreviousCategoryValue;
|
||||
private string m_PreviousLabelValue;
|
||||
private bool m_IgnoreNextDeserializeCallback;
|
||||
private bool m_ReInitOnNextGUI;
|
||||
SpriteSelectorWidget m_SpriteSelectorWidget = new SpriteSelectorWidget();
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
m_SpriteKey = serializedObject.FindProperty("m_SpriteKey");
|
||||
m_LabelHash = serializedObject.FindProperty("m_labelHash");
|
||||
m_CategoryHash = serializedObject.FindProperty("m_CategoryHash");
|
||||
m_SpriteSkin = (target as SpriteResolver).GetComponent<SpriteSkin>();
|
||||
UpdateSpriteLibrary();
|
||||
spriteResolver.onDeserializedCallback += SpriteResolverDeserializedCallback;
|
||||
}
|
||||
|
||||
void SpriteResolverDeserializedCallback()
|
||||
{
|
||||
if (!m_IgnoreNextDeserializeCallback)
|
||||
{
|
||||
m_ReInitOnNextGUI = true;
|
||||
}
|
||||
}
|
||||
|
||||
SpriteResolver spriteResolver { get {return target as SpriteResolver; } }
|
||||
|
||||
void GetCategoryAndLabelStringValue(out string categoryName, out string labelName)
|
||||
{
|
||||
categoryName = null;
|
||||
labelName = null;
|
||||
var spriteLib = spriteResolver.spriteLibrary;
|
||||
if (spriteLib != null)
|
||||
{
|
||||
int entryHash = SpriteResolver.ConvertFloatToInt(m_SpriteKey.floatValue);
|
||||
spriteLib.GetCategoryAndEntryNameFromHash(entryHash, out categoryName, out labelName);
|
||||
if (string.IsNullOrEmpty(categoryName) || string.IsNullOrEmpty(labelName))
|
||||
{
|
||||
int labelHash = SpriteResolver.ConvertFloatToInt(m_LabelHash.floatValue);
|
||||
int categoryHash = SpriteResolver.ConvertFloatToInt(m_CategoryHash.floatValue);
|
||||
m_SpriteKey.floatValue = SpriteResolver.ConvertCategoryLabelHashToSpriteKey(spriteLib, categoryHash, labelHash);
|
||||
entryHash = SpriteResolver.ConvertFloatToInt(m_SpriteKey.floatValue);
|
||||
spriteLib.GetCategoryAndEntryNameFromHash(entryHash, out categoryName, out labelName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSpriteLibrary()
|
||||
{
|
||||
m_SpriteLibSelection.Clear();
|
||||
|
||||
var spriteLib = spriteResolver.spriteLibrary;
|
||||
string categoryName ="", labelName ="";
|
||||
if (spriteLib != null)
|
||||
{
|
||||
GetCategoryAndLabelStringValue(out categoryName, out labelName);
|
||||
var enumerator = spriteLib.categoryNames;
|
||||
foreach(var category in spriteLib.categoryNames)
|
||||
{
|
||||
if (!m_SpriteLibSelection.ContainsKey(category))
|
||||
{
|
||||
var entries = spriteLib.GetEntryNames(category);
|
||||
if (entries == null)
|
||||
entries = new string[0];
|
||||
|
||||
var selectionList = new SpriteCategorySelectionList()
|
||||
{
|
||||
entryNames = entries.ToArray(),
|
||||
sprites = entries.Select(x =>
|
||||
{
|
||||
return spriteLib.GetSprite(category, x);
|
||||
}).ToArray(),
|
||||
categoryName = category,
|
||||
};
|
||||
|
||||
m_SpriteLibSelection.Add(category, selectionList);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
m_CategorySelection = new string[1 + m_SpriteLibSelection.Keys.Count];
|
||||
m_CategorySelection[0] = Style.noCategory.text;
|
||||
for (int i = 0; i < m_SpriteLibSelection.Keys.Count; ++i)
|
||||
{
|
||||
var selection = m_SpriteLibSelection[m_SpriteLibSelection.Keys.ElementAt(i)];
|
||||
m_CategorySelection[i + 1] = selection.categoryName;
|
||||
if (selection.categoryName == categoryName)
|
||||
m_CategorySelectionIndex = i + 1;
|
||||
}
|
||||
ValidateCategorySelectionIndexValue();
|
||||
if (m_CategorySelectionIndex > 0)
|
||||
{
|
||||
categoryName = m_CategorySelection[m_CategorySelectionIndex];
|
||||
m_SpriteSelectorWidget.UpdateContents(
|
||||
m_SpriteLibSelection[m_CategorySelection[m_CategorySelectionIndex]].sprites);
|
||||
if (m_SpriteLibSelection.ContainsKey(categoryName))
|
||||
{
|
||||
m_LabelSelectionIndex = Array.FindIndex(m_SpriteLibSelection[categoryName].entryNames,
|
||||
x => x == labelName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SpriteSelectorWidget.UpdateContents(new Sprite[0]);
|
||||
}
|
||||
spriteResolver.spriteLibChanged = false;
|
||||
}
|
||||
|
||||
void ValidateCategorySelectionIndexValue()
|
||||
{
|
||||
if (m_CategorySelectionIndex < 0 || m_CategorySelection.Length <= m_CategorySelectionIndex)
|
||||
m_CategorySelectionIndex = 0;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
if (m_ReInitOnNextGUI)
|
||||
{
|
||||
m_ReInitOnNextGUI = false;
|
||||
UpdateSpriteLibrary();
|
||||
}
|
||||
|
||||
if (spriteResolver.spriteLibChanged)
|
||||
UpdateSpriteLibrary();
|
||||
|
||||
var currentLabelValue = "";
|
||||
var currentCategoryValue = "";
|
||||
GetCategoryAndLabelStringValue(out currentCategoryValue, out currentLabelValue);
|
||||
var catIndex = Array.FindIndex(m_CategorySelection, x => x == currentCategoryValue);
|
||||
if(catIndex >= 0)
|
||||
m_CategorySelectionIndex = catIndex;
|
||||
ValidateCategorySelectionIndexValue();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
using (new EditorGUI.DisabledScope(m_CategorySelection.Length <= 1))
|
||||
m_CategorySelectionIndex = EditorGUILayout.Popup(Style.categoryLabel, m_CategorySelectionIndex, m_CategorySelection);
|
||||
|
||||
SpriteCategorySelectionList selection;
|
||||
m_SpriteLibSelection.TryGetValue(m_CategorySelection[m_CategorySelectionIndex], out selection);
|
||||
|
||||
string[] entryNames = Style.emptyCategoryDropDownOption;
|
||||
if (selection.entryNames != null)
|
||||
entryNames = selection.entryNames;
|
||||
if (m_LabelSelectionIndex < 0 || m_LabelSelectionIndex >= entryNames.Length)
|
||||
m_LabelSelectionIndex = 0;
|
||||
using (new EditorGUI.DisabledScope(m_CategorySelectionIndex == 0 || entryNames.Length == 0))
|
||||
{
|
||||
if (entryNames.Length == 0)
|
||||
{
|
||||
m_LabelSelectionIndex = EditorGUILayout.Popup(Style.labelLabel, 0, new [] {Style.categoryIsEmptyLabel});
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LabelSelectionIndex = EditorGUILayout.Popup(Style.labelLabel, m_LabelSelectionIndex, entryNames);
|
||||
}
|
||||
}
|
||||
|
||||
m_LabelSelectionIndex = m_SpriteSelectorWidget.ShowGUI(m_LabelSelectionIndex);
|
||||
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
currentCategoryValue = m_CategorySelection[m_CategorySelectionIndex];
|
||||
if (m_SpriteLibSelection.ContainsKey(currentCategoryValue))
|
||||
{
|
||||
var hash = m_SpriteLibSelection[currentCategoryValue].entryNames;
|
||||
if (hash.Length > 0)
|
||||
{
|
||||
if (m_LabelSelectionIndex < 0 || m_LabelSelectionIndex >= hash.Length)
|
||||
m_LabelSelectionIndex = 0;
|
||||
currentLabelValue = m_SpriteLibSelection[currentCategoryValue].entryNames[m_LabelSelectionIndex];
|
||||
}
|
||||
}
|
||||
|
||||
m_SpriteKey.floatValue = SpriteResolver.ConvertIntToFloat(SpriteLibrary.GetHashForCategoryAndEntry(currentCategoryValue, currentLabelValue));
|
||||
ApplyModifiedProperty();
|
||||
|
||||
var sf = target as SpriteResolver;
|
||||
if (m_SpriteSkin != null)
|
||||
m_SpriteSkin.ignoreNextSpriteChange = true;
|
||||
sf.ResolveSpriteToSpriteRenderer();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(currentCategoryValue) && m_PreviousCategoryValue != currentCategoryValue)
|
||||
{
|
||||
if (m_SpriteLibSelection.ContainsKey(currentCategoryValue))
|
||||
{
|
||||
m_SpriteSelectorWidget.UpdateContents(m_SpriteLibSelection[currentCategoryValue].sprites);
|
||||
}
|
||||
else
|
||||
m_SpriteSelectorWidget.UpdateContents(new Sprite[0]);
|
||||
m_PreviousCategoryValue = currentCategoryValue;
|
||||
this.Repaint();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(currentLabelValue) && m_PreviousLabelValue != currentLabelValue)
|
||||
{
|
||||
if (m_SpriteLibSelection.ContainsKey(currentCategoryValue))
|
||||
m_LabelSelectionIndex = Array.FindIndex(m_SpriteLibSelection[currentCategoryValue].entryNames, x => x == currentLabelValue);
|
||||
m_PreviousLabelValue = currentLabelValue;
|
||||
}
|
||||
|
||||
ApplyModifiedProperty();
|
||||
if (m_SpriteSelectorWidget.NeedUpdatePreview())
|
||||
this.Repaint();
|
||||
}
|
||||
|
||||
void ApplyModifiedProperty()
|
||||
{
|
||||
m_IgnoreNextDeserializeCallback = true;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
m_IgnoreNextDeserializeCallback = false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.U2D.Animation
|
||||
{
|
||||
internal class SpriteSelectorWidget
|
||||
{
|
||||
class Styles
|
||||
{
|
||||
public GUIStyle gridListStyle;
|
||||
|
||||
public Styles()
|
||||
{
|
||||
gridListStyle = new GUIStyle("GridList");
|
||||
gridListStyle.alignment = GUI.skin.button.alignment;
|
||||
}
|
||||
}
|
||||
|
||||
Sprite[] m_SpriteList = new Sprite[0];
|
||||
Texture2D[] m_SpritePreviews = new Texture2D[0];
|
||||
List<int> m_SpritePreviewNeedFetching = new List<int>();
|
||||
Vector2 m_ScrollPos;
|
||||
Styles m_Style;
|
||||
const int kTargetPreviewSize = 64;
|
||||
public SpriteSelectorWidget()
|
||||
{}
|
||||
|
||||
public void UpdateContents(Sprite[] sprites)
|
||||
{
|
||||
m_SpriteList = sprites;
|
||||
m_SpritePreviews = new Texture2D[sprites.Length];
|
||||
for (int i = 0; i < m_SpritePreviews.Length; ++i)
|
||||
m_SpritePreviewNeedFetching.Add(i);
|
||||
UpdateSpritePreviews();
|
||||
}
|
||||
|
||||
|
||||
public int ShowGUI(int selectedIndex)
|
||||
{
|
||||
if (m_Style == null)
|
||||
m_Style = new Styles();
|
||||
|
||||
UpdateSpritePreviews();
|
||||
|
||||
var drawRect = EditorGUILayout.GetControlRect(false, kTargetPreviewSize + 10f, new[] {GUILayout.ExpandWidth(true)});
|
||||
if(Event.current.type == EventType.Repaint)
|
||||
GUI.skin.box.Draw(drawRect, false, false, false, false);
|
||||
if (m_SpriteList == null || m_SpriteList.Length == 0)
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
selectedIndex = (selectedIndex > m_SpriteList.Length) ? 0 : selectedIndex;
|
||||
|
||||
float columnF;
|
||||
int columnCount, rowCount;
|
||||
GetRowColumnCount(drawRect.width - 20, kTargetPreviewSize, m_SpriteList.Length, out columnCount, out rowCount, out columnF);
|
||||
if (columnCount > 0 && rowCount > 0)
|
||||
{
|
||||
float contentSize = (columnF * kTargetPreviewSize) / columnCount;
|
||||
var gridRect = new Rect(drawRect.x, drawRect.y, drawRect.width - 20, rowCount * contentSize);
|
||||
m_ScrollPos = GUI.BeginScrollView(drawRect,m_ScrollPos, gridRect, false, false, GUIStyle.none, GUI.skin.verticalScrollbar);
|
||||
|
||||
m_Style.gridListStyle.fixedWidth = contentSize;
|
||||
m_Style.gridListStyle.fixedHeight = contentSize;
|
||||
selectedIndex = GUI.SelectionGrid( gridRect, selectedIndex, m_SpritePreviews, columnCount, m_Style.gridListStyle);
|
||||
GUI.EndScrollView();
|
||||
}
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
static void GetRowColumnCount(float drawWidth, int size, int contentCount, out int column, out int row, out float columnf)
|
||||
{
|
||||
columnf = drawWidth / size;
|
||||
column = (int)Mathf.Floor(columnf);
|
||||
if (column == 0)
|
||||
row = 0;
|
||||
else
|
||||
row = (int)Mathf.Ceil((contentCount + column) / column);
|
||||
}
|
||||
|
||||
public bool NeedUpdatePreview()
|
||||
{
|
||||
return m_SpritePreviewNeedFetching.Count > 0;
|
||||
}
|
||||
|
||||
void UpdateSpritePreviews()
|
||||
{
|
||||
for (int i = 0; i < m_SpritePreviewNeedFetching.Count; ++i)
|
||||
{
|
||||
var index = m_SpritePreviewNeedFetching[i];
|
||||
if(m_SpriteList[index] == null)
|
||||
m_SpritePreviews[index] = EditorGUIUtility.Load("icons/console.warnicon.png") as Texture2D;
|
||||
else
|
||||
m_SpritePreviews[index] = AssetPreview.GetAssetPreview(m_SpriteList[index]);
|
||||
if (m_SpritePreviews[index] != null)
|
||||
{
|
||||
m_SpritePreviewNeedFetching.RemoveAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user