SpriteLibraryAssetInspector.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. using UnityEditor.U2D.Animation;
  2. using UnityEditorInternal;
  3. using UnityEngine;
  4. using UnityEngine.Experimental.U2D.Animation;
  5. namespace UnityEditor.Experimental.U2D.Animation
  6. {
  7. [CustomEditor(typeof(SpriteLibraryAsset))]
  8. internal class SpriteLibraryAssetInspector : Editor
  9. {
  10. static class Style
  11. {
  12. public static GUIContent duplicateWarningText = EditorGUIUtility.TrTextContent("Duplicate name found or name hash clashes. Please use a different name");
  13. public static GUIContent duplicateWarning = EditorGUIUtility.TrIconContent("console.warnicon.sml", duplicateWarningText.text);
  14. public static GUIContent nameLabel = new GUIContent(TextContent.label);
  15. public static string categoryListLabel = L10n.Tr("Category List");
  16. public static int lineSpacing = 3;
  17. }
  18. private SerializedProperty m_Labels;
  19. private ReorderableList m_LabelReorderableList;
  20. private bool m_UpdateHash = false;
  21. private readonly float kElementHeight = EditorGUIUtility.singleLineHeight * 3;
  22. public void OnEnable()
  23. {
  24. m_Labels = serializedObject.FindProperty("m_Labels");
  25. m_LabelReorderableList = new ReorderableList(serializedObject, m_Labels, true, false, true, true);
  26. SetupOrderList();
  27. }
  28. public void OnDisable()
  29. {
  30. var sla = target as SpriteLibraryAsset;
  31. if (sla != null)
  32. sla.UpdateHashes();
  33. }
  34. float GetElementHeight(int index)
  35. {
  36. var property = m_Labels.GetArrayElementAtIndex(index);
  37. var spriteListProp = property.FindPropertyRelative("m_CategoryList");
  38. if (spriteListProp.isExpanded)
  39. return (spriteListProp.arraySize + 1) * (EditorGUIUtility.singleLineHeight + Style.lineSpacing) + kElementHeight;
  40. return kElementHeight;
  41. }
  42. void DrawElement(Rect rect, int index, bool selected, bool focused)
  43. {
  44. var property = m_Labels.GetArrayElementAtIndex(index);
  45. var catRect = new Rect(rect.x, rect.y, rect.width - kElementHeight, EditorGUIUtility.singleLineHeight);
  46. var vaRect = new Rect(rect.x, rect.y + EditorGUIUtility.singleLineHeight, rect.width - kElementHeight, EditorGUIUtility.singleLineHeight);
  47. var categoryProp = property.FindPropertyRelative("m_Name");
  48. var spriteListProp = property.FindPropertyRelative("m_CategoryList");
  49. EditorGUI.BeginChangeCheck();
  50. var newCatName = EditorGUI.DelayedTextField(catRect, categoryProp.stringValue);
  51. if (EditorGUI.EndChangeCheck())
  52. {
  53. newCatName = newCatName.Trim();
  54. m_UpdateHash = true;
  55. if (categoryProp.stringValue != newCatName)
  56. {
  57. // Check if this nameLabel is already taken
  58. if (!IsNameInUsed(newCatName, m_Labels, "m_Name", 0))
  59. categoryProp.stringValue = newCatName;
  60. else
  61. Debug.LogWarning(Style.duplicateWarningText.text);
  62. }
  63. }
  64. spriteListProp.isExpanded = EditorGUI.Foldout(vaRect, spriteListProp.isExpanded, Style.categoryListLabel, true);
  65. if (spriteListProp.isExpanded)
  66. {
  67. EditorGUI.indentLevel++;
  68. var indentedRect = EditorGUI.IndentedRect(vaRect);
  69. var labelWidth = EditorGUIUtility.labelWidth;
  70. EditorGUIUtility.labelWidth = 40 + indentedRect.x - vaRect.x;
  71. indentedRect.y += EditorGUIUtility.singleLineHeight + Style.lineSpacing;
  72. var sizeRect = indentedRect;
  73. int size = EditorGUI.IntField(sizeRect, TextContent.size, spriteListProp.arraySize);
  74. if (size != spriteListProp.arraySize && size >= 0)
  75. spriteListProp.arraySize = size;
  76. indentedRect.y += EditorGUIUtility.singleLineHeight + Style.lineSpacing;
  77. DrawSpriteListProperty(indentedRect, spriteListProp);
  78. EditorGUIUtility.labelWidth = labelWidth;
  79. EditorGUI.indentLevel--;
  80. }
  81. }
  82. void DrawSpriteListProperty(Rect rect, SerializedProperty spriteListProp)
  83. {
  84. for (int i = 0; i < spriteListProp.arraySize; ++i)
  85. {
  86. var element = spriteListProp.GetArrayElementAtIndex(i);
  87. EditorGUI.BeginChangeCheck();
  88. var oldName = element.FindPropertyRelative("m_Name").stringValue;
  89. var nameRect = new Rect(rect.x, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight);
  90. bool nameDuplicate = IsNameInUsed(oldName, spriteListProp, "m_Name", 1);
  91. if (nameDuplicate)
  92. {
  93. nameRect.width -= 20;
  94. }
  95. var newName = EditorGUI.DelayedTextField(
  96. nameRect,
  97. Style.nameLabel,
  98. oldName);
  99. if (nameDuplicate)
  100. {
  101. nameRect.x += nameRect.width;
  102. nameRect.width = 20;
  103. GUI.Label(nameRect, Style.duplicateWarning);
  104. }
  105. if (EditorGUI.EndChangeCheck())
  106. {
  107. newName = newName.Trim();
  108. element.FindPropertyRelative("m_Name").stringValue = newName;
  109. }
  110. EditorGUI.PropertyField(new Rect(rect.x + rect.width / 2 + 5, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight),
  111. element.FindPropertyRelative("m_Sprite"));
  112. rect.y += EditorGUIUtility.singleLineHeight + Style.lineSpacing;
  113. }
  114. }
  115. public override void OnInspectorGUI()
  116. {
  117. serializedObject.Update();
  118. EditorGUI.BeginChangeCheck();
  119. if (EditorGUI.EndChangeCheck())
  120. SetupOrderList();
  121. m_UpdateHash = false;
  122. m_LabelReorderableList.DoLayoutList();
  123. serializedObject.ApplyModifiedProperties();
  124. if (m_UpdateHash)
  125. (target as SpriteLibraryAsset).UpdateHashes();
  126. }
  127. bool IsNameInUsed(string name, SerializedProperty property, string propertyField, int threshold)
  128. {
  129. int count = 0;
  130. var nameHash = SpriteLibraryAsset.GetStringHash(name);
  131. for (int i = 0; i < property.arraySize; ++i)
  132. {
  133. var sp = property.GetArrayElementAtIndex(i);
  134. var otherName = sp.FindPropertyRelative(propertyField).stringValue;
  135. var otherNameHash = SpriteLibraryAsset.GetStringHash(otherName);
  136. if (otherName == name || nameHash == otherNameHash)
  137. {
  138. count++;
  139. if (count > threshold)
  140. return true;
  141. }
  142. }
  143. return false;
  144. }
  145. void OnAddCallback(ReorderableList list)
  146. {
  147. var oldSize = m_Labels.arraySize;
  148. m_Labels.arraySize += 1;
  149. const string kNewCatName = "New Category";
  150. string newCatName = kNewCatName;
  151. int catNameIncrement = 1;
  152. while (true)
  153. {
  154. if (IsNameInUsed(newCatName, m_Labels, "m_Name", 0))
  155. newCatName = string.Format("{0} {1}", kNewCatName, catNameIncrement++);
  156. else
  157. break;
  158. }
  159. var sp = m_Labels.GetArrayElementAtIndex(oldSize);
  160. sp.FindPropertyRelative("m_Name").stringValue = newCatName;
  161. sp.FindPropertyRelative("m_Hash").intValue = SpriteLibraryAsset.GetStringHash(newCatName);
  162. }
  163. private void SetupOrderList()
  164. {
  165. m_LabelReorderableList.drawElementCallback = DrawElement;
  166. m_LabelReorderableList.elementHeight = kElementHeight;
  167. m_LabelReorderableList.elementHeightCallback = GetElementHeight;
  168. m_LabelReorderableList.onAddCallback = OnAddCallback;
  169. }
  170. }
  171. }