A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using UnityEditor.EditorTools;
4using UnityEditor.ShortcutManagement;
5using UnityEngine;
6
7namespace UnityEditor.Tilemaps
8{
9 /// <summary>
10 /// A base class for Editor Tools which work with the Tile Palette
11 /// and GridBrushes
12 /// </summary>
13 public abstract class TilemapEditorTool : EditorTool
14 {
15 /// <summary>
16 /// Context to determine if TilemapEditorTools can be triggered through shortcuts
17 /// </summary>
18 public class ShortcutContext : IShortcutContext
19 {
20 /// <summary>
21 /// Returns whether the ShortcutContext is active or not.
22 /// </summary>
23 public bool active { get; set; }
24 }
25
26 private static Dictionary<Type, EditorTool> s_TilemapEditorToolsMap;
27 private static EditorTool[] s_DefaultTilemapEditorTools;
28
29 /// <summary>
30 /// Types for all the Default Editor Tools
31 /// </summary>
32 internal static Type[] s_DefaultToolTypes = new[]
33 {
34 typeof(SelectTool),
35 typeof(MoveTool),
36 typeof(PaintTool),
37 typeof(BoxTool),
38 typeof(PickingTool),
39 typeof(EraseTool),
40 typeof(FillTool),
41 typeof(RotateCounterClockwiseTool),
42 typeof(RotateClockwiseTool),
43 typeof(FlipXTool),
44 typeof(FlipYTool)
45 };
46
47 /// <summary>
48 /// All currently active Editor Tools which work with the Tile Palette
49 /// </summary>
50 public static EditorTool[] tilemapEditorTools
51 {
52 get
53 {
54 if (IsCachedEditorToolsInvalid())
55 InstantiateEditorTools();
56 return GridPaintingState.activeBrushTools;
57 }
58 }
59
60 /// <summary>
61 /// The horizontal size of a Toolbar with all the TilemapEditorTools
62 /// </summary>
63 [Obsolete]
64 public static float tilemapEditorToolsToolbarSize
65 {
66 get
67 {
68 if (IsCachedEditorToolsInvalid())
69 InstantiateEditorTools();
70 return GridPaintingState.activeBrushToolbarSize;
71 }
72 }
73
74 /// <summary>
75 /// Tooltip String format which accepts a shortcut combination as the parameter
76 /// </summary>
77 protected abstract string tooltipStringFormat { get; }
78 /// <summary>
79 /// Shortcut Id for this tool
80 /// </summary>
81 protected abstract string shortcutId { get; }
82
83 /// <summary>
84 /// Gets the text for the tooltip given a tooltip string format
85 /// and the shortcut combination for a tooltip
86 /// </summary>
87 /// <param name="tooltipStringFormat">String format which accepts a shortcut combination as the parameter</param>
88 /// <param name="shortcutId">Shortcut Id for this tool</param>
89 /// <returns>The final text for the tooltip</returns>
90 protected static string GetTooltipText(string tooltipStringFormat, string shortcutId)
91 {
92 return String.Format(tooltipStringFormat, GetKeysFromToolName(shortcutId));
93 }
94
95 /// <summary>
96 /// Gets the key combination for triggering the shortcut for this tool
97 /// </summary>
98 /// <param name="id">The shortcut id for this tool</param>
99 /// <returns>The key combination for triggering the shortcut for this tool</returns>
100 protected static string GetKeysFromToolName(string id)
101 {
102 return ShortcutIntegration.instance.GetKeyCombinationFor(id);
103 }
104
105 /// <summary>
106 /// Updates the tooltip whenever there is a change in shortcut combinations
107 /// </summary>
108 protected void UpdateTooltip()
109 {
110 toolbarIcon.tooltip = GetTooltipText(tooltipStringFormat, shortcutId);
111 }
112
113 /// <summary>
114 /// Method called when the Tool is being used.
115 /// Override this to have custom behaviour when the Tool is used.
116 /// </summary>
117 /// <param name="isHotControl">Whether the tool is the hot control</param>
118 /// <param name="gridLayout">GridLayout the tool is being used on</param>
119 /// <param name="brushTarget">Target GameObject the tool is being used on</param>
120 /// <param name="gridMousePosition">Grid Cell position of the Mouse on the GridLayout</param>
121 /// <returns>Whether the tool has been used and modified the brushTarget</returns>
122 public virtual bool HandleTool(bool isHotControl, GridLayout gridLayout, GameObject brushTarget, Vector3Int gridMousePosition)
123 {
124 return false;
125 }
126
127 /// <summary>
128 /// Gets whether the tool is available for use
129 /// </summary>
130 /// <returns>Whether the tool is available for use</returns>
131 public override bool IsAvailable()
132 {
133 return (GridPaintingState.isEditing) && GridPaintingState.gridBrush;
134 }
135
136 /// <summary>
137 /// Callback when a TilemapEditorTool is activated
138 /// </summary>
139 public override void OnActivated()
140 {
141 //if (ToolManager.activeContextType != typeof(GridSelectionToolContext))
142 // ToolManager.SetActiveContext<GridSelectionToolContext>();
143 }
144
145 internal static void UpdateTooltips()
146 {
147 if (IsCachedEditorToolsInvalid())
148 InstantiateEditorTools();
149
150 foreach (var editorTool in GridPaintingState.activeBrushTools)
151 {
152 var tilemapEditorTool = editorTool as TilemapEditorTool;
153 if (tilemapEditorTool == null)
154 return;
155
156 tilemapEditorTool.UpdateTooltip();
157 }
158 }
159
160 /// <summary>
161 /// Toggles the state of active editor tool with the type passed in.
162 /// </summary>
163 /// <remarks>
164 /// This will change the current active editor tool if the type passed in
165 /// is not the same as the current active editor tool. Otherwise, it will
166 /// set the View Mode tool as the current active editor tool.
167 /// </remarks>
168 /// <param name="type">
169 /// The type of editor tool. This must be inherited from EditorTool.
170 /// </param>
171 public static void ToggleActiveEditorTool(Type type)
172 {
173 if (ToolManager.activeToolType != type)
174 {
175 SetActiveEditorTool(type);
176 }
177 else
178 {
179 ToolManager.RestorePreviousPersistentTool();
180 }
181 }
182
183 /// <summary>
184 /// Sets the current active editor tool to the type passed in
185 /// </summary>
186 /// <param name="type">The type of editor tool. This must be inherited from TilemapEditorTool</param>
187 /// <exception cref="ArgumentException">Throws this if an invalid type parameter is set</exception>
188 public static void SetActiveEditorTool(Type type)
189 {
190 if (type == null || !type.IsSubclassOf(typeof(TilemapEditorTool)))
191 throw new ArgumentException("The tool to set must be valid and derive from TilemapEditorTool.");
192
193 EditorTool selectedTool = null;
194 foreach (var tool in tilemapEditorTools)
195 {
196 if (tool.GetType() == type)
197 {
198 selectedTool = tool;
199 break;
200 }
201 }
202
203 if (selectedTool != null)
204 {
205 ToolManager.SetActiveTool(selectedTool);
206 }
207 }
208
209 internal static bool IsActive(Type toolType)
210 {
211 return ToolManager.activeToolType != null && ToolManager.activeToolType == toolType;
212 }
213
214 private static bool IsCachedEditorToolsInvalid()
215 {
216 return s_TilemapEditorToolsMap == null
217 || s_DefaultTilemapEditorTools == null
218 || s_DefaultTilemapEditorTools.Length == 0
219 || s_DefaultTilemapEditorTools[0] == null;
220 }
221
222 private static void InstantiateEditorTools()
223 {
224 s_DefaultTilemapEditorTools = TilemapEditorToolPreferences.CreateDefaultTilePaletteEditorTools();
225 s_TilemapEditorToolsMap = new Dictionary<Type, EditorTool>(s_DefaultTilemapEditorTools.Length);
226 foreach (var editorTool in s_DefaultTilemapEditorTools)
227 {
228 s_TilemapEditorToolsMap.Add(editorTool.GetType(), editorTool);
229 }
230 GridPaintingState.UpdateBrushToolbar();
231 }
232
233 internal static void UpdateEditorTools(BrushToolsAttribute brushToolsAttribute)
234 {
235 if (IsCachedEditorToolsInvalid())
236 InstantiateEditorTools();
237 EditorTool[] editorTools;
238 if (brushToolsAttribute?.toolList == null || brushToolsAttribute.toolList.Count == 0)
239 {
240 editorTools = s_DefaultTilemapEditorTools;
241 }
242 else
243 {
244 editorTools = new EditorTool[brushToolsAttribute.toolList.Count];
245 for (int i = 0; i < brushToolsAttribute.toolList.Count; ++i)
246 {
247 var toolType = brushToolsAttribute.toolList[i];
248 if (!s_TilemapEditorToolsMap.TryGetValue(toolType, out EditorTool editorTool))
249 {
250 editorTool = (EditorTool)CreateInstance(toolType);
251 s_TilemapEditorToolsMap.Add(toolType, editorTool);
252 }
253 editorTools[i] = editorTool;
254 }
255 }
256 GridPaintingState.SetBrushTools(editorTools);
257 }
258
259 internal static bool IsCustomTilemapEditorToolActive()
260 {
261 if (EditorToolManager.activeTool == null
262 || !(EditorToolManager.activeTool is TilemapEditorTool))
263 return false;
264
265 if (s_DefaultTilemapEditorTools == null)
266 return false;
267
268 var activeToolType = EditorToolManager.activeTool.GetType();
269 foreach (var toolType in s_DefaultToolTypes)
270 {
271 if (toolType == activeToolType)
272 return false;
273 }
274
275 return true;
276 }
277 }
278}