TMP_StyleSheetEditor.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. using UnityEngine;
  2. using UnityEditor;
  3. namespace TMPro.EditorUtilities
  4. {
  5. [CustomPropertyDrawer(typeof(TMP_Style))]
  6. public class StyleDrawer : PropertyDrawer
  7. {
  8. public static readonly float height = 95f;
  9. public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  10. {
  11. return height;
  12. }
  13. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  14. {
  15. SerializedProperty nameProperty = property.FindPropertyRelative("m_Name");
  16. SerializedProperty hashCodeProperty = property.FindPropertyRelative("m_HashCode");
  17. SerializedProperty openingDefinitionProperty = property.FindPropertyRelative("m_OpeningDefinition");
  18. SerializedProperty closingDefinitionProperty = property.FindPropertyRelative("m_ClosingDefinition");
  19. SerializedProperty openingDefinitionArray = property.FindPropertyRelative("m_OpeningTagArray");
  20. SerializedProperty closingDefinitionArray = property.FindPropertyRelative("m_ClosingTagArray");
  21. EditorGUIUtility.labelWidth = 90;
  22. position.height = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
  23. float labelHeight = position.height + 2f;
  24. EditorGUI.BeginChangeCheck();
  25. Rect rect0 = new Rect(position.x, position.y, (position.width) / 2 + 5, position.height);
  26. EditorGUI.PropertyField(rect0, nameProperty);
  27. if (EditorGUI.EndChangeCheck())
  28. {
  29. // Recompute HashCode if name has changed.
  30. hashCodeProperty.intValue = TMP_TextUtilities.GetSimpleHashCode(nameProperty.stringValue);
  31. property.serializedObject.ApplyModifiedProperties();
  32. // Dictionary needs to be updated since HashCode has changed.
  33. TMP_StyleSheet.RefreshStyles();
  34. }
  35. // HashCode
  36. Rect rect1 = new Rect(rect0.x + rect0.width + 5, position.y, 65, position.height);
  37. GUI.Label(rect1, "HashCode");
  38. GUI.enabled = false;
  39. rect1.x += 65;
  40. rect1.width = position.width / 2 - 75;
  41. EditorGUI.PropertyField(rect1, hashCodeProperty, GUIContent.none);
  42. GUI.enabled = true;
  43. // Text Tags
  44. EditorGUI.BeginChangeCheck();
  45. // Opening Tags
  46. position.y += labelHeight;
  47. GUI.Label(position, "Opening Tags");
  48. Rect textRect1 = new Rect(108, position.y, position.width - 86, 35);
  49. openingDefinitionProperty.stringValue = EditorGUI.TextArea(textRect1, openingDefinitionProperty.stringValue);
  50. if (EditorGUI.EndChangeCheck())
  51. {
  52. // If any properties have changed, we need to update the Opening and Closing Arrays.
  53. int size = openingDefinitionProperty.stringValue.Length;
  54. // Adjust array size to match new string length.
  55. if (openingDefinitionArray.arraySize != size) openingDefinitionArray.arraySize = size;
  56. for (int i = 0; i < size; i++)
  57. {
  58. SerializedProperty element = openingDefinitionArray.GetArrayElementAtIndex(i);
  59. element.intValue = openingDefinitionProperty.stringValue[i];
  60. }
  61. }
  62. EditorGUI.BeginChangeCheck();
  63. // Closing Tags
  64. position.y += 38;
  65. GUI.Label(position, "Closing Tags");
  66. Rect textRect2 = new Rect(108, position.y, position.width - 86, 35);
  67. closingDefinitionProperty.stringValue = EditorGUI.TextArea(textRect2, closingDefinitionProperty.stringValue);
  68. if (EditorGUI.EndChangeCheck())
  69. {
  70. // If any properties have changed, we need to update the Opening and Closing Arrays.
  71. int size = closingDefinitionProperty.stringValue.Length;
  72. // Adjust array size to match new string length.
  73. if (closingDefinitionArray.arraySize != size) closingDefinitionArray.arraySize = size;
  74. for (int i = 0; i < size; i++)
  75. {
  76. SerializedProperty element = closingDefinitionArray.GetArrayElementAtIndex(i);
  77. element.intValue = closingDefinitionProperty.stringValue[i];
  78. }
  79. }
  80. }
  81. }
  82. [CustomEditor(typeof(TMP_StyleSheet)), CanEditMultipleObjects]
  83. public class TMP_StyleEditor : Editor
  84. {
  85. SerializedProperty m_StyleListProp;
  86. int m_SelectedElement = -1;
  87. //private Event m_CurrentEvent;
  88. int m_Page;
  89. void OnEnable()
  90. {
  91. m_StyleListProp = serializedObject.FindProperty("m_StyleList");
  92. }
  93. public override void OnInspectorGUI()
  94. {
  95. Event currentEvent = Event.current;
  96. serializedObject.Update();
  97. int arraySize = m_StyleListProp.arraySize;
  98. int itemsPerPage = (Screen.height - 178) / 111;
  99. if (arraySize > 0)
  100. {
  101. // Display each Style entry using the StyleDrawer PropertyDrawer.
  102. for (int i = itemsPerPage * m_Page; i < arraySize && i < itemsPerPage * (m_Page + 1); i++)
  103. {
  104. // Define the start of the selection region of the element.
  105. Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
  106. EditorGUILayout.BeginVertical(EditorStyles.helpBox);
  107. SerializedProperty spriteInfo = m_StyleListProp.GetArrayElementAtIndex(i);
  108. EditorGUI.BeginChangeCheck();
  109. EditorGUILayout.PropertyField(spriteInfo);
  110. EditorGUILayout.EndVertical();
  111. if (EditorGUI.EndChangeCheck())
  112. {
  113. //
  114. }
  115. // Define the end of the selection region of the element.
  116. Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
  117. // Check for Item selection
  118. Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y);
  119. if (DoSelectionCheck(selectionArea))
  120. {
  121. if (m_SelectedElement == i)
  122. {
  123. m_SelectedElement = -1;
  124. }
  125. else
  126. {
  127. m_SelectedElement = i;
  128. GUIUtility.keyboardControl = 0;
  129. }
  130. }
  131. // Handle Selection Highlighting
  132. if (m_SelectedElement == i)
  133. {
  134. TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
  135. }
  136. }
  137. }
  138. int shiftMultiplier = currentEvent.shift ? 10 : 1; // Page + Shift goes 10 page forward
  139. GUILayout.Space(-3f);
  140. Rect pagePos = EditorGUILayout.GetControlRect(false, 20);
  141. pagePos.width /= 6;
  142. // Return if we can't display any items.
  143. if (itemsPerPage == 0) return;
  144. // Add new style.
  145. pagePos.x += pagePos.width * 4;
  146. if (GUI.Button(pagePos, "+"))
  147. {
  148. m_StyleListProp.arraySize += 1;
  149. serializedObject.ApplyModifiedProperties();
  150. TMP_StyleSheet.RefreshStyles();
  151. }
  152. // Delete selected style.
  153. pagePos.x += pagePos.width;
  154. if (m_SelectedElement == -1) GUI.enabled = false;
  155. if (GUI.Button(pagePos, "-"))
  156. {
  157. if (m_SelectedElement != -1)
  158. m_StyleListProp.DeleteArrayElementAtIndex(m_SelectedElement);
  159. m_SelectedElement = -1;
  160. serializedObject.ApplyModifiedProperties();
  161. TMP_StyleSheet.RefreshStyles();
  162. }
  163. GUILayout.Space(5f);
  164. pagePos = EditorGUILayout.GetControlRect(false, 20);
  165. pagePos.width /= 3;
  166. // Previous Page
  167. if (m_Page > 0) GUI.enabled = true;
  168. else GUI.enabled = false;
  169. if (GUI.Button(pagePos, "Previous"))
  170. m_Page -= 1 * shiftMultiplier;
  171. // PAGE COUNTER
  172. GUI.enabled = true;
  173. pagePos.x += pagePos.width;
  174. int totalPages = (int)(arraySize / (float)itemsPerPage + 0.999f);
  175. GUI.Label(pagePos, "Page " + (m_Page + 1) + " / " + totalPages, TMP_UIStyleManager.centeredLabel);
  176. // Next Page
  177. pagePos.x += pagePos.width;
  178. if (itemsPerPage * (m_Page + 1) < arraySize) GUI.enabled = true;
  179. else GUI.enabled = false;
  180. if (GUI.Button(pagePos, "Next"))
  181. m_Page += 1 * shiftMultiplier;
  182. // Clamp page range
  183. m_Page = Mathf.Clamp(m_Page, 0, arraySize / itemsPerPage);
  184. if (serializedObject.ApplyModifiedProperties())
  185. TMPro_EventManager.ON_TEXT_STYLE_PROPERTY_CHANGED(true);
  186. // Clear selection if mouse event was not consumed.
  187. GUI.enabled = true;
  188. if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0)
  189. m_SelectedElement = -1;
  190. }
  191. // Check if any of the Style elements were clicked on.
  192. static bool DoSelectionCheck(Rect selectionArea)
  193. {
  194. Event currentEvent = Event.current;
  195. switch (currentEvent.type)
  196. {
  197. case EventType.MouseDown:
  198. if (selectionArea.Contains(currentEvent.mousePosition) && currentEvent.button == 0)
  199. {
  200. currentEvent.Use();
  201. return true;
  202. }
  203. break;
  204. }
  205. return false;
  206. }
  207. }
  208. }