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