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