Нема описа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TMP_SpriteCharacterPropertyDrawer.cs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. using UnityEngine;
  2. using UnityEngine.TextCore;
  3. using UnityEditor;
  4. using System.Collections.Generic;
  5. namespace TMPro.EditorUtilities
  6. {
  7. [CustomPropertyDrawer(typeof(TMP_SpriteCharacter))]
  8. public class TMP_SpriteCharacterPropertyDrawer : PropertyDrawer
  9. {
  10. int m_GlyphSelectedForEditing = -1;
  11. private Dictionary<uint, GlyphProxy> m_GlyphLookupDictionary;
  12. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  13. {
  14. SerializedProperty prop_SpriteName = property.FindPropertyRelative("m_Name");
  15. SerializedProperty prop_SpriteUnicode = property.FindPropertyRelative("m_Unicode");
  16. SerializedProperty prop_SpriteGlyphIndex = property.FindPropertyRelative("m_GlyphIndex");
  17. SerializedProperty prop_SpriteScale = property.FindPropertyRelative("m_Scale");
  18. GUIStyle style = new GUIStyle(EditorStyles.label);
  19. style.richText = true;
  20. EditorGUIUtility.labelWidth = 40f;
  21. EditorGUIUtility.fieldWidth = 50;
  22. Rect rect = new Rect(position.x + 60, position.y, position.width, 49);
  23. // Display non-editable fields
  24. if (GUI.enabled == false)
  25. {
  26. // Sprite Character Index
  27. int spriteCharacterIndex;
  28. int.TryParse(property.displayName.Split(' ')[1], out spriteCharacterIndex);
  29. EditorGUI.LabelField(new Rect(rect.x, rect.y, 75f, 18), new GUIContent("Index: <color=#FFFF80>" + spriteCharacterIndex + "</color>"), style);
  30. EditorGUI.LabelField(new Rect(rect.x + 75f, rect.y, 120f, 18), new GUIContent("Unicode: <color=#FFFF80>0x" + prop_SpriteUnicode.intValue.ToString("X") + "</color>"), style);
  31. EditorGUI.LabelField(new Rect(rect.x + 195f, rect.y, rect.width - 255, 18), new GUIContent("Name: <color=#FFFF80>" + prop_SpriteName.stringValue + "</color>"), style);
  32. EditorGUI.LabelField(new Rect(rect.x, rect.y + 18, 120, 18), new GUIContent("Glyph ID: <color=#FFFF80>" + prop_SpriteGlyphIndex.intValue + "</color>"), style);
  33. // Draw Sprite Glyph (if exists)
  34. DrawSpriteGlyph((uint)prop_SpriteGlyphIndex.intValue, position, property);
  35. EditorGUI.LabelField(new Rect(rect.x, rect.y + 36, 80, 18), new GUIContent("Scale: <color=#FFFF80>" + prop_SpriteScale.floatValue + "</color>"), style);
  36. }
  37. else // Display editable fields
  38. {
  39. // Get a reference to the underlying Sprite Asset
  40. TMP_SpriteAsset spriteAsset = property.serializedObject.targetObject as TMP_SpriteAsset;
  41. // Sprite Character Index
  42. int spriteCharacterIndex;
  43. int.TryParse(property.displayName.Split(' ')[1], out spriteCharacterIndex);
  44. EditorGUI.LabelField(new Rect(rect.x, rect.y, 75f, 18), new GUIContent("Index: <color=#FFFF80>" + spriteCharacterIndex + "</color>"), style);
  45. EditorGUIUtility.labelWidth = 55f;
  46. GUI.SetNextControlName("Unicode Input");
  47. EditorGUI.BeginChangeCheck();
  48. string unicode = EditorGUI.DelayedTextField(new Rect(rect.x + 75f, rect.y, 120, 18), "Unicode:", prop_SpriteUnicode.intValue.ToString("X"));
  49. if (GUI.GetNameOfFocusedControl() == "Unicode Input")
  50. {
  51. //Filter out unwanted characters.
  52. char chr = Event.current.character;
  53. if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F'))
  54. {
  55. Event.current.character = '\0';
  56. }
  57. }
  58. if (EditorGUI.EndChangeCheck())
  59. {
  60. // Update Unicode value
  61. prop_SpriteUnicode.intValue = TMP_TextUtilities.StringHexToInt(unicode);
  62. spriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
  63. }
  64. EditorGUIUtility.labelWidth = 41f;
  65. EditorGUI.BeginChangeCheck();
  66. EditorGUI.DelayedTextField(new Rect(rect.x + 195f, rect.y, rect.width - 255, 18), prop_SpriteName, new GUIContent("Name:"));
  67. if (EditorGUI.EndChangeCheck())
  68. {
  69. spriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
  70. }
  71. EditorGUIUtility.labelWidth = 59f;
  72. EditorGUI.BeginChangeCheck();
  73. EditorGUI.DelayedIntField(new Rect(rect.x, rect.y + 18, 100, 18), prop_SpriteGlyphIndex, new GUIContent("Glyph ID:"));
  74. if (EditorGUI.EndChangeCheck())
  75. {
  76. spriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
  77. }
  78. // Draw Sprite Glyph (if exists)
  79. DrawSpriteGlyph((uint)prop_SpriteGlyphIndex.intValue, position, property);
  80. int glyphIndex = prop_SpriteGlyphIndex.intValue;
  81. // Reset glyph selection if new character has been selected.
  82. if (GUI.enabled && m_GlyphSelectedForEditing != glyphIndex)
  83. m_GlyphSelectedForEditing = -1;
  84. // Display button to edit the glyph data.
  85. if (GUI.Button(new Rect(rect.x + 120, rect.y + 18, 75, 18), new GUIContent("Edit Glyph")))
  86. {
  87. if (m_GlyphSelectedForEditing == -1)
  88. m_GlyphSelectedForEditing = glyphIndex;
  89. else
  90. m_GlyphSelectedForEditing = -1;
  91. // Button clicks should not result in potential change.
  92. GUI.changed = false;
  93. }
  94. // Show the glyph property drawer if selected
  95. if (glyphIndex == m_GlyphSelectedForEditing && GUI.enabled)
  96. {
  97. if (spriteAsset != null)
  98. {
  99. // Lookup glyph and draw glyph (if available)
  100. int elementIndex = spriteAsset.spriteGlyphTable.FindIndex(item => item.index == glyphIndex);
  101. if (elementIndex != -1)
  102. {
  103. // Get a reference to the Sprite Glyph Table
  104. SerializedProperty prop_SpriteGlyphTable = property.serializedObject.FindProperty("m_GlyphTable");
  105. SerializedProperty prop_SpriteGlyph = prop_SpriteGlyphTable.GetArrayElementAtIndex(elementIndex);
  106. SerializedProperty prop_GlyphMetrics = prop_SpriteGlyph.FindPropertyRelative("m_Metrics");
  107. SerializedProperty prop_GlyphRect = prop_SpriteGlyph.FindPropertyRelative("m_GlyphRect");
  108. Rect newRect = EditorGUILayout.GetControlRect(false, 115);
  109. EditorGUI.DrawRect(new Rect(newRect.x + 62, newRect.y - 20, newRect.width - 62, newRect.height - 5), new Color(0.1f, 0.1f, 0.1f, 0.45f));
  110. EditorGUI.DrawRect(new Rect(newRect.x + 63, newRect.y - 19, newRect.width - 64, newRect.height - 7), new Color(0.3f, 0.3f, 0.3f, 0.8f));
  111. // Display GlyphRect
  112. newRect.x += 65;
  113. newRect.y -= 18;
  114. newRect.width += 5;
  115. EditorGUI.PropertyField(newRect, prop_GlyphRect);
  116. // Display GlyphMetrics
  117. newRect.y += 45;
  118. EditorGUI.PropertyField(newRect, prop_GlyphMetrics);
  119. rect.y += 120;
  120. }
  121. }
  122. }
  123. EditorGUIUtility.labelWidth = 39f;
  124. EditorGUI.PropertyField(new Rect(rect.x, rect.y + 36, 80, 18), prop_SpriteScale, new GUIContent("Scale:"));
  125. }
  126. }
  127. public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  128. {
  129. return 58;
  130. }
  131. void DrawSpriteGlyph(uint glyphIndex, Rect position, SerializedProperty property)
  132. {
  133. if (m_GlyphLookupDictionary == null)
  134. m_GlyphLookupDictionary = TMP_PropertyDrawerUtilities.GetGlyphProxyLookupDictionary(property.serializedObject);
  135. // Try getting a reference to the glyph for the given glyph index.
  136. if (!m_GlyphLookupDictionary.TryGetValue(glyphIndex, out GlyphProxy glyph))
  137. return;
  138. GlyphRect glyphRect = glyph.glyphRect;
  139. // Get a reference to the sprite texture
  140. Texture tex = property.serializedObject.FindProperty("spriteSheet").objectReferenceValue as Texture;
  141. if (tex == null)
  142. {
  143. Debug.LogWarning("Please assign a valid Sprite Atlas texture to the [" + property.serializedObject.targetObject.name + "] Sprite Asset.", property.serializedObject.targetObject);
  144. return;
  145. }
  146. Vector2 spriteTexPosition = new Vector2(position.x, position.y);
  147. Vector2 spriteSize = new Vector2(48, 48);
  148. Vector2 alignmentOffset = new Vector2((58 - spriteSize.x) / 2, (58 - spriteSize.y) / 2);
  149. float x = glyphRect.x;
  150. float y = glyphRect.y;
  151. float spriteWidth = glyphRect.width;
  152. float spriteHeight = glyphRect.height;
  153. if (spriteWidth >= spriteHeight)
  154. {
  155. spriteSize.y = spriteHeight * spriteSize.x / spriteWidth;
  156. spriteTexPosition.y += (spriteSize.x - spriteSize.y) / 2;
  157. }
  158. else
  159. {
  160. spriteSize.x = spriteWidth * spriteSize.y / spriteHeight;
  161. spriteTexPosition.x += (spriteSize.y - spriteSize.x) / 2;
  162. }
  163. // Compute the normalized texture coordinates
  164. Rect texCoords = new Rect(x / tex.width, y / tex.height, spriteWidth / tex.width, spriteHeight / tex.height);
  165. GUI.DrawTextureWithTexCoords(new Rect(spriteTexPosition.x + alignmentOffset.x, spriteTexPosition.y + alignmentOffset.y, spriteSize.x, spriteSize.y), tex, texCoords, true);
  166. }
  167. }
  168. }