Singularity/Library/PackageCache/com.unity.2d.tilemap@1.0.0/Editor/EditorTools/TilemapEditorToolPreference...
2024-05-06 11:45:45 -07:00

344 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor.EditorTools;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;
namespace UnityEditor.Tilemaps
{
internal class TilemapEditorToolPreferences : ScriptableSingleton<TilemapEditorToolPreferences>
{
private static readonly string s_LibraryFolderPath = "Library/GridBrush";
private static readonly string s_AssetPath = FileUtil.CombinePaths(s_LibraryFolderPath, "TilemapEditorToolPreferences.asset");
internal class TilemapEditorToolProperties
{
public static readonly string defaultToolsEditorPref = "TilemapEditorTool.DefaultTools";
public static readonly GUIContent defaultToolsLabel = EditorGUIUtility.TrTextContent("Default Tile Palette Tools");
public static readonly GUIContent addLabel = EditorGUIUtility.TrTextContent("+", "Add to Defaults");
public static readonly GUIContent removeLabel = EditorGUIUtility.TrTextContent("-", "Remove from Defaults");
public static readonly GUIContent saveLabel = EditorGUIUtility.TrTextContent("Save", "Save Defaults");
public static readonly GUIContent revertLabel = EditorGUIUtility.TrTextContent("Revert", "Revert Changes");
public static readonly GUIContent resetLabel = EditorGUIUtility.TrTextContent("Reset", "Reset Defaults");
}
internal static void PreferencesGUI()
{
using (new SettingsWindow.GUIScope())
{
instance.DoPreferencesGUI();
}
}
internal static EditorTool[] CreateDefaultTilePaletteEditorTools()
{
return instance.CreateDefaultTilemapEditorTools();
}
private ReorderableList m_DefaultTypes;
private ReorderableList m_OtherTypes;
private bool m_Changed;
private HashSet<Type> m_AllTilemapEditorToolTypes;
private List<DefaultTilemapEditorTool> m_DefaultTilemapEditorToolTypes;
private List<DefaultTilemapEditorTool> m_OtherTilemapEditorToolTypes;
private static EditorTool[] s_DefaultTilemapEditorTools;
private void OnEnable()
{
m_DefaultTilemapEditorToolTypes = new List<DefaultTilemapEditorTool>();
m_OtherTilemapEditorToolTypes = new List<DefaultTilemapEditorTool>();
LoadDefaultEditorToolTypes();
m_DefaultTypes = new ReorderableList(m_DefaultTilemapEditorToolTypes, typeof(DefaultTilemapEditorTool), true, false, false, false);
m_DefaultTypes.drawElementCallback = OnDrawDefaultElement;
m_DefaultTypes.onReorderCallback = OnReorderDefaultElement;
m_OtherTypes = new ReorderableList(m_OtherTilemapEditorToolTypes, typeof(DefaultTilemapEditorTool), true, false, false, false);
m_OtherTypes.drawElementCallback = OnDrawOtherElement;
m_Changed = false;
}
private void InitializeAllTilemapEditorToolTypes()
{
m_AllTilemapEditorToolTypes = new HashSet<Type>();
foreach (var tilemapEditorToolType in TypeCache.GetTypesDerivedFrom(typeof(TilemapEditorTool)))
{
if (tilemapEditorToolType.IsAbstract)
continue;
m_AllTilemapEditorToolTypes.Add(tilemapEditorToolType);
}
}
internal void LoadDefaultEditorToolTypes()
{
InitializeAllTilemapEditorToolTypes();
m_DefaultTilemapEditorToolTypes.Clear();
m_OtherTilemapEditorToolTypes.Clear();
var defaultTools = LoadTilemapEditorToolPreferencesAsset();
if (defaultTools == null || defaultTools.Count == 0)
{
foreach (var type in TilemapEditorTool.s_DefaultToolTypes)
{
m_DefaultTilemapEditorToolTypes.Add(new DefaultTilemapEditorTool { fullTypeName = type.FullName, tilemapEditorToolType = type });
}
}
else
{
foreach (var defaultTool in defaultTools)
{
if (!String.IsNullOrWhiteSpace(defaultTool.fullTypeName))
{
Type toolType = null;
foreach (var type in m_AllTilemapEditorToolTypes)
{
if (type.FullName == defaultTool.fullTypeName)
{
toolType = type;
break;
}
}
m_DefaultTilemapEditorToolTypes.Add(new DefaultTilemapEditorTool { fullTypeName = defaultTool.fullTypeName, tilemapEditorToolType = toolType });
}
}
}
HashSet<Type> otherTypes = new HashSet<Type>(m_AllTilemapEditorToolTypes);
foreach (var defaultType in m_DefaultTilemapEditorToolTypes)
{
if (defaultType.tilemapEditorToolType != null)
otherTypes.Remove(defaultType.tilemapEditorToolType);
}
foreach (var otherType in otherTypes)
{
m_OtherTilemapEditorToolTypes.Add(new DefaultTilemapEditorTool
{fullTypeName = otherType.FullName, tilemapEditorToolType = otherType});
}
}
private EditorTool[] CreateDefaultTilemapEditorTools()
{
if (m_DefaultTilemapEditorToolTypes == null)
LoadDefaultEditorToolTypes();
// Create Tools based on the user's preferences
List<EditorTool> editorTools = new List<EditorTool>();
foreach (var defaultTool in m_DefaultTilemapEditorToolTypes)
{
if (defaultTool.tilemapEditorToolType != null)
{
var tool = ScriptableObject.CreateInstance(defaultTool.tilemapEditorToolType) as EditorTool;
if (tool != null)
editorTools.Add(tool);
}
}
// Ensure that there are always tools for the Tile Palette
if (editorTools.Count == 0)
{
foreach (var defaultToolType in TilemapEditorTool.s_DefaultToolTypes)
{
editorTools.Add(ScriptableObject.CreateInstance(defaultToolType) as EditorTool);
}
}
s_DefaultTilemapEditorTools = editorTools.ToArray();
return s_DefaultTilemapEditorTools;
}
internal void ClearExistingDefaultTilemapEditorTools()
{
if (s_DefaultTilemapEditorTools == null)
return;
for (int i = 0; i < s_DefaultTilemapEditorTools.Length; ++i)
{
s_DefaultTilemapEditorTools[i] = null;
}
}
private void OnDrawDefaultElement(Rect rect, int i, bool isactive, bool isfocused)
{
if (i < 0 || i >= m_DefaultTilemapEditorToolTypes.Count)
return;
var type = m_DefaultTilemapEditorToolTypes[i];
DoDrawElement(rect, type);
}
private void OnDrawOtherElement(Rect rect, int i, bool isactive, bool isfocused)
{
if (i < 0 || i >= m_OtherTilemapEditorToolTypes.Count)
return;
var type = m_OtherTilemapEditorToolTypes[i];
DoDrawElement(rect, type);
}
private void DoDrawElement(Rect rect, DefaultTilemapEditorTool defaultType)
{
if (defaultType.tilemapEditorToolType == null)
{
EditorGUI.LabelField(rect, GUIContent.Temp(String.Format("[{0}] {1}", "Invalid", defaultType.fullTypeName)));
}
else
{
if (defaultType.toolInstance == null)
defaultType.toolInstance = (TilemapEditorTool)ScriptableObject.CreateInstance(defaultType.tilemapEditorToolType);
if (defaultType.toolInstance != null && defaultType.toolInstance.toolbarIcon != null)
{
EditorGUI.LabelField(rect, defaultType.toolInstance.toolbarIcon);
var size = GUI.skin.label.CalcSize(defaultType.toolInstance.toolbarIcon);
rect.xMin += size.x;
}
EditorGUI.LabelField(rect, GUIContent.Temp(defaultType.tilemapEditorToolType.Name, defaultType.tilemapEditorToolType.FullName));
}
}
private void OnReorderDefaultElement(ReorderableList list)
{
m_Changed = true;
}
private void DoPreferencesGUI()
{
if (m_DefaultTypes == null)
LoadDefaultEditorToolTypes();
EditorGUILayout.LabelField(TilemapEditorToolProperties.defaultToolsLabel);
EditorGUILayout.BeginHorizontal();
m_DefaultTypes.DoLayoutList();
EditorGUILayout.BeginVertical();
if (GUILayout.Button(TilemapEditorToolProperties.addLabel))
{
var otherIndex = m_OtherTypes.index;
if (0 <= otherIndex && otherIndex < m_OtherTilemapEditorToolTypes.Count)
{
var otherType = m_OtherTilemapEditorToolTypes[otherIndex];
var defaultIndex = m_DefaultTypes.index;
m_DefaultTilemapEditorToolTypes.Insert(defaultIndex + 1, otherType);
m_OtherTilemapEditorToolTypes.RemoveAt(otherIndex);
m_DefaultTypes.index = defaultIndex + 1;
m_OtherTypes.index = -1;
m_Changed = true;
}
}
if (GUILayout.Button(TilemapEditorToolProperties.removeLabel))
{
var defaultIndex = m_DefaultTypes.index;
if (0 <= defaultIndex && defaultIndex < m_DefaultTilemapEditorToolTypes.Count)
{
var defaultType = m_DefaultTilemapEditorToolTypes[defaultIndex];
if (defaultType.tilemapEditorToolType != null)
{
var otherIndex = m_OtherTypes.index;
m_OtherTilemapEditorToolTypes.Insert(otherIndex + 1, defaultType);
m_OtherTypes.index = otherIndex + 1;
}
m_DefaultTilemapEditorToolTypes.RemoveAt(defaultIndex);
m_DefaultTypes.index = -1;
m_Changed = true;
}
}
EditorGUILayout.EndVertical();
m_OtherTypes.DoLayoutList();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
using (new EditorGUI.DisabledScope(!m_Changed))
{
if (GUILayout.Button(TilemapEditorToolProperties.saveLabel))
{
SaveTilemapEditorToolPreferencesAsset(m_DefaultTilemapEditorToolTypes);
ClearExistingDefaultTilemapEditorTools();
m_Changed = false;
GridPaintingState.RepaintGridPaintPaletteWindow();
}
if (GUILayout.Button(TilemapEditorToolProperties.revertLabel))
{
LoadDefaultEditorToolTypes();
m_DefaultTypes.index = -1;
m_OtherTypes.index = -1;
m_Changed = false;
}
}
if (GUILayout.Button(TilemapEditorToolProperties.resetLabel))
{
DeleteTilemapEditorToolPreferencesAsset();
ClearExistingDefaultTilemapEditorTools();
LoadDefaultEditorToolTypes();
m_DefaultTypes.index = -1;
m_OtherTypes.index = -1;
m_Changed = false;
GridPaintingState.RepaintGridPaintPaletteWindow();
}
EditorGUILayout.EndHorizontal();
}
internal void DeleteTilemapEditorToolPreferencesAsset()
{
if (File.Exists(s_AssetPath))
{
FileUtil.DeleteFileOrDirectory(s_AssetPath);
}
}
internal void SaveTilemapEditorToolPreferencesAsset(List<DefaultTilemapEditorTool> defaultTools)
{
if (defaultTools == null)
return;
foreach (var defaultTool in defaultTools)
{
if (defaultTool.tilemapEditorToolType != null &&
!(defaultTool.tilemapEditorToolType.IsSubclassOf(typeof(TilemapEditorTool))))
{
return;
}
}
if (!Directory.Exists(s_LibraryFolderPath))
{
Directory.CreateDirectory(s_LibraryFolderPath);
}
var saveAsset = ScriptableObject.CreateInstance<TilemapEditorToolPreferencesAsset>();
saveAsset.m_UserDefaultTools = defaultTools;
InternalEditorUtility.SaveToSerializedFileAndForget(new Object[] { saveAsset }, s_AssetPath, true);
}
internal List<DefaultTilemapEditorTool> LoadTilemapEditorToolPreferencesAsset()
{
if (!File.Exists(s_AssetPath))
return null;
var serializedObjects = InternalEditorUtility.LoadSerializedFileAndForget(s_AssetPath);
if (serializedObjects != null && serializedObjects.Length > 0)
{
var defaultTools = serializedObjects[0] as TilemapEditorToolPreferencesAsset;
if (defaultTools != null)
return defaultTools.m_UserDefaultTools;
}
return null;
}
}
}