This repository has been archived on 2020-08-22. You can view files and clone it, but cannot push or open issues or pull requests.
flutter-unity-view-widget/example/Unity/Demo App/Library/PackageCache/com.unity.textmeshpro@1.3.0/Scripts/Editor/TMP_SpriteAssetEditor.cs

502 lines
21 KiB
C#

using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TMP_SpriteAsset))]
public class TMP_SpriteAssetEditor : Editor
{
struct UI_PanelState
{
public static bool spriteAssetInfoPanel = true;
public static bool fallbackSpriteAssetPanel = true;
public static bool spriteInfoPanel;
}
int m_moveToIndex;
int m_selectedElement = -1;
int m_page;
const string k_UndoRedo = "UndoRedoPerformed";
string m_searchPattern;
List<int> m_searchList;
bool m_isSearchDirty;
SerializedProperty m_spriteAtlas_prop;
SerializedProperty m_material_prop;
SerializedProperty m_spriteInfoList_prop;
ReorderableList m_fallbackSpriteAssetList;
bool isAssetDirty;
float m_xOffset;
float m_yOffset;
float m_xAdvance;
float m_scale;
public void OnEnable()
{
m_spriteAtlas_prop = serializedObject.FindProperty("spriteSheet");
m_material_prop = serializedObject.FindProperty("material");
m_spriteInfoList_prop = serializedObject.FindProperty("spriteInfoList");
// Fallback TMP Sprite Asset list
m_fallbackSpriteAssetList = new ReorderableList(serializedObject, serializedObject.FindProperty("fallbackSpriteAssets"), true, true, true, true);
m_fallbackSpriteAssetList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
{
var element = m_fallbackSpriteAssetList.serializedProperty.GetArrayElementAtIndex(index);
rect.y += 2;
EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none);
};
m_fallbackSpriteAssetList.drawHeaderCallback = rect =>
{
EditorGUI.LabelField(rect, new GUIContent("Fallback Sprite Asset List", "Select the Sprite Assets that will be searched and used as fallback when a given sprite is missing from this sprite asset."));
};
}
public override void OnInspectorGUI()
{
//Debug.Log("OnInspectorGUI Called.");
Event currentEvent = Event.current;
string evt_cmd = currentEvent.commandName; // Get Current Event CommandName to check for Undo Events
serializedObject.Update();
// TEXTMESHPRO SPRITE INFO PANEL
GUILayout.Label("Sprite Info", EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_spriteAtlas_prop , new GUIContent("Sprite Atlas"));
if (EditorGUI.EndChangeCheck())
{
// Assign the new sprite atlas texture to the current material
Texture2D tex = m_spriteAtlas_prop.objectReferenceValue as Texture2D;
if (tex != null)
{
Material mat = m_material_prop.objectReferenceValue as Material;
if (mat != null)
mat.mainTexture = tex;
}
}
EditorGUILayout.PropertyField(m_material_prop, new GUIContent("Default Material"));
EditorGUILayout.Space();
// FALLBACK SPRITE ASSETS
EditorGUI.indentLevel = 0;
UI_PanelState.fallbackSpriteAssetPanel = EditorGUILayout.Foldout(UI_PanelState.fallbackSpriteAssetPanel, new GUIContent("Fallback Sprite Assets", "Select the Sprite Assets that will be searched and used as fallback when a given sprite is missing from this sprite asset."), true, TMP_UIStyleManager.boldFoldout);
if (UI_PanelState.fallbackSpriteAssetPanel)
{
m_fallbackSpriteAssetList.DoLayoutList();
}
// SPRITE LIST
EditorGUI.indentLevel = 0;
UI_PanelState.spriteInfoPanel = EditorGUILayout.Foldout(UI_PanelState.spriteInfoPanel, "Sprite List", true, TMP_UIStyleManager.boldFoldout);
if (UI_PanelState.spriteInfoPanel)
{
int arraySize = m_spriteInfoList_prop.arraySize;
int itemsPerPage = 10; // (Screen.height - 292) / 80;
// Display Glyph Management Tools
EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.ExpandWidth(true));
{
// Search Bar implementation
#region DISPLAY SEARCH BAR
EditorGUILayout.BeginHorizontal();
{
EditorGUIUtility.labelWidth = 110f;
EditorGUI.BeginChangeCheck();
string searchPattern = EditorGUILayout.TextField("Sprite Search", m_searchPattern, "SearchTextField");
if (EditorGUI.EndChangeCheck() || m_isSearchDirty)
{
if (string.IsNullOrEmpty(searchPattern) == false)
{
//GUIUtility.keyboardControl = 0;
m_searchPattern = searchPattern.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim();
// Search Glyph Table for potential matches
SearchGlyphTable(m_searchPattern, ref m_searchList);
}
m_isSearchDirty = false;
}
string styleName = string.IsNullOrEmpty(m_searchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton";
if (GUILayout.Button(GUIContent.none, styleName))
{
GUIUtility.keyboardControl = 0;
m_searchPattern = string.Empty;
}
}
EditorGUILayout.EndHorizontal();
#endregion
// Display Page Navigation
if (!string.IsNullOrEmpty(m_searchPattern))
arraySize = m_searchList.Count;
// Display Page Navigation
DisplayGlyphPageNavigation(arraySize, itemsPerPage);
}
EditorGUILayout.EndVertical();
if (arraySize > 0)
{
// Display each SpriteInfo entry using the SpriteInfo property drawer.
for (int i = itemsPerPage * m_page; i < arraySize && i < itemsPerPage * (m_page + 1); i++)
{
// Define the start of the selection region of the element.
Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
int elementIndex = i;
if (!string.IsNullOrEmpty(m_searchPattern))
elementIndex = m_searchList[i];
SerializedProperty spriteInfo = m_spriteInfoList_prop.GetArrayElementAtIndex(elementIndex);
EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(75));
{
EditorGUI.BeginDisabledGroup(i != m_selectedElement);
{
EditorGUILayout.PropertyField(spriteInfo);
}
EditorGUI.EndDisabledGroup();
}
EditorGUILayout.EndVertical();
// Define the end of the selection region of the element.
Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
// Check for Item selection
Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y);
if (DoSelectionCheck(selectionArea))
{
if (m_selectedElement == i)
{
m_selectedElement = -1;
}
else
{
m_selectedElement = i;
GUIUtility.keyboardControl = 0;
}
}
// Draw & Handle Section Area
if (m_selectedElement == i)
{
// Draw selection highlight
TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
// Draw options to MoveUp, MoveDown, Add or Remove Sprites
Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f);
controlRect.width /= 8;
// Move sprite up.
bool guiEnabled = GUI.enabled;
if (i == 0) { GUI.enabled = false; }
if (GUI.Button(controlRect, "Up"))
{
SwapSpriteElement(i, i - 1);
}
GUI.enabled = guiEnabled;
// Move sprite down.
controlRect.x += controlRect.width;
if (i == arraySize - 1) { GUI.enabled = false; }
if (GUI.Button(controlRect, "Down"))
{
SwapSpriteElement(i, i + 1);
}
GUI.enabled = guiEnabled;
// Move sprite to new index
controlRect.x += controlRect.width * 2;
//if (i == arraySize - 1) { GUI.enabled = false; }
m_moveToIndex = EditorGUI.IntField(controlRect, m_moveToIndex);
controlRect.x -= controlRect.width;
if (GUI.Button(controlRect, "Goto"))
{
MoveSpriteElement(i, m_moveToIndex);
}
//controlRect.x += controlRect.width;
GUI.enabled = guiEnabled;
// Add new Sprite
controlRect.x += controlRect.width * 4;
if (GUI.Button(controlRect, "+"))
{
m_spriteInfoList_prop.arraySize += 1;
int index = m_spriteInfoList_prop.arraySize - 1;
SerializedProperty spriteInfo_prop = m_spriteInfoList_prop.GetArrayElementAtIndex(index);
// Copy properties of the selected element
CopySerializedProperty(m_spriteInfoList_prop.GetArrayElementAtIndex(elementIndex), ref spriteInfo_prop);
spriteInfo_prop.FindPropertyRelative("id").intValue = index;
serializedObject.ApplyModifiedProperties();
m_isSearchDirty = true;
}
// Delete selected Sprite
controlRect.x += controlRect.width;
if (m_selectedElement == -1) GUI.enabled = false;
if (GUI.Button(controlRect, "-"))
{
m_spriteInfoList_prop.DeleteArrayElementAtIndex(elementIndex);
m_selectedElement = -1;
serializedObject.ApplyModifiedProperties();
m_isSearchDirty = true;
return;
}
}
}
}
DisplayGlyphPageNavigation(arraySize, itemsPerPage);
EditorGUIUtility.labelWidth = 40f;
EditorGUIUtility.fieldWidth = 20f;
GUILayout.Space(5f);
// GLOBAL TOOLS
#region Global Tools
GUI.enabled = true;
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
Rect rect = EditorGUILayout.GetControlRect(false, 40);
float width = (rect.width - 75f) / 4;
EditorGUI.LabelField(rect, "Global Offsets & Scale", EditorStyles.boldLabel);
rect.x += 70;
bool old_ChangedState = GUI.changed;
GUI.changed = false;
m_xOffset = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 0, rect.y + 20, width - 5f, 18), new GUIContent("OX:"), m_xOffset);
if (GUI.changed) UpdateGlobalProperty("xOffset", m_xOffset);
m_yOffset = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 1, rect.y + 20, width - 5f, 18), new GUIContent("OY:"), m_yOffset);
if (GUI.changed) UpdateGlobalProperty("yOffset", m_yOffset);
m_xAdvance = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 2, rect.y + 20, width - 5f, 18), new GUIContent("ADV."), m_xAdvance);
if (GUI.changed) UpdateGlobalProperty("xAdvance", m_xAdvance);
m_scale = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 3, rect.y + 20, width - 5f, 18), new GUIContent("SF."), m_scale);
if (GUI.changed) UpdateGlobalProperty("scale", m_scale);
EditorGUILayout.EndVertical();
#endregion
GUI.changed = old_ChangedState;
}
if (serializedObject.ApplyModifiedProperties() || evt_cmd == k_UndoRedo || isAssetDirty)
{
isAssetDirty = false;
EditorUtility.SetDirty(target);
//TMPro_EditorUtility.RepaintAll(); // Consider SetDirty
}
// Clear selection if mouse event was not consumed.
GUI.enabled = true;
if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0)
m_selectedElement = -1;
}
/// <summary>
///
/// </summary>
/// <param name="arraySize"></param>
/// <param name="itemsPerPage"></param>
void DisplayGlyphPageNavigation(int arraySize, int itemsPerPage)
{
Rect pagePos = EditorGUILayout.GetControlRect(false, 20);
pagePos.width /= 3;
int shiftMultiplier = Event.current.shift ? 10 : 1; // Page + Shift goes 10 page forward
// Previous Page
GUI.enabled = m_page > 0;
if (GUI.Button(pagePos, "Previous Page"))
{
m_page -= 1 * shiftMultiplier;
//m_isNewPage = true;
}
// Page Counter
GUI.enabled = true;
pagePos.x += pagePos.width;
int totalPages = (int)(arraySize / (float)itemsPerPage + 0.999f);
GUI.Label(pagePos, "Page " + (m_page + 1) + " / " + totalPages, TMP_UIStyleManager.centeredLabel);
// Next Page
pagePos.x += pagePos.width;
GUI.enabled = itemsPerPage * (m_page + 1) < arraySize;
if (GUI.Button(pagePos, "Next Page"))
{
m_page += 1 * shiftMultiplier;
//m_isNewPage = true;
}
// Clamp page range
m_page = Mathf.Clamp(m_page, 0, arraySize / itemsPerPage);
GUI.enabled = true;
}
/// <summary>
/// Method to update the properties of all sprites
/// </summary>
/// <param name="property"></param>
/// <param name="value"></param>
void UpdateGlobalProperty(string property, float value)
{
int arraySize = m_spriteInfoList_prop.arraySize;
for (int i = 0; i < arraySize; i++)
{
SerializedProperty spriteInfo = m_spriteInfoList_prop.GetArrayElementAtIndex(i);
spriteInfo.FindPropertyRelative(property).floatValue = value;
}
GUI.changed = false;
}
// Check if any of the Style elements were clicked on.
private bool DoSelectionCheck(Rect selectionArea)
{
Event currentEvent = Event.current;
switch (currentEvent.type)
{
case EventType.MouseDown:
if (selectionArea.Contains(currentEvent.mousePosition) && currentEvent.button == 0)
{
currentEvent.Use();
return true;
}
break;
}
return false;
}
/// <summary>
/// Swap the sprite item at the currently selected array index to another index.
/// </summary>
/// <param name="selectedIndex">Selected index.</param>
/// <param name="newIndex">New index.</param>
void SwapSpriteElement(int selectedIndex, int newIndex)
{
m_spriteInfoList_prop.MoveArrayElement(selectedIndex, newIndex);
m_spriteInfoList_prop.GetArrayElementAtIndex(selectedIndex).FindPropertyRelative("id").intValue = selectedIndex;
m_spriteInfoList_prop.GetArrayElementAtIndex(newIndex).FindPropertyRelative("id").intValue = newIndex;
m_selectedElement = newIndex;
m_isSearchDirty = true;
}
/// <summary>
/// Move Sprite Element at selected index to another index and reorder sprite list.
/// </summary>
/// <param name="selectedIndex"></param>
/// <param name="newIndex"></param>
void MoveSpriteElement(int selectedIndex, int newIndex)
{
m_spriteInfoList_prop.MoveArrayElement(selectedIndex, newIndex);
// Reorder Sprite Element Index
for (int i = 0; i < m_spriteInfoList_prop.arraySize; i++)
m_spriteInfoList_prop.GetArrayElementAtIndex(i).FindPropertyRelative("id").intValue = i;
m_selectedElement = newIndex;
m_isSearchDirty = true;
}
/// <summary>
///
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
void CopySerializedProperty(SerializedProperty source, ref SerializedProperty target)
{
target.FindPropertyRelative("name").stringValue = source.FindPropertyRelative("name").stringValue;
target.FindPropertyRelative("hashCode").intValue = source.FindPropertyRelative("hashCode").intValue;
target.FindPropertyRelative("x").floatValue = source.FindPropertyRelative("x").floatValue;
target.FindPropertyRelative("y").floatValue = source.FindPropertyRelative("y").floatValue;
target.FindPropertyRelative("width").floatValue = source.FindPropertyRelative("width").floatValue;
target.FindPropertyRelative("height").floatValue = source.FindPropertyRelative("height").floatValue;
target.FindPropertyRelative("xOffset").floatValue = source.FindPropertyRelative("xOffset").floatValue;
target.FindPropertyRelative("yOffset").floatValue = source.FindPropertyRelative("yOffset").floatValue;
target.FindPropertyRelative("xAdvance").floatValue = source.FindPropertyRelative("xAdvance").floatValue;
target.FindPropertyRelative("scale").floatValue = source.FindPropertyRelative("scale").floatValue;
target.FindPropertyRelative("sprite").objectReferenceValue = source.FindPropertyRelative("sprite").objectReferenceValue;
}
/// <summary>
///
/// </summary>
/// <param name="searchPattern"></param>
/// <returns></returns>
void SearchGlyphTable(string searchPattern, ref List<int> searchResults)
{
if (searchResults == null) searchResults = new List<int>();
searchResults.Clear();
int arraySize = m_spriteInfoList_prop.arraySize;
for (int i = 0; i < arraySize; i++)
{
SerializedProperty sourceSprite = m_spriteInfoList_prop.GetArrayElementAtIndex(i);
// Check for potential match against decimal id
int id = sourceSprite.FindPropertyRelative("id").intValue;
if (id.ToString().Contains(searchPattern))
searchResults.Add(i);
// Check for potential match against name
string name = sourceSprite.FindPropertyRelative("name").stringValue.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim();
if (name.Contains(searchPattern))
searchResults.Add(i);
}
}
}
}