No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SpriteSecondaryTexturesModule.cs 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor.U2D.Sprites;
  5. using UnityEditorInternal;
  6. using UnityEngine;
  7. using UnityEngine.UIElements;
  8. namespace UnityEditor._2D.Sprite.Editor
  9. {
  10. [RequireSpriteDataProvider(typeof(ISecondaryTextureDataProvider), typeof(ITextureDataProvider))]
  11. internal class SpriteSecondaryTexturesModule : SpriteEditorModuleBase
  12. {
  13. private static class Styles
  14. {
  15. public static readonly string invalidEntriesWarning = L10n.Tr("Invalid secondary Texture entries (without names or Textures) have been removed.");
  16. public static readonly string invalidSourcesWarning = L10n.Tr("Source texture used as secondary Texture. This is invalid and removed.");
  17. public static readonly string nameUniquenessWarning = L10n.Tr("Every secondary Texture attached to the Sprite must have a unique name.");
  18. public static readonly string builtInNameCollisionWarning = L10n.Tr("The names _MainTex and _AlphaTex are reserved for internal use.");
  19. public static readonly GUIContent panelTitle = EditorGUIUtility.TrTextContent("Secondary Textures");
  20. public static readonly GUIContent name = EditorGUIUtility.TrTextContent("Name");
  21. public static readonly GUIContent texture = EditorGUIUtility.TrTextContent("Texture");
  22. public const float textFieldDropDownWidth = 18.0f;
  23. }
  24. ReorderableList m_ReorderableList;
  25. Vector2 m_ReorderableListScrollPosition;
  26. string[] m_SuggestedNames;
  27. private IMGUIContainer m_SecondaryTextureInspectorContainer;
  28. internal List<SecondarySpriteTexture> secondaryTextureList { get; private set; }
  29. public override string moduleName
  30. {
  31. get { return Styles.panelTitle.text; }
  32. }
  33. public override bool ApplyRevert(bool apply)
  34. {
  35. if (apply)
  36. {
  37. var spriteAssetPath = "";
  38. var secondaryTextureDataProvider = spriteEditor.GetDataProvider<ISecondaryTextureDataProvider>();
  39. var spriteDataProvider = spriteEditor.GetDataProvider<ISpriteEditorDataProvider>();
  40. if (spriteDataProvider != null)
  41. {
  42. var assetImporter = spriteDataProvider.targetObject as AssetImporter;
  43. spriteAssetPath = assetImporter != null ? assetImporter.assetPath : spriteAssetPath;
  44. }
  45. // Remove invalid entries.
  46. var validEntries = secondaryTextureList.FindAll(x => (x.name != null && x.name != "" && x.texture != null));
  47. if (validEntries.Count < secondaryTextureList.Count)
  48. Debug.Log(Styles.invalidEntriesWarning);
  49. // Remove entries with Sprite's source as secondary textures.
  50. var finalEntries = validEntries.FindAll(x => (AssetDatabase.GetAssetPath(x.texture) != spriteAssetPath));
  51. if (finalEntries.Count < validEntries.Count)
  52. Debug.Log(Styles.invalidSourcesWarning);
  53. secondaryTextureDataProvider.textures = finalEntries.ToArray();
  54. }
  55. return true;
  56. }
  57. public override bool CanBeActivated()
  58. {
  59. var dataProvider = spriteEditor.GetDataProvider<ISpriteEditorDataProvider>();
  60. return dataProvider != null && dataProvider.spriteImportMode != SpriteImportMode.None;
  61. }
  62. public override void DoPostGUI()
  63. {
  64. }
  65. public void SecondaryTextureReorderableListUI()
  66. {
  67. using (new EditorGUI.DisabledScope(spriteEditor.editingDisabled))
  68. {
  69. var windowDimension = spriteEditor.windowDimension;
  70. GUILayout.BeginArea(new Rect(0, 0, 290, 290), Styles.panelTitle, GUI.skin.window);
  71. m_ReorderableListScrollPosition = GUILayout.BeginScrollView(m_ReorderableListScrollPosition);
  72. m_ReorderableList.DoLayoutList();
  73. GUILayout.EndScrollView();
  74. GUILayout.EndArea();
  75. // Deselect the list item if left click outside the panel area.
  76. UnityEngine.Event e = UnityEngine.Event.current;
  77. if (e.type == EventType.MouseDown && e.button == 0)
  78. {
  79. m_ReorderableList.index = -1;
  80. OnSelectCallback(m_ReorderableList);
  81. spriteEditor.RequestRepaint();
  82. }
  83. }
  84. }
  85. public override void DoMainGUI()
  86. {
  87. }
  88. public override void DoToolbarGUI(Rect drawArea)
  89. {
  90. }
  91. public override void OnModuleActivate()
  92. {
  93. var secondaryTextureDataProvider = spriteEditor.GetDataProvider<ISecondaryTextureDataProvider>();
  94. secondaryTextureList = secondaryTextureDataProvider.textures == null ? new List<SecondarySpriteTexture>() : secondaryTextureDataProvider.textures.ToList();
  95. m_ReorderableListScrollPosition = Vector2.zero;
  96. m_ReorderableList = new ReorderableList(secondaryTextureList, typeof(SecondarySpriteTexture), false, false, true, true);
  97. m_ReorderableList.drawElementCallback = DrawSpriteSecondaryTextureElement;
  98. m_ReorderableList.onAddCallback = AddSpriteSecondaryTextureElement;
  99. m_ReorderableList.onRemoveCallback = RemoveSpriteSecondaryTextureElement;
  100. m_ReorderableList.onCanAddCallback = CanAddSpriteSecondaryTextureElement;
  101. m_ReorderableList.elementHeightCallback = (int index) => (EditorGUIUtility.singleLineHeight * 3) + 5;
  102. m_ReorderableList.onSelectCallback = OnSelectCallback;
  103. spriteEditor.selectedSpriteRect = null;
  104. string suggestedNamesPrefs = EditorPrefs.GetString("SecondarySpriteTexturePropertyNames");
  105. if (!string.IsNullOrEmpty(suggestedNamesPrefs))
  106. {
  107. m_SuggestedNames = suggestedNamesPrefs.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  108. for (int i = 0; i < m_SuggestedNames.Length; ++i)
  109. m_SuggestedNames[i] = m_SuggestedNames[i].Trim();
  110. Array.Sort(m_SuggestedNames);
  111. }
  112. else
  113. m_SuggestedNames = null;
  114. m_SecondaryTextureInspectorContainer = new IMGUIContainer(SecondaryTextureReorderableListUI)
  115. {
  116. style =
  117. {
  118. flexGrow = 0,
  119. flexBasis = 1,
  120. flexShrink = 0,
  121. minWidth = 290,
  122. minHeight = 290,
  123. bottom = 24,
  124. right = 24,
  125. position = new StyleEnum<Position>(Position.Absolute)
  126. },
  127. name = "SecondaryTextureInspector"
  128. };
  129. spriteEditor.GetMainVisualContainer().Add(m_SecondaryTextureInspectorContainer);
  130. }
  131. void OnSelectCallback(ReorderableList list)
  132. {
  133. // Preview the current selected secondary texture.
  134. Texture2D previewTexture = null;
  135. int width = 0, height = 0;
  136. var textureDataProvider = spriteEditor.GetDataProvider<ITextureDataProvider>();
  137. if (textureDataProvider != null)
  138. {
  139. previewTexture = textureDataProvider.previewTexture;
  140. textureDataProvider.GetTextureActualWidthAndHeight(out width, out height);
  141. }
  142. if (m_ReorderableList.index >= 0 && m_ReorderableList.index < secondaryTextureList.Count)
  143. previewTexture = secondaryTextureList[m_ReorderableList.index].texture;
  144. if (previewTexture != null)
  145. spriteEditor.SetPreviewTexture(previewTexture, width, height);
  146. }
  147. public override void OnModuleDeactivate()
  148. {
  149. DisplayMainTexture();
  150. if (spriteEditor.GetMainVisualContainer().Contains(m_SecondaryTextureInspectorContainer))
  151. spriteEditor.GetMainVisualContainer().Remove(m_SecondaryTextureInspectorContainer);
  152. }
  153. void DrawSpriteSecondaryTextureElement(Rect rect, int index, bool isActive, bool isFocused)
  154. {
  155. bool dataModified = false;
  156. float oldLabelWidth = EditorGUIUtility.labelWidth;
  157. EditorGUIUtility.labelWidth = 70.0f;
  158. SecondarySpriteTexture secondaryTexture = secondaryTextureList[index];
  159. // "Name" text field
  160. EditorGUI.BeginChangeCheck();
  161. var r = new Rect(rect.x, rect.y + 5, rect.width - Styles.textFieldDropDownWidth, EditorGUIUtility.singleLineHeight);
  162. string newName = EditorGUI.TextField(r, Styles.name, secondaryTexture.name);
  163. dataModified = EditorGUI.EndChangeCheck();
  164. // Suggested names
  165. if (m_SuggestedNames != null)
  166. {
  167. var popupRect = new Rect(r.x + r.width, r.y, Styles.textFieldDropDownWidth, EditorGUIUtility.singleLineHeight);
  168. EditorGUI.BeginChangeCheck();
  169. int selected = EditorGUI.Popup(popupRect, -1, m_SuggestedNames, EditorStyles.textFieldDropDown);
  170. if (EditorGUI.EndChangeCheck())
  171. {
  172. newName = m_SuggestedNames[selected];
  173. dataModified = true;
  174. }
  175. }
  176. if (dataModified)
  177. {
  178. if (!string.IsNullOrEmpty(newName) && newName != secondaryTexture.name && secondaryTextureList.Exists(x => x.name == newName))
  179. Debug.LogWarning(Styles.nameUniquenessWarning);
  180. else if (newName == "_MainTex" || newName == "_AlphaTex")
  181. Debug.LogWarning(Styles.builtInNameCollisionWarning);
  182. else
  183. secondaryTexture.name = newName;
  184. }
  185. // "Texture" object field
  186. EditorGUI.BeginChangeCheck();
  187. r.width = rect.width;
  188. r.y += EditorGUIUtility.singleLineHeight + 2.0f;
  189. secondaryTexture.texture = EditorGUI.ObjectField(r, Styles.texture, secondaryTexture.texture, typeof(Texture2D), false) as Texture2D;
  190. dataModified = dataModified || EditorGUI.EndChangeCheck();
  191. if (dataModified)
  192. {
  193. secondaryTextureList[index] = secondaryTexture;
  194. spriteEditor.SetDataModified();
  195. }
  196. EditorGUIUtility.labelWidth = oldLabelWidth;
  197. }
  198. void AddSpriteSecondaryTextureElement(ReorderableList list)
  199. {
  200. m_ReorderableListScrollPosition += new Vector2(0.0f, list.elementHeightCallback(0));
  201. secondaryTextureList.Add(new SecondarySpriteTexture());
  202. spriteEditor.SetDataModified();
  203. }
  204. void RemoveSpriteSecondaryTextureElement(ReorderableList list)
  205. {
  206. DisplayMainTexture();
  207. secondaryTextureList.RemoveAt(list.index);
  208. spriteEditor.SetDataModified();
  209. }
  210. bool CanAddSpriteSecondaryTextureElement(ReorderableList list)
  211. {
  212. return list.count < 8;
  213. }
  214. void DisplayMainTexture()
  215. {
  216. ITextureDataProvider textureDataProvider = spriteEditor.GetDataProvider<ITextureDataProvider>();
  217. if (textureDataProvider != null && textureDataProvider.previewTexture != null)
  218. {
  219. Texture2D mainTexture = textureDataProvider.previewTexture;
  220. int width = 0, height = 0;
  221. textureDataProvider.GetTextureActualWidthAndHeight(out width, out height);
  222. spriteEditor.SetPreviewTexture(mainTexture, width, height);
  223. }
  224. }
  225. }
  226. }