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 11KB

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