Nessuna descrizione
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.

TilemapEditorToolPreferences.cs 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using UnityEditor.EditorTools;
  5. using UnityEditorInternal;
  6. using UnityEngine;
  7. using Object = UnityEngine.Object;
  8. namespace UnityEditor.Tilemaps
  9. {
  10. internal class TilemapEditorToolPreferences : ScriptableSingleton<TilemapEditorToolPreferences>
  11. {
  12. private static readonly string s_LibraryFolderPath = "Library/GridBrush";
  13. private static readonly string s_AssetPath = FileUtil.CombinePaths(s_LibraryFolderPath, "TilemapEditorToolPreferences.asset");
  14. internal class TilemapEditorToolProperties
  15. {
  16. public static readonly string defaultToolsEditorPref = "TilemapEditorTool.DefaultTools";
  17. public static readonly GUIContent defaultToolsLabel = EditorGUIUtility.TrTextContent("Default Tile Palette Tools");
  18. public static readonly GUIContent addLabel = EditorGUIUtility.TrTextContent("<<", "Add to Defaults");
  19. public static readonly GUIContent removeLabel = EditorGUIUtility.TrTextContent(">>", "Remove from Defaults");
  20. public static readonly GUIContent saveLabel = EditorGUIUtility.TrTextContent("Save", "Save Defaults");
  21. public static readonly GUIContent revertLabel = EditorGUIUtility.TrTextContent("Revert", "Revert Changes");
  22. public static readonly GUIContent resetLabel = EditorGUIUtility.TrTextContent("Reset", "Reset Defaults");
  23. }
  24. internal static void PreferencesGUI()
  25. {
  26. using (new SettingsWindow.GUIScope())
  27. {
  28. instance.DoPreferencesGUI();
  29. }
  30. }
  31. internal static EditorTool[] CreateDefaultTilePaletteEditorTools()
  32. {
  33. return instance.CreateDefaultTilemapEditorTools();
  34. }
  35. internal static event Action tilemapEditorToolsChanged;
  36. private ReorderableList m_DefaultTypes;
  37. private ReorderableList m_OtherTypes;
  38. private bool m_Changed;
  39. private HashSet<Type> m_AllTilemapEditorToolTypes;
  40. private List<DefaultTilemapEditorTool> m_DefaultTilemapEditorToolTypes;
  41. private List<DefaultTilemapEditorTool> m_OtherTilemapEditorToolTypes;
  42. private static EditorTool[] s_DefaultTilemapEditorTools;
  43. private void OnEnable()
  44. {
  45. m_DefaultTilemapEditorToolTypes = new List<DefaultTilemapEditorTool>();
  46. m_OtherTilemapEditorToolTypes = new List<DefaultTilemapEditorTool>();
  47. LoadDefaultEditorToolTypes();
  48. m_DefaultTypes = new ReorderableList(m_DefaultTilemapEditorToolTypes, typeof(DefaultTilemapEditorTool), true, false, false, false);
  49. m_DefaultTypes.drawElementCallback = OnDrawDefaultElement;
  50. m_DefaultTypes.onReorderCallback = OnReorderDefaultElement;
  51. m_OtherTypes = new ReorderableList(m_OtherTilemapEditorToolTypes, typeof(DefaultTilemapEditorTool), true, false, false, false);
  52. m_OtherTypes.drawElementCallback = OnDrawOtherElement;
  53. m_Changed = false;
  54. }
  55. private void InitializeAllTilemapEditorToolTypes()
  56. {
  57. m_AllTilemapEditorToolTypes = new HashSet<Type>();
  58. foreach (var tilemapEditorToolType in TypeCache.GetTypesDerivedFrom(typeof(TilemapEditorTool)))
  59. {
  60. if (tilemapEditorToolType.IsAbstract)
  61. continue;
  62. m_AllTilemapEditorToolTypes.Add(tilemapEditorToolType);
  63. }
  64. }
  65. private void LoadDefaultEditorToolTypes()
  66. {
  67. InitializeAllTilemapEditorToolTypes();
  68. m_DefaultTilemapEditorToolTypes.Clear();
  69. m_OtherTilemapEditorToolTypes.Clear();
  70. var defaultTools = LoadTilemapEditorToolPreferencesAsset();
  71. if (defaultTools == null || defaultTools.Count == 0)
  72. {
  73. foreach (var type in TilemapEditorTool.s_DefaultToolTypes)
  74. {
  75. m_DefaultTilemapEditorToolTypes.Add(new DefaultTilemapEditorTool { fullTypeName = type.FullName, tilemapEditorToolType = type });
  76. }
  77. }
  78. else
  79. {
  80. foreach (var defaultTool in defaultTools)
  81. {
  82. if (!String.IsNullOrWhiteSpace(defaultTool.fullTypeName))
  83. {
  84. Type toolType = null;
  85. foreach (var type in m_AllTilemapEditorToolTypes)
  86. {
  87. if (type.FullName == defaultTool.fullTypeName)
  88. {
  89. toolType = type;
  90. break;
  91. }
  92. }
  93. m_DefaultTilemapEditorToolTypes.Add(new DefaultTilemapEditorTool { fullTypeName = defaultTool.fullTypeName, tilemapEditorToolType = toolType });
  94. }
  95. }
  96. }
  97. HashSet<Type> otherTypes = new HashSet<Type>(m_AllTilemapEditorToolTypes);
  98. foreach (var defaultType in m_DefaultTilemapEditorToolTypes)
  99. {
  100. if (defaultType.tilemapEditorToolType != null)
  101. otherTypes.Remove(defaultType.tilemapEditorToolType);
  102. }
  103. foreach (var otherType in otherTypes)
  104. {
  105. m_OtherTilemapEditorToolTypes.Add(new DefaultTilemapEditorTool
  106. {fullTypeName = otherType.FullName, tilemapEditorToolType = otherType});
  107. }
  108. }
  109. private EditorTool[] CreateDefaultTilemapEditorTools()
  110. {
  111. if (m_DefaultTilemapEditorToolTypes == null)
  112. LoadDefaultEditorToolTypes();
  113. // Create Tools based on the user's preferences
  114. List<EditorTool> editorTools = new List<EditorTool>();
  115. foreach (var defaultTool in m_DefaultTilemapEditorToolTypes)
  116. {
  117. if (defaultTool.tilemapEditorToolType != null)
  118. {
  119. var tool = ScriptableObject.CreateInstance(defaultTool.tilemapEditorToolType) as EditorTool;
  120. if (tool != null)
  121. editorTools.Add(tool);
  122. }
  123. }
  124. // Ensure that there are always tools for the Tile Palette
  125. if (editorTools.Count == 0)
  126. {
  127. foreach (var defaultToolType in TilemapEditorTool.s_DefaultToolTypes)
  128. {
  129. editorTools.Add(ScriptableObject.CreateInstance(defaultToolType) as EditorTool);
  130. }
  131. }
  132. s_DefaultTilemapEditorTools = editorTools.ToArray();
  133. return s_DefaultTilemapEditorTools;
  134. }
  135. internal void UpdateTilemapEditorToolsChange()
  136. {
  137. tilemapEditorToolsChanged?.Invoke();
  138. }
  139. private void OnDrawDefaultElement(Rect rect, int i, bool isactive, bool isfocused)
  140. {
  141. if (i < 0 || i >= m_DefaultTilemapEditorToolTypes.Count)
  142. return;
  143. var type = m_DefaultTilemapEditorToolTypes[i];
  144. DoDrawElement(rect, type);
  145. }
  146. private void OnDrawOtherElement(Rect rect, int i, bool isactive, bool isfocused)
  147. {
  148. if (i < 0 || i >= m_OtherTilemapEditorToolTypes.Count)
  149. return;
  150. var type = m_OtherTilemapEditorToolTypes[i];
  151. DoDrawElement(rect, type);
  152. }
  153. private void DoDrawElement(Rect rect, DefaultTilemapEditorTool defaultType)
  154. {
  155. if (defaultType.tilemapEditorToolType == null)
  156. {
  157. EditorGUI.LabelField(rect, GUIContent.Temp(String.Format("[{0}] {1}", "Invalid", defaultType.fullTypeName)));
  158. }
  159. else
  160. {
  161. if (defaultType.toolInstance == null)
  162. defaultType.toolInstance = (TilemapEditorTool)ScriptableObject.CreateInstance(defaultType.tilemapEditorToolType);
  163. if (defaultType.toolInstance != null && defaultType.toolInstance.toolbarIcon != null)
  164. {
  165. EditorGUI.LabelField(rect, defaultType.toolInstance.toolbarIcon);
  166. var size = GUI.skin.label.CalcSize(defaultType.toolInstance.toolbarIcon);
  167. rect.xMin += size.x;
  168. }
  169. EditorGUI.LabelField(rect, GUIContent.Temp(defaultType.tilemapEditorToolType.Name, defaultType.tilemapEditorToolType.FullName));
  170. }
  171. }
  172. private void OnReorderDefaultElement(ReorderableList list)
  173. {
  174. m_Changed = true;
  175. }
  176. private void DoPreferencesGUI()
  177. {
  178. if (m_DefaultTypes == null)
  179. LoadDefaultEditorToolTypes();
  180. EditorGUILayout.LabelField(TilemapEditorToolProperties.defaultToolsLabel);
  181. EditorGUILayout.BeginHorizontal();
  182. m_DefaultTypes.DoLayoutList();
  183. EditorGUILayout.BeginVertical(GUILayout.Width(100));
  184. if (GUILayout.Button(TilemapEditorToolProperties.addLabel))
  185. {
  186. var otherIndex = m_OtherTypes.index;
  187. if (0 <= otherIndex && otherIndex < m_OtherTilemapEditorToolTypes.Count)
  188. {
  189. var otherType = m_OtherTilemapEditorToolTypes[otherIndex];
  190. var defaultIndex = m_DefaultTypes.index;
  191. m_DefaultTilemapEditorToolTypes.Insert(defaultIndex + 1, otherType);
  192. m_OtherTilemapEditorToolTypes.RemoveAt(otherIndex);
  193. m_DefaultTypes.index = defaultIndex + 1;
  194. m_OtherTypes.index = -1;
  195. m_Changed = true;
  196. }
  197. }
  198. if (GUILayout.Button(TilemapEditorToolProperties.removeLabel))
  199. {
  200. var defaultIndex = m_DefaultTypes.index;
  201. if (0 <= defaultIndex && defaultIndex < m_DefaultTilemapEditorToolTypes.Count)
  202. {
  203. var defaultType = m_DefaultTilemapEditorToolTypes[defaultIndex];
  204. if (defaultType.tilemapEditorToolType != null)
  205. {
  206. var otherIndex = m_OtherTypes.index;
  207. m_OtherTilemapEditorToolTypes.Insert(otherIndex + 1, defaultType);
  208. m_OtherTypes.index = otherIndex + 1;
  209. }
  210. m_DefaultTilemapEditorToolTypes.RemoveAt(defaultIndex);
  211. m_DefaultTypes.index = -1;
  212. m_Changed = true;
  213. }
  214. }
  215. EditorGUILayout.EndVertical();
  216. m_OtherTypes.DoLayoutList();
  217. EditorGUILayout.EndHorizontal();
  218. EditorGUILayout.BeginHorizontal();
  219. using (new EditorGUI.DisabledScope(!m_Changed))
  220. {
  221. if (GUILayout.Button(TilemapEditorToolProperties.saveLabel))
  222. {
  223. SaveTilemapEditorToolPreferences(m_DefaultTilemapEditorToolTypes);
  224. m_Changed = false;
  225. GridPaintingState.RepaintGridPaintPaletteWindow();
  226. }
  227. if (GUILayout.Button(TilemapEditorToolProperties.revertLabel))
  228. {
  229. LoadDefaultEditorToolTypes();
  230. m_DefaultTypes.index = -1;
  231. m_OtherTypes.index = -1;
  232. m_Changed = false;
  233. }
  234. }
  235. if (GUILayout.Button(TilemapEditorToolProperties.resetLabel))
  236. {
  237. ResetTilemapEditorToolPreferences();
  238. m_DefaultTypes.index = -1;
  239. m_OtherTypes.index = -1;
  240. m_Changed = false;
  241. GridPaintingState.RepaintGridPaintPaletteWindow();
  242. }
  243. EditorGUILayout.EndHorizontal();
  244. }
  245. internal void SaveTilemapEditorToolPreferences(List<DefaultTilemapEditorTool> defaultTools)
  246. {
  247. SaveTilemapEditorToolPreferencesAsset(defaultTools);
  248. ClearExistingDefaultTilemapEditorTools();
  249. LoadDefaultEditorToolTypes();
  250. DeactivateToolIfNotInDefault();
  251. UpdateTilemapEditorToolsChange();
  252. }
  253. internal void ResetTilemapEditorToolPreferences()
  254. {
  255. DeleteTilemapEditorToolPreferencesAsset();
  256. ClearExistingDefaultTilemapEditorTools();
  257. LoadDefaultEditorToolTypes();
  258. DeactivateToolIfNotInDefault();
  259. UpdateTilemapEditorToolsChange();
  260. }
  261. private static void DeleteTilemapEditorToolPreferencesAsset()
  262. {
  263. if (File.Exists(s_AssetPath))
  264. {
  265. FileUtil.DeleteFileOrDirectory(s_AssetPath);
  266. }
  267. }
  268. private static void SaveTilemapEditorToolPreferencesAsset(List<DefaultTilemapEditorTool> defaultTools)
  269. {
  270. if (defaultTools == null)
  271. return;
  272. foreach (var defaultTool in defaultTools)
  273. {
  274. if (defaultTool.tilemapEditorToolType != null &&
  275. !(defaultTool.tilemapEditorToolType.IsSubclassOf(typeof(TilemapEditorTool))))
  276. {
  277. return;
  278. }
  279. }
  280. if (!Directory.Exists(s_LibraryFolderPath))
  281. {
  282. Directory.CreateDirectory(s_LibraryFolderPath);
  283. }
  284. var saveAsset = ScriptableObject.CreateInstance<TilemapEditorToolPreferencesAsset>();
  285. saveAsset.m_UserDefaultTools = defaultTools;
  286. InternalEditorUtility.SaveToSerializedFileAndForget(new Object[] { saveAsset }, s_AssetPath, true);
  287. }
  288. private static void ClearExistingDefaultTilemapEditorTools()
  289. {
  290. if (s_DefaultTilemapEditorTools == null)
  291. return;
  292. for (int i = 0; i < s_DefaultTilemapEditorTools.Length; ++i)
  293. {
  294. s_DefaultTilemapEditorTools[i] = null;
  295. }
  296. }
  297. private List<DefaultTilemapEditorTool> LoadTilemapEditorToolPreferencesAsset()
  298. {
  299. if (!File.Exists(s_AssetPath))
  300. return null;
  301. var serializedObjects = InternalEditorUtility.LoadSerializedFileAndForget(s_AssetPath);
  302. if (serializedObjects != null && serializedObjects.Length > 0)
  303. {
  304. var defaultTools = serializedObjects[0] as TilemapEditorToolPreferencesAsset;
  305. if (defaultTools != null)
  306. return defaultTools.m_UserDefaultTools;
  307. }
  308. return null;
  309. }
  310. private void DeactivateToolIfNotInDefault()
  311. {
  312. var activeToolType = ToolManager.activeToolType;
  313. if (activeToolType == null ||
  314. !activeToolType.IsSubclassOf(typeof(TilemapEditorTool)))
  315. {
  316. return;
  317. }
  318. if (s_DefaultTilemapEditorTools == null || s_DefaultTilemapEditorTools[0] == null)
  319. CreateDefaultTilemapEditorTools();
  320. foreach (var defaultToolType in s_DefaultTilemapEditorTools)
  321. {
  322. if (activeToolType == defaultToolType.GetType())
  323. return;
  324. }
  325. ToolManager.SetActiveTool(typeof(ViewModeTool));
  326. }
  327. }
  328. }