|
|
- 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);
- }
- }
-
- }
- }
|