using System;
using System.Collections.Generic;
using UnityEditor.EditorTools;
using UnityEditor.ShortcutManagement;
using UnityEngine;
namespace UnityEditor.Tilemaps
{
///
/// A base class for Editor Tools which work with the Tile Palette
/// and GridBrushes
///
public abstract class TilemapEditorTool : EditorTool
{
///
/// Context to determine if TilemapEditorTools can be triggered through shortcuts
///
public class ShortcutContext : IShortcutToolContext
{
public bool active { get; set; }
}
private static Dictionary s_TilemapEditorToolsMap;
private static EditorTool[] s_DefaultTilemapEditorTools;
///
/// Types for all the Default Editor Tools
///
internal static Type[] s_DefaultToolTypes = new[]
{
typeof(SelectTool),
typeof(MoveTool),
typeof(PaintTool),
typeof(BoxTool),
typeof(PickingTool),
typeof(EraseTool),
typeof(FillTool)
};
///
/// All currently active Editor Tools which work with the Tile Palette
///
public static EditorTool[] tilemapEditorTools
{
get
{
if (IsCachedEditorToolsInvalid())
InstantiateEditorTools();
return GridPaintingState.activeBrushTools;
}
}
///
/// The horizontal size of a Toolbar with all the TilemapEditorTools
///
public static float tilemapEditorToolsToolbarSize
{
get
{
if (IsCachedEditorToolsInvalid())
InstantiateEditorTools();
return GridPaintingState.activeBrushToolbarSize;
}
}
///
/// Tooltip String format which accepts a shortcut combination as the parameter
///
protected abstract string tooltipStringFormat { get; }
///
/// Shortcut Id for this tool
///
protected abstract string shortcutId { get; }
///
/// Gets the text for the tooltip given a tooltip string format
/// and the shortcut combination for a tooltip
///
/// String format which accepts a shortcut combination as the parameter
/// Shortcut Id for this tool
/// The final text for the tooltip
protected static string GetTooltipText(string tooltipStringFormat, string shortcutId)
{
return String.Format(tooltipStringFormat, GetKeysFromToolName(shortcutId));
}
///
/// Gets the key combination for triggering the shortcut for this tool
///
/// The shortcut id for this tool
/// The key combination for triggering the shortcut for this tool
protected static string GetKeysFromToolName(string id)
{
return ShortcutIntegration.instance.GetKeyCombinationFor(id);
}
///
/// Updates the tooltip whenever there is a change in shortcut combinations
///
protected void UpdateTooltip()
{
toolbarIcon.tooltip = GetTooltipText(tooltipStringFormat, shortcutId);
}
///
/// Method called when the Tool is being used.
/// Override this to have custom behaviour when the Tool is used.
///
/// Whether the tool is the hot control
/// GridLayout the tool is being used on
/// Target GameObject the tool is being used on
/// Grid Cell position of the Mouse on the GridLayout
/// Whether the tool has been used and modified the brushTarget
public virtual bool HandleTool(bool isHotControl, GridLayout gridLayout, GameObject brushTarget, Vector3Int gridMousePosition)
{
return false;
}
///
/// Gets whether the tool is available for use
///
/// Whether the tool is available for use
public override bool IsAvailable()
{
return (GridPaintPaletteWindow.instances.Count > 0) && GridPaintingState.gridBrush;
}
internal static void UpdateTooltips()
{
if (IsCachedEditorToolsInvalid())
InstantiateEditorTools();
foreach (var editorTool in GridPaintingState.activeBrushTools)
{
var tilemapEditorTool = editorTool as TilemapEditorTool;
if (tilemapEditorTool == null)
return;
tilemapEditorTool.UpdateTooltip();
}
}
///
/// Toggles the state of active editor tool with the type passed in.
///
///
/// This will change the current active editor tool if the type passed in
/// is not the same as the current active editor tool. Otherwise, it will
/// set the View Mode tool as the current active editor tool.
///
///
/// The type of editor tool. This must be inherited from EditorTool.
///
public static void ToggleActiveEditorTool(Type type)
{
if (ToolManager.activeToolType != type)
{
SetActiveEditorTool(type);
}
else
{
ToolManager.RestorePreviousPersistentTool();
}
}
///
/// Sets the current active editor tool to the type passed in
///
/// The type of editor tool. This must be inherited from TilemapEditorTool
/// Throws this if an invalid type parameter is set
public static void SetActiveEditorTool(Type type)
{
if (type == null || !type.IsSubclassOf(typeof(TilemapEditorTool)))
throw new ArgumentException("The tool to set must be valid and derive from TilemapEditorTool.");
EditorTool selectedTool = null;
foreach (var tool in tilemapEditorTools)
{
if (tool.GetType() == type)
{
selectedTool = tool;
break;
}
}
if (selectedTool != null)
{
ToolManager.SetActiveTool(selectedTool);
}
}
internal static bool IsActive(Type toolType)
{
return ToolManager.activeToolType != null && ToolManager.activeToolType == toolType;
}
private static bool IsCachedEditorToolsInvalid()
{
return s_TilemapEditorToolsMap == null
|| s_DefaultTilemapEditorTools == null
|| s_DefaultTilemapEditorTools.Length == 0
|| s_DefaultTilemapEditorTools[0] == null;
}
private static void InstantiateEditorTools()
{
s_DefaultTilemapEditorTools = TilemapEditorToolPreferences.CreateDefaultTilePaletteEditorTools();
s_TilemapEditorToolsMap = new Dictionary(s_DefaultTilemapEditorTools.Length);
foreach (var editorTool in s_DefaultTilemapEditorTools)
{
s_TilemapEditorToolsMap.Add(editorTool.GetType(), editorTool);
}
GridPaintingState.UpdateBrushToolbar();
}
internal static void UpdateEditorTools(BrushToolsAttribute brushToolsAttribute)
{
if (IsCachedEditorToolsInvalid())
InstantiateEditorTools();
EditorTool[] editorTools;
if (brushToolsAttribute?.toolList == null || brushToolsAttribute.toolList.Count == 0)
{
editorTools = s_DefaultTilemapEditorTools;
}
else
{
editorTools = new EditorTool[brushToolsAttribute.toolList.Count];
for (int i = 0; i < brushToolsAttribute.toolList.Count; ++i)
{
var toolType = brushToolsAttribute.toolList[i];
if (!s_TilemapEditorToolsMap.TryGetValue(toolType, out EditorTool editorTool))
{
editorTool = (EditorTool)ScriptableObject.CreateInstance(toolType);
s_TilemapEditorToolsMap.Add(toolType, editorTool);
}
editorTools[i] = editorTool;
}
}
GridPaintingState.SetBrushTools(editorTools);
}
internal static bool IsCustomTilemapEditorToolActive()
{
if (EditorToolManager.activeTool == null
|| !(EditorToolManager.activeTool is TilemapEditorTool))
return false;
if (s_DefaultTilemapEditorTools == null)
return false;
var activeToolType = EditorToolManager.activeTool.GetType();
foreach (var toolType in s_DefaultToolTypes)
{
if (toolType == activeToolType)
return false;
}
return true;
}
}
}