A game about forced loneliness, made by TACStudios
1using UnityEngine;
2using UnityEditor;
3using System.Collections.Generic;
4using System.Linq;
5using UnityEngine.TextCore.LowLevel;
6
7
8namespace TMPro.EditorUtilities
9{
10 public abstract class TMP_BaseEditorPanel : Editor
11 {
12 //Labels and Tooltips
13 static readonly GUIContent k_RtlToggleLabel = new GUIContent("Enable RTL Editor", "Reverses text direction and allows right to left editing.");
14 //static readonly GUIContent k_MainSettingsLabel = new GUIContent("Main Settings");
15 static readonly GUIContent k_FontAssetLabel = new GUIContent("Font Asset", "The Font Asset containing the glyphs that can be rendered for this text.");
16 static readonly GUIContent k_MaterialPresetLabel = new GUIContent("Material Preset", "The material used for rendering. Only materials created from the Font Asset can be used.");
17 static readonly GUIContent k_StyleLabel = new GUIContent("Text Style", "The style from a style sheet to be applied to the text.");
18 static readonly GUIContent k_AutoSizeLabel = new GUIContent("Auto Size", "Auto sizes the text to fit the available space.");
19 static readonly GUIContent k_FontSizeLabel = new GUIContent("Font Size", "The size the text will be rendered at in points.");
20 static readonly GUIContent k_AutoSizeOptionsLabel = new GUIContent("Auto Size Options");
21 static readonly GUIContent k_MinLabel = new GUIContent("Min", "The minimum font size.");
22 static readonly GUIContent k_MaxLabel = new GUIContent("Max", "The maximum font size.");
23 static readonly GUIContent k_WdLabel = new GUIContent("WD%", "Compresses character width up to this value before reducing font size.");
24 static readonly GUIContent k_LineLabel = new GUIContent("Line", "Negative value only. Compresses line height down to this value before reducing font size.");
25 static readonly GUIContent k_FontStyleLabel = new GUIContent("Font Style", "Styles to apply to the text such as Bold or Italic.");
26
27 static readonly GUIContent k_BoldLabel = new GUIContent("B", "Bold");
28 static readonly GUIContent k_ItalicLabel = new GUIContent("I", "Italic");
29 static readonly GUIContent k_UnderlineLabel = new GUIContent("U", "Underline");
30 static readonly GUIContent k_StrikethroughLabel = new GUIContent("S", "Strikethrough");
31 static readonly GUIContent k_LowercaseLabel = new GUIContent("ab", "Lowercase");
32 static readonly GUIContent k_UppercaseLabel = new GUIContent("AB", "Uppercase");
33 static readonly GUIContent k_SmallcapsLabel = new GUIContent("SC", "Smallcaps");
34
35 static readonly GUIContent k_ColorModeLabel = new GUIContent("Color Mode", "The type of gradient to use.");
36 static readonly GUIContent k_BaseColorLabel = new GUIContent("Vertex Color", "The base color of the text vertices.");
37 static readonly GUIContent k_ColorPresetLabel = new GUIContent("Color Preset", "A Color Preset which override the local color settings.");
38 static readonly GUIContent k_ColorGradientLabel = new GUIContent("Color Gradient", "The gradient color applied over the Vertex Color. Can be locally set or driven by a Gradient Asset.");
39 static readonly GUIContent k_CorenerColorsLabel = new GUIContent("Colors", "The color composition of the gradient.");
40 static readonly GUIContent k_OverrideTagsLabel = new GUIContent("Override Tags", "Whether the color settings override the <color> tag.");
41
42 static readonly GUIContent k_SpacingOptionsLabel = new GUIContent("Spacing Options (em)", "Spacing adjustments between different elements of the text. Values are in font units where a value of 1 equals 1/100em.");
43 static readonly GUIContent k_CharacterSpacingLabel = new GUIContent("Character");
44 static readonly GUIContent k_WordSpacingLabel = new GUIContent("Word");
45 static readonly GUIContent k_LineSpacingLabel = new GUIContent("Line");
46 static readonly GUIContent k_ParagraphSpacingLabel = new GUIContent("Paragraph");
47
48 static readonly GUIContent k_AlignmentLabel = new GUIContent("Alignment", "Horizontal and vertical alignment of the text within its container.");
49 static readonly GUIContent k_WrapMixLabel = new GUIContent("Wrap Mix (W <-> C)", "How much to favor words versus characters when distributing the text.");
50
51 static readonly GUIContent k_WrappingLabel = new GUIContent("Wrapping", "Wraps text to the next line when reaching the edge of the container.");
52 static readonly GUIContent[] k_WrappingOptions = { new GUIContent("Disabled"), new GUIContent("Enabled") };
53 static readonly GUIContent k_OverflowLabel = new GUIContent("Overflow", "How to display text which goes past the edge of the container.");
54
55 static readonly GUIContent k_MarginsLabel = new GUIContent("Margins", "The space between the text and the edge of its container.");
56 static readonly GUIContent k_GeometrySortingLabel = new GUIContent("Geometry Sorting", "The order in which text geometry is sorted. Used to adjust the way overlapping characters are displayed.");
57 static readonly GUIContent k_IsTextObjectScaleStatic = new GUIContent("Is Scale Static", "Controls whether a text object will be excluded from the InteralUpdate callback to handle scale changes of the text object or its parent(s).");
58 static readonly GUIContent k_RichTextLabel = new GUIContent("Rich Text", "Enables the use of rich text tags such as <color> and <font>.");
59 static readonly GUIContent k_EscapeCharactersLabel = new GUIContent("Parse Escape Characters", "Whether to display strings such as \"\\n\" as is or replace them by the character they represent.");
60 static readonly GUIContent k_VisibleDescenderLabel = new GUIContent("Visible Descender", "Compute descender values from visible characters only. Used to adjust layout behavior when hiding and revealing characters dynamically.");
61 static readonly GUIContent k_EmojiFallbackSupportLabel = new GUIContent("Emoji Fallback Support", "When text contains Emojis, try using and displaying those from the potential Text Assets assigned in the TMP Settings Emoji Fallback Text Assets.");
62 static readonly GUIContent k_SpriteAssetLabel = new GUIContent("Sprite Asset", "The Sprite Asset used when NOT specifically referencing one using <sprite=\"Sprite Asset Name\">.");
63 static readonly GUIContent k_StyleSheetAssetLabel = new GUIContent("Style Sheet Asset", "The Style Sheet Asset used by this text object.");
64
65 static readonly GUIContent k_HorizontalMappingLabel = new GUIContent("Horizontal Mapping", "Horizontal UV mapping when using a shader with a texture face option.");
66 static readonly GUIContent k_VerticalMappingLabel = new GUIContent("Vertical Mapping", "Vertical UV mapping when using a shader with a texture face option.");
67 static readonly GUIContent k_LineOffsetLabel = new GUIContent("Line Offset", "Adds an horizontal offset to each successive line. Used for slanted texturing.");
68
69 static readonly GUIContent k_FontFeaturesLabel = new GUIContent("Font Features", "Font features available for the primary font asset assigned to the text component.");
70 static readonly GUIContent k_PaddingLabel = new GUIContent("Extra Padding", "Adds some padding between the characters and the edge of the text mesh. Can reduce graphical errors when displaying small text.");
71
72 static readonly GUIContent k_LeftLabel = new GUIContent("Left");
73 static readonly GUIContent k_TopLabel = new GUIContent("Top");
74 static readonly GUIContent k_RightLabel = new GUIContent("Right");
75 static readonly GUIContent k_BottomLabel = new GUIContent("Bottom");
76
77 protected static readonly GUIContent k_ExtraSettingsLabel = new GUIContent("Extra Settings");
78 protected static string[] k_UiStateLabel = new string[] { "<i>(Click to collapse)</i> ", "<i>(Click to expand)</i> " };
79
80 static Dictionary<int, TMP_Style> k_AvailableStyles = new Dictionary<int, TMP_Style>();
81 protected Dictionary<int, int> m_TextStyleIndexLookup = new Dictionary<int, int>();
82
83 protected struct Foldout
84 {
85 // Track Inspector foldout panel states, globally.
86 public static bool extraSettings = false;
87 public static bool materialInspector = true;
88 }
89
90 protected static int s_EventId;
91
92 public int selAlignGridA;
93 public int selAlignGridB;
94
95 protected SerializedProperty m_TextProp;
96
97 protected SerializedProperty m_IsRightToLeftProp;
98 protected string m_RtlText;
99
100 protected SerializedProperty m_FontAssetProp;
101
102 protected SerializedProperty m_FontSharedMaterialProp;
103 protected Material[] m_MaterialPresets;
104 protected GUIContent[] m_MaterialPresetNames;
105 protected Dictionary<int, int> m_MaterialPresetIndexLookup = new Dictionary<int, int>();
106 protected int m_MaterialPresetSelectionIndex;
107 protected bool m_IsPresetListDirty;
108
109 protected List<TMP_Style> m_Styles = new List<TMP_Style>();
110 protected GUIContent[] m_StyleNames;
111 protected int m_StyleSelectionIndex;
112
113 protected SerializedProperty m_FontStyleProp;
114
115 protected SerializedProperty m_FontColorProp;
116 protected SerializedProperty m_EnableVertexGradientProp;
117 protected SerializedProperty m_FontColorGradientProp;
118 protected SerializedProperty m_FontColorGradientPresetProp;
119 protected SerializedProperty m_OverrideHtmlColorProp;
120
121 protected SerializedProperty m_FontSizeProp;
122 protected SerializedProperty m_FontSizeBaseProp;
123
124 protected SerializedProperty m_AutoSizingProp;
125 protected SerializedProperty m_FontSizeMinProp;
126 protected SerializedProperty m_FontSizeMaxProp;
127
128 protected SerializedProperty m_LineSpacingMaxProp;
129 protected SerializedProperty m_CharWidthMaxAdjProp;
130
131 protected SerializedProperty m_CharacterSpacingProp;
132 protected SerializedProperty m_WordSpacingProp;
133 protected SerializedProperty m_LineSpacingProp;
134 protected SerializedProperty m_ParagraphSpacingProp;
135
136 protected SerializedProperty m_TextAlignmentProp;
137
138 protected SerializedProperty m_HorizontalAlignmentProp;
139 protected SerializedProperty m_VerticalAlignmentProp;
140
141 protected SerializedProperty m_HorizontalMappingProp;
142 protected SerializedProperty m_VerticalMappingProp;
143 protected SerializedProperty m_UvLineOffsetProp;
144
145 protected SerializedProperty m_TextWrappingModeProp;
146 protected SerializedProperty m_WordWrappingRatiosProp;
147 protected SerializedProperty m_TextOverflowModeProp;
148 protected SerializedProperty m_PageToDisplayProp;
149 protected SerializedProperty m_LinkedTextComponentProp;
150 protected SerializedProperty m_ParentLinkedTextComponentProp;
151
152 protected SerializedProperty m_FontFeaturesActiveProp;
153
154 protected SerializedProperty m_IsRichTextProp;
155
156 protected SerializedProperty m_HasFontAssetChangedProp;
157
158 protected SerializedProperty m_EnableExtraPaddingProp;
159 protected SerializedProperty m_CheckPaddingRequiredProp;
160 protected SerializedProperty m_EnableEscapeCharacterParsingProp;
161 protected SerializedProperty m_UseMaxVisibleDescenderProp;
162 protected SerializedProperty m_GeometrySortingOrderProp;
163 protected SerializedProperty m_IsTextObjectScaleStaticProp;
164
165 protected SerializedProperty m_EmojiFallbackSupportProp;
166
167 protected SerializedProperty m_SpriteAssetProp;
168
169 protected SerializedProperty m_StyleSheetAssetProp;
170 protected SerializedProperty m_TextStyleHashCodeProp;
171
172 protected SerializedProperty m_MarginProp;
173
174 protected SerializedProperty m_ColorModeProp;
175
176 protected bool m_HavePropertiesChanged;
177
178 protected TMP_Text m_TextComponent;
179 protected TMP_Text m_PreviousLinkedTextComponent;
180 protected RectTransform m_RectTransform;
181
182 protected Material m_TargetMaterial;
183
184 protected Vector3[] m_RectCorners = new Vector3[4];
185 protected Vector3[] m_HandlePoints = new Vector3[4];
186
187 private static readonly string[] k_FontFeatures = new string[] { "kern", "liga", "mark", "mkmk" };
188
189 protected virtual void OnEnable()
190 {
191 m_TextProp = serializedObject.FindProperty("m_text");
192 m_IsRightToLeftProp = serializedObject.FindProperty("m_isRightToLeft");
193 m_FontAssetProp = serializedObject.FindProperty("m_fontAsset");
194 m_FontSharedMaterialProp = serializedObject.FindProperty("m_sharedMaterial");
195
196 m_FontStyleProp = serializedObject.FindProperty("m_fontStyle");
197
198 m_FontSizeProp = serializedObject.FindProperty("m_fontSize");
199 m_FontSizeBaseProp = serializedObject.FindProperty("m_fontSizeBase");
200
201 m_AutoSizingProp = serializedObject.FindProperty("m_enableAutoSizing");
202 m_FontSizeMinProp = serializedObject.FindProperty("m_fontSizeMin");
203 m_FontSizeMaxProp = serializedObject.FindProperty("m_fontSizeMax");
204
205 m_LineSpacingMaxProp = serializedObject.FindProperty("m_lineSpacingMax");
206 m_CharWidthMaxAdjProp = serializedObject.FindProperty("m_charWidthMaxAdj");
207
208 // Colors & Gradient
209 m_FontColorProp = serializedObject.FindProperty("m_fontColor");
210 m_EnableVertexGradientProp = serializedObject.FindProperty("m_enableVertexGradient");
211 m_FontColorGradientProp = serializedObject.FindProperty("m_fontColorGradient");
212 m_FontColorGradientPresetProp = serializedObject.FindProperty("m_fontColorGradientPreset");
213 m_OverrideHtmlColorProp = serializedObject.FindProperty("m_overrideHtmlColors");
214
215 m_CharacterSpacingProp = serializedObject.FindProperty("m_characterSpacing");
216 m_WordSpacingProp = serializedObject.FindProperty("m_wordSpacing");
217 m_LineSpacingProp = serializedObject.FindProperty("m_lineSpacing");
218 m_ParagraphSpacingProp = serializedObject.FindProperty("m_paragraphSpacing");
219
220 m_TextAlignmentProp = serializedObject.FindProperty("m_textAlignment");
221 m_HorizontalAlignmentProp = serializedObject.FindProperty("m_HorizontalAlignment");
222 m_VerticalAlignmentProp = serializedObject.FindProperty("m_VerticalAlignment");
223
224 m_HorizontalMappingProp = serializedObject.FindProperty("m_horizontalMapping");
225 m_VerticalMappingProp = serializedObject.FindProperty("m_verticalMapping");
226 m_UvLineOffsetProp = serializedObject.FindProperty("m_uvLineOffset");
227
228 m_TextWrappingModeProp = serializedObject.FindProperty("m_TextWrappingMode");
229 m_WordWrappingRatiosProp = serializedObject.FindProperty("m_wordWrappingRatios");
230 m_TextOverflowModeProp = serializedObject.FindProperty("m_overflowMode");
231 m_PageToDisplayProp = serializedObject.FindProperty("m_pageToDisplay");
232 m_LinkedTextComponentProp = serializedObject.FindProperty("m_linkedTextComponent");
233 m_ParentLinkedTextComponentProp = serializedObject.FindProperty("parentLinkedComponent");
234
235 m_FontFeaturesActiveProp = serializedObject.FindProperty("m_ActiveFontFeatures");
236
237 m_EnableExtraPaddingProp = serializedObject.FindProperty("m_enableExtraPadding");
238 m_IsRichTextProp = serializedObject.FindProperty("m_isRichText");
239 m_CheckPaddingRequiredProp = serializedObject.FindProperty("checkPaddingRequired");
240 m_EnableEscapeCharacterParsingProp = serializedObject.FindProperty("m_parseCtrlCharacters");
241 m_UseMaxVisibleDescenderProp = serializedObject.FindProperty("m_useMaxVisibleDescender");
242
243 m_GeometrySortingOrderProp = serializedObject.FindProperty("m_geometrySortingOrder");
244 m_IsTextObjectScaleStaticProp = serializedObject.FindProperty("m_IsTextObjectScaleStatic");
245
246 m_EmojiFallbackSupportProp = serializedObject.FindProperty("m_EmojiFallbackSupport");
247
248 m_SpriteAssetProp = serializedObject.FindProperty("m_spriteAsset");
249
250 m_StyleSheetAssetProp = serializedObject.FindProperty("m_StyleSheet");
251 m_TextStyleHashCodeProp = serializedObject.FindProperty("m_TextStyleHashCode");
252
253 m_MarginProp = serializedObject.FindProperty("m_margin");
254
255 m_HasFontAssetChangedProp = serializedObject.FindProperty("m_hasFontAssetChanged");
256
257 m_ColorModeProp = serializedObject.FindProperty("m_colorMode");
258
259 m_TextComponent = (TMP_Text)target;
260 m_RectTransform = m_TextComponent.rectTransform;
261
262 // Restore Previous Linked Text Component
263 m_PreviousLinkedTextComponent = m_TextComponent.linkedTextComponent;
264
265 // Create new Material Editor if one does not exists
266 m_TargetMaterial = m_TextComponent.fontSharedMaterial;
267
268 // Set material inspector visibility
269 if (m_TargetMaterial != null)
270 UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded(m_TargetMaterial, Foldout.materialInspector);
271
272 // Find all Material Presets matching the current Font Asset Material
273 m_MaterialPresetNames = GetMaterialPresets();
274
275 // Get Styles from Style Sheet
276 if (TMP_Settings.instance != null)
277 m_StyleNames = GetStyleNames();
278
279 // Get list of font features for the primary font asset assigned to the text component
280 // FontEngine.LoadFontFace(m_TextComponent.font.SourceFont_EditorRef);
281 // OTL_Table gposTable = UnityEngine.TextCore.LowLevel.FontEngine.GetOpenTypeLayoutTable(OTL_TableType.GPOS);
282 // OTL_Table gsubTable = UnityEngine.TextCore.LowLevel.FontEngine.GetOpenTypeLayoutTable(OTL_TableType.GSUB);
283 //
284 // HashSet<string> fontFeatures = new HashSet<string>();
285 //
286 // foreach (OTL_Feature feature in gposTable.features)
287 // {
288 // fontFeatures.Add(feature.tag);
289 // }
290 //
291 // foreach (OTL_Feature feature in gsubTable.features)
292 // {
293 // fontFeatures.Add(feature.tag);
294 // }
295 //
296 // m_FontFeatures = fontFeatures.OrderBy(item => item).ToArray();
297
298 // Register to receive events when style sheets are modified.
299 TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
300
301 // Initialize the Event Listener for Undo Events.
302 Undo.undoRedoPerformed += OnUndoRedo;
303 }
304
305 protected virtual void OnDisable()
306 {
307 // Set material inspector visibility
308 if (m_TargetMaterial != null)
309 Foldout.materialInspector = UnityEditorInternal.InternalEditorUtility.GetIsInspectorExpanded(m_TargetMaterial);
310
311 if (Undo.undoRedoPerformed != null)
312 Undo.undoRedoPerformed -= OnUndoRedo;
313
314 // Unregister from style sheet related events.
315 TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
316 }
317
318 // Event received when Text Styles are changed.
319 void ON_TEXT_STYLE_CHANGED(bool isChanged)
320 {
321 m_StyleNames = GetStyleNames();
322 }
323
324 public override void OnInspectorGUI()
325 {
326 // Make sure Multi selection only includes TMP Text objects.
327 if (IsMixSelectionTypes()) return;
328
329 serializedObject.Update();
330
331 DrawTextInput();
332
333 DrawMainSettings();
334
335 DrawExtraSettings();
336
337 EditorGUILayout.Space();
338
339 if (serializedObject.ApplyModifiedProperties() || m_HavePropertiesChanged)
340 {
341 m_TextComponent.havePropertiesChanged = true;
342 m_HavePropertiesChanged = false;
343 }
344 }
345
346 public void OnSceneGUI()
347 {
348 if (IsMixSelectionTypes()) return;
349
350 // Margin Frame & Handles
351 m_RectTransform.GetWorldCorners(m_RectCorners);
352 Vector4 marginOffset = m_TextComponent.margin;
353 Vector3 lossyScale = m_RectTransform.lossyScale;
354
355 m_HandlePoints[0] = m_RectCorners[0] + m_RectTransform.TransformDirection(new Vector3(marginOffset.x * lossyScale.x, marginOffset.w * lossyScale.y, 0));
356 m_HandlePoints[1] = m_RectCorners[1] + m_RectTransform.TransformDirection(new Vector3(marginOffset.x * lossyScale.x, -marginOffset.y * lossyScale.y, 0));
357 m_HandlePoints[2] = m_RectCorners[2] + m_RectTransform.TransformDirection(new Vector3(-marginOffset.z * lossyScale.x, -marginOffset.y * lossyScale.y, 0));
358 m_HandlePoints[3] = m_RectCorners[3] + m_RectTransform.TransformDirection(new Vector3(-marginOffset.z * lossyScale.x, marginOffset.w * lossyScale.y, 0));
359
360 Handles.DrawSolidRectangleWithOutline(m_HandlePoints, new Color32(255, 255, 255, 0), new Color32(255, 255, 0, 255));
361
362 Matrix4x4 matrix = m_RectTransform.worldToLocalMatrix;
363
364 // Draw & process FreeMoveHandles
365
366 // LEFT HANDLE
367 Vector3 oldLeft = (m_HandlePoints[0] + m_HandlePoints[1]) * 0.5f;
368 #if UNITY_2022_1_OR_NEWER
369 Vector3 newLeft = Handles.FreeMoveHandle(oldLeft, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap);
370 #else
371 Vector3 newLeft = Handles.FreeMoveHandle(oldLeft, Quaternion.identity, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap);
372 #endif
373 bool hasChanged = false;
374 if (oldLeft != newLeft)
375 {
376 oldLeft = matrix.MultiplyPoint(oldLeft);
377 newLeft = matrix.MultiplyPoint(newLeft);
378
379 float delta = (oldLeft.x - newLeft.x) * lossyScale.x;
380 marginOffset.x += -delta / lossyScale.x;
381 //Debug.Log("Left Margin H0:" + handlePoints[0] + " H1:" + handlePoints[1]);
382 hasChanged = true;
383 }
384
385 // TOP HANDLE
386 Vector3 oldTop = (m_HandlePoints[1] + m_HandlePoints[2]) * 0.5f;
387 #if UNITY_2022_1_OR_NEWER
388 Vector3 newTop = Handles.FreeMoveHandle(oldTop, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap);
389 #else
390 Vector3 newTop = Handles.FreeMoveHandle(oldTop, Quaternion.identity, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap);
391 #endif
392 if (oldTop != newTop)
393 {
394 oldTop = matrix.MultiplyPoint(oldTop);
395 newTop = matrix.MultiplyPoint(newTop);
396
397 float delta = (oldTop.y - newTop.y) * lossyScale.y;
398 marginOffset.y += delta / lossyScale.y;
399 //Debug.Log("Top Margin H1:" + handlePoints[1] + " H2:" + handlePoints[2]);
400 hasChanged = true;
401 }
402
403 // RIGHT HANDLE
404 Vector3 oldRight = (m_HandlePoints[2] + m_HandlePoints[3]) * 0.5f;
405 #if UNITY_2022_1_OR_NEWER
406 Vector3 newRight = Handles.FreeMoveHandle(oldRight, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap);
407 #else
408 Vector3 newRight = Handles.FreeMoveHandle(oldRight, Quaternion.identity, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap);
409 #endif
410 if (oldRight != newRight)
411 {
412 oldRight = matrix.MultiplyPoint(oldRight);
413 newRight = matrix.MultiplyPoint(newRight);
414
415 float delta = (oldRight.x - newRight.x) * lossyScale.x;
416 marginOffset.z += delta / lossyScale.x;
417 hasChanged = true;
418 //Debug.Log("Right Margin H2:" + handlePoints[2] + " H3:" + handlePoints[3]);
419 }
420
421 // BOTTOM HANDLE
422 Vector3 oldBottom = (m_HandlePoints[3] + m_HandlePoints[0]) * 0.5f;
423 #if UNITY_2022_1_OR_NEWER
424 Vector3 newBottom = Handles.FreeMoveHandle(oldBottom, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap);
425 #else
426 Vector3 newBottom = Handles.FreeMoveHandle(oldBottom, Quaternion.identity, HandleUtility.GetHandleSize(m_RectTransform.position) * 0.05f, Vector3.zero, Handles.DotHandleCap);
427 #endif
428 if (oldBottom != newBottom)
429 {
430 oldBottom = matrix.MultiplyPoint(oldBottom);
431 newBottom = matrix.MultiplyPoint(newBottom);
432
433 float delta = (oldBottom.y - newBottom.y) * lossyScale.y;
434 marginOffset.w += -delta / lossyScale.y;
435 hasChanged = true;
436 //Debug.Log("Bottom Margin H0:" + handlePoints[0] + " H3:" + handlePoints[3]);
437 }
438
439 if (hasChanged)
440 {
441 Undo.RecordObjects(new Object[] {m_RectTransform, m_TextComponent }, "Margin Changes");
442 m_TextComponent.margin = marginOffset;
443 EditorUtility.SetDirty(target);
444 }
445 }
446
447 protected void DrawTextInput()
448 {
449 EditorGUILayout.Space();
450
451 Rect rect = EditorGUILayout.GetControlRect(false, 22);
452 GUI.Label(rect, new GUIContent("<b>Text Input</b>"), TMP_UIStyleManager.sectionHeader);
453
454 EditorGUI.indentLevel = 0;
455
456 // If the text component is linked, disable the text input box.
457 if (m_ParentLinkedTextComponentProp.objectReferenceValue != null)
458 {
459 EditorGUILayout.HelpBox("The Text Input Box is disabled due to this text component being linked to another.", MessageType.Info);
460 }
461 else
462 {
463 // Display RTL Toggle
464 float labelWidth = EditorGUIUtility.labelWidth;
465 EditorGUIUtility.labelWidth = 110f;
466
467 m_IsRightToLeftProp.boolValue = EditorGUI.Toggle(new Rect(rect.width - 120, rect.y + 3, 130, 20), k_RtlToggleLabel, m_IsRightToLeftProp.boolValue);
468
469 EditorGUIUtility.labelWidth = labelWidth;
470
471 EditorGUI.BeginChangeCheck();
472 EditorGUILayout.PropertyField(m_TextProp, GUIContent.none);
473
474 // Need to also compare string content due to issue related to scroll bar drag handle
475 if (EditorGUI.EndChangeCheck() && m_TextProp.stringValue != m_TextComponent.text)
476 {
477 m_TextComponent.m_inputSource = TMP_Text.TextInputSources.TextInputBox;
478 m_HavePropertiesChanged = true;
479 }
480
481 if (m_IsRightToLeftProp.boolValue)
482 {
483 // Copy source text to RTL string
484 m_RtlText = string.Empty;
485 string sourceText = m_TextProp.stringValue;
486
487 // Reverse Text displayed in Text Input Box
488 for (int i = 0; i < sourceText.Length; i++)
489 m_RtlText += sourceText[sourceText.Length - i - 1];
490
491 GUILayout.Label("RTL Text Input");
492
493 EditorGUI.BeginChangeCheck();
494 m_RtlText = EditorGUILayout.TextArea(m_RtlText, TMP_UIStyleManager.wrappingTextArea, GUILayout.Height(EditorGUI.GetPropertyHeight(m_TextProp) - EditorGUIUtility.singleLineHeight), GUILayout.ExpandWidth(true));
495
496 if (EditorGUI.EndChangeCheck())
497 {
498 // Convert RTL input
499 sourceText = string.Empty;
500
501 // Reverse Text displayed in Text Input Box
502 for (int i = 0; i < m_RtlText.Length; i++)
503 sourceText += m_RtlText[m_RtlText.Length - i - 1];
504
505 m_TextProp.stringValue = sourceText;
506 }
507 }
508
509 // TEXT STYLE
510 if (m_StyleNames != null)
511 {
512 rect = EditorGUILayout.GetControlRect(false, 17);
513
514 EditorGUI.BeginProperty(rect, k_StyleLabel, m_TextStyleHashCodeProp);
515
516 m_TextStyleIndexLookup.TryGetValue(m_TextStyleHashCodeProp.intValue, out m_StyleSelectionIndex);
517
518 EditorGUI.BeginChangeCheck();
519 m_StyleSelectionIndex = EditorGUI.Popup(rect, k_StyleLabel, m_StyleSelectionIndex, m_StyleNames);
520 if (EditorGUI.EndChangeCheck())
521 {
522 m_TextStyleHashCodeProp.intValue = m_Styles[m_StyleSelectionIndex].hashCode;
523 m_TextComponent.m_TextStyle = m_Styles[m_StyleSelectionIndex];
524 m_HavePropertiesChanged = true;
525 }
526
527 EditorGUI.EndProperty();
528 }
529 }
530 }
531
532 protected void DrawMainSettings()
533 {
534 // MAIN SETTINGS SECTION
535 GUILayout.Label(new GUIContent("<b>Main Settings</b>"), TMP_UIStyleManager.sectionHeader);
536
537 //EditorGUI.indentLevel += 1;
538
539 DrawFont();
540
541 DrawColor();
542
543 DrawSpacing();
544
545 DrawAlignment();
546
547 DrawWrappingOverflow();
548
549 DrawTextureMapping();
550
551 //EditorGUI.indentLevel -= 1;
552 }
553
554 void DrawFont()
555 {
556 bool isFontAssetDirty = false;
557
558 // FONT ASSET
559 EditorGUI.BeginChangeCheck();
560 EditorGUILayout.PropertyField(m_FontAssetProp, k_FontAssetLabel);
561 if (EditorGUI.EndChangeCheck())
562 {
563 m_HavePropertiesChanged = true;
564 m_HasFontAssetChangedProp.boolValue = true;
565
566 // Get new Material Presets for the new font asset
567 m_MaterialPresetNames = GetMaterialPresets();
568 m_MaterialPresetSelectionIndex = 0;
569
570 isFontAssetDirty = true;
571 }
572
573 Rect rect;
574
575 // MATERIAL PRESET
576 if (m_MaterialPresetNames != null && !isFontAssetDirty )
577 {
578 EditorGUI.BeginChangeCheck();
579 rect = EditorGUILayout.GetControlRect(false, 17);
580
581 EditorGUI.BeginProperty(rect, k_MaterialPresetLabel, m_FontSharedMaterialProp);
582
583 float oldHeight = EditorStyles.popup.fixedHeight;
584 EditorStyles.popup.fixedHeight = rect.height;
585
586 int oldSize = EditorStyles.popup.fontSize;
587 EditorStyles.popup.fontSize = 11;
588
589 if (m_FontSharedMaterialProp.objectReferenceValue != null)
590 m_MaterialPresetIndexLookup.TryGetValue(m_FontSharedMaterialProp.objectReferenceValue.GetInstanceID(), out m_MaterialPresetSelectionIndex);
591
592 m_MaterialPresetSelectionIndex = EditorGUI.Popup(rect, k_MaterialPresetLabel, m_MaterialPresetSelectionIndex, m_MaterialPresetNames);
593
594 EditorGUI.EndProperty();
595
596 if (EditorGUI.EndChangeCheck())
597 {
598 m_FontSharedMaterialProp.objectReferenceValue = m_MaterialPresets[m_MaterialPresetSelectionIndex];
599 m_HavePropertiesChanged = true;
600 }
601
602 EditorStyles.popup.fixedHeight = oldHeight;
603 EditorStyles.popup.fontSize = oldSize;
604 }
605
606 // FONT STYLE
607 EditorGUI.BeginChangeCheck();
608
609 int v1, v2, v3, v4, v5, v6, v7;
610
611 if (EditorGUIUtility.wideMode)
612 {
613 rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight + 2f);
614
615 EditorGUI.BeginProperty(rect, k_FontStyleLabel, m_FontStyleProp);
616
617 EditorGUI.PrefixLabel(rect, k_FontStyleLabel);
618
619 int styleValue = m_FontStyleProp.intValue;
620
621 rect.x += EditorGUIUtility.labelWidth;
622 rect.width -= EditorGUIUtility.labelWidth;
623
624 rect.width = Mathf.Max(25f, rect.width / 7f);
625
626 v1 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 1) == 1, k_BoldLabel, TMP_UIStyleManager.alignmentButtonLeft) ? 1 : 0; // Bold
627 rect.x += rect.width;
628 v2 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 2) == 2, k_ItalicLabel, TMP_UIStyleManager.alignmentButtonMid) ? 2 : 0; // Italics
629 rect.x += rect.width;
630 v3 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 4) == 4, k_UnderlineLabel, TMP_UIStyleManager.alignmentButtonMid) ? 4 : 0; // Underline
631 rect.x += rect.width;
632 v7 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 64) == 64, k_StrikethroughLabel, TMP_UIStyleManager.alignmentButtonRight) ? 64 : 0; // Strikethrough
633 rect.x += rect.width;
634
635 int selected = 0;
636
637 EditorGUI.BeginChangeCheck();
638 v4 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 8) == 8, k_LowercaseLabel, TMP_UIStyleManager.alignmentButtonLeft) ? 8 : 0; // Lowercase
639 if (EditorGUI.EndChangeCheck() && v4 > 0)
640 {
641 selected = v4;
642 }
643 rect.x += rect.width;
644 EditorGUI.BeginChangeCheck();
645 v5 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 16) == 16, k_UppercaseLabel, TMP_UIStyleManager.alignmentButtonMid) ? 16 : 0; // Uppercase
646 if (EditorGUI.EndChangeCheck() && v5 > 0)
647 {
648 selected = v5;
649 }
650 rect.x += rect.width;
651 EditorGUI.BeginChangeCheck();
652 v6 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 32) == 32, k_SmallcapsLabel, TMP_UIStyleManager.alignmentButtonRight) ? 32 : 0; // Smallcaps
653 if (EditorGUI.EndChangeCheck() && v6 > 0)
654 {
655 selected = v6;
656 }
657
658 if (selected > 0)
659 {
660 v4 = selected == 8 ? 8 : 0;
661 v5 = selected == 16 ? 16 : 0;
662 v6 = selected == 32 ? 32 : 0;
663 }
664
665 EditorGUI.EndProperty();
666 }
667 else
668 {
669 rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight + 2f);
670
671 EditorGUI.BeginProperty(rect, k_FontStyleLabel, m_FontStyleProp);
672
673 EditorGUI.PrefixLabel(rect, k_FontStyleLabel);
674
675 int styleValue = m_FontStyleProp.intValue;
676
677 rect.x += EditorGUIUtility.labelWidth;
678 rect.width -= EditorGUIUtility.labelWidth;
679 rect.width = Mathf.Max(25f, rect.width / 4f);
680
681 v1 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 1) == 1, k_BoldLabel, TMP_UIStyleManager.alignmentButtonLeft) ? 1 : 0; // Bold
682 rect.x += rect.width;
683 v2 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 2) == 2, k_ItalicLabel, TMP_UIStyleManager.alignmentButtonMid) ? 2 : 0; // Italics
684 rect.x += rect.width;
685 v3 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 4) == 4, k_UnderlineLabel, TMP_UIStyleManager.alignmentButtonMid) ? 4 : 0; // Underline
686 rect.x += rect.width;
687 v7 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 64) == 64, k_StrikethroughLabel, TMP_UIStyleManager.alignmentButtonRight) ? 64 : 0; // Strikethrough
688
689 rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight + 2f);
690
691 rect.x += EditorGUIUtility.labelWidth;
692 rect.width -= EditorGUIUtility.labelWidth;
693
694 rect.width = Mathf.Max(25f, rect.width / 4f);
695
696 int selected = 0;
697
698 EditorGUI.BeginChangeCheck();
699 v4 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 8) == 8, k_LowercaseLabel, TMP_UIStyleManager.alignmentButtonLeft) ? 8 : 0; // Lowercase
700 if (EditorGUI.EndChangeCheck() && v4 > 0)
701 {
702 selected = v4;
703 }
704 rect.x += rect.width;
705 EditorGUI.BeginChangeCheck();
706 v5 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 16) == 16, k_UppercaseLabel, TMP_UIStyleManager.alignmentButtonMid) ? 16 : 0; // Uppercase
707 if (EditorGUI.EndChangeCheck() && v5 > 0)
708 {
709 selected = v5;
710 }
711 rect.x += rect.width;
712 EditorGUI.BeginChangeCheck();
713 v6 = TMP_EditorUtility.EditorToggle(rect, (styleValue & 32) == 32, k_SmallcapsLabel, TMP_UIStyleManager.alignmentButtonRight) ? 32 : 0; // Smallcaps
714 if (EditorGUI.EndChangeCheck() && v6 > 0)
715 {
716 selected = v6;
717 }
718
719 if (selected > 0)
720 {
721 v4 = selected == 8 ? 8 : 0;
722 v5 = selected == 16 ? 16 : 0;
723 v6 = selected == 32 ? 32 : 0;
724 }
725
726 EditorGUI.EndProperty();
727 }
728
729 if (EditorGUI.EndChangeCheck())
730 {
731 m_FontStyleProp.intValue = v1 + v2 + v3 + v4 + v5 + v6 + v7;
732 m_HavePropertiesChanged = true;
733 }
734
735 // FONT SIZE
736 EditorGUI.BeginChangeCheck();
737
738 EditorGUI.BeginDisabledGroup(m_AutoSizingProp.boolValue);
739 EditorGUILayout.PropertyField(m_FontSizeProp, k_FontSizeLabel, GUILayout.MaxWidth(EditorGUIUtility.labelWidth + 50f));
740 EditorGUI.EndDisabledGroup();
741
742 if (EditorGUI.EndChangeCheck())
743 {
744 float fontSize = Mathf.Clamp(m_FontSizeProp.floatValue, 0, 32767);
745
746 m_FontSizeProp.floatValue = fontSize;
747 m_FontSizeBaseProp.floatValue = fontSize;
748 m_HavePropertiesChanged = true;
749 }
750
751 EditorGUI.indentLevel += 1;
752
753 EditorGUI.BeginChangeCheck();
754 EditorGUILayout.PropertyField(m_AutoSizingProp, k_AutoSizeLabel);
755 if (EditorGUI.EndChangeCheck())
756 {
757 if (m_AutoSizingProp.boolValue == false)
758 m_FontSizeProp.floatValue = m_FontSizeBaseProp.floatValue;
759
760 m_HavePropertiesChanged = true;
761 }
762
763 // Show auto sizing options
764 if (m_AutoSizingProp.boolValue)
765 {
766 rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
767
768 EditorGUI.PrefixLabel(rect, k_AutoSizeOptionsLabel);
769
770 int previousIndent = EditorGUI.indentLevel;
771
772 EditorGUI.indentLevel = 0;
773
774 rect.width = (rect.width - EditorGUIUtility.labelWidth) / 4f;
775 rect.x += EditorGUIUtility.labelWidth;
776
777 EditorGUIUtility.labelWidth = 24;
778 EditorGUI.BeginChangeCheck();
779 EditorGUI.PropertyField(rect, m_FontSizeMinProp, k_MinLabel);
780 if (EditorGUI.EndChangeCheck())
781 {
782 float minSize = m_FontSizeMinProp.floatValue;
783
784 minSize = Mathf.Max(0, minSize);
785
786 m_FontSizeMinProp.floatValue = Mathf.Min(minSize, m_FontSizeMaxProp.floatValue);
787 m_HavePropertiesChanged = true;
788 }
789 rect.x += rect.width;
790
791 EditorGUIUtility.labelWidth = 27;
792 EditorGUI.BeginChangeCheck();
793 EditorGUI.PropertyField(rect, m_FontSizeMaxProp, k_MaxLabel);
794 if (EditorGUI.EndChangeCheck())
795 {
796 float maxSize = Mathf.Clamp(m_FontSizeMaxProp.floatValue, 0, 32767);
797
798 m_FontSizeMaxProp.floatValue = Mathf.Max(m_FontSizeMinProp.floatValue, maxSize);
799 m_HavePropertiesChanged = true;
800 }
801 rect.x += rect.width;
802
803 EditorGUI.BeginChangeCheck();
804 EditorGUIUtility.labelWidth = 36;
805 EditorGUI.PropertyField(rect, m_CharWidthMaxAdjProp, k_WdLabel);
806 rect.x += rect.width;
807 EditorGUIUtility.labelWidth = 28;
808 EditorGUI.PropertyField(rect, m_LineSpacingMaxProp, k_LineLabel);
809
810 EditorGUIUtility.labelWidth = 0;
811
812 if (EditorGUI.EndChangeCheck())
813 {
814 m_CharWidthMaxAdjProp.floatValue = Mathf.Clamp(m_CharWidthMaxAdjProp.floatValue, 0, 50);
815 m_LineSpacingMaxProp.floatValue = Mathf.Min(0, m_LineSpacingMaxProp.floatValue);
816 m_HavePropertiesChanged = true;
817 }
818
819 EditorGUI.indentLevel = previousIndent;
820 }
821
822 EditorGUI.indentLevel -= 1;
823
824
825
826 EditorGUILayout.Space();
827 }
828
829 void DrawColor()
830 {
831 // FACE VERTEX COLOR
832 EditorGUI.BeginChangeCheck();
833 EditorGUILayout.PropertyField(m_FontColorProp, k_BaseColorLabel);
834 if (EditorGUI.EndChangeCheck())
835 {
836 m_HavePropertiesChanged = true;
837 }
838
839 EditorGUI.BeginChangeCheck();
840 EditorGUILayout.PropertyField(m_EnableVertexGradientProp, k_ColorGradientLabel);
841 if (EditorGUI.EndChangeCheck())
842 {
843 m_HavePropertiesChanged = true;
844 }
845
846 EditorGUIUtility.fieldWidth = 0;
847
848 if (m_EnableVertexGradientProp.boolValue)
849 {
850 EditorGUI.indentLevel += 1;
851
852 EditorGUI.BeginChangeCheck();
853
854 EditorGUILayout.PropertyField(m_FontColorGradientPresetProp, k_ColorPresetLabel);
855
856 SerializedObject obj = null;
857
858 SerializedProperty colorMode;
859
860 SerializedProperty topLeft;
861 SerializedProperty topRight;
862 SerializedProperty bottomLeft;
863 SerializedProperty bottomRight;
864
865 if (m_FontColorGradientPresetProp.objectReferenceValue == null)
866 {
867 colorMode = m_ColorModeProp;
868 topLeft = m_FontColorGradientProp.FindPropertyRelative("topLeft");
869 topRight = m_FontColorGradientProp.FindPropertyRelative("topRight");
870 bottomLeft = m_FontColorGradientProp.FindPropertyRelative("bottomLeft");
871 bottomRight = m_FontColorGradientProp.FindPropertyRelative("bottomRight");
872 }
873 else
874 {
875 obj = new SerializedObject(m_FontColorGradientPresetProp.objectReferenceValue);
876 colorMode = obj.FindProperty("colorMode");
877 topLeft = obj.FindProperty("topLeft");
878 topRight = obj.FindProperty("topRight");
879 bottomLeft = obj.FindProperty("bottomLeft");
880 bottomRight = obj.FindProperty("bottomRight");
881 }
882
883 EditorGUILayout.PropertyField(colorMode, k_ColorModeLabel);
884
885 Rect rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
886
887 EditorGUI.PrefixLabel(rect, k_CorenerColorsLabel);
888
889 rect.x += EditorGUIUtility.labelWidth;
890 rect.width = rect.width - EditorGUIUtility.labelWidth;
891
892 switch ((ColorMode)colorMode.enumValueIndex)
893 {
894 case ColorMode.Single:
895 TMP_EditorUtility.DrawColorProperty(rect, topLeft);
896
897 topRight.colorValue = topLeft.colorValue;
898 bottomLeft.colorValue = topLeft.colorValue;
899 bottomRight.colorValue = topLeft.colorValue;
900 break;
901 case ColorMode.HorizontalGradient:
902 rect.width /= 2f;
903
904 TMP_EditorUtility.DrawColorProperty(rect, topLeft);
905
906 rect.x += rect.width;
907
908 TMP_EditorUtility.DrawColorProperty(rect, topRight);
909
910 bottomLeft.colorValue = topLeft.colorValue;
911 bottomRight.colorValue = topRight.colorValue;
912 break;
913 case ColorMode.VerticalGradient:
914 TMP_EditorUtility.DrawColorProperty(rect, topLeft);
915
916 rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
917 rect.x += EditorGUIUtility.labelWidth;
918
919 TMP_EditorUtility.DrawColorProperty(rect, bottomLeft);
920
921 topRight.colorValue = topLeft.colorValue;
922 bottomRight.colorValue = bottomLeft.colorValue;
923 break;
924 case ColorMode.FourCornersGradient:
925 rect.width /= 2f;
926
927 TMP_EditorUtility.DrawColorProperty(rect, topLeft);
928
929 rect.x += rect.width;
930
931 TMP_EditorUtility.DrawColorProperty(rect, topRight);
932
933 rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
934 rect.x += EditorGUIUtility.labelWidth;
935 rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f;
936
937 TMP_EditorUtility.DrawColorProperty(rect, bottomLeft);
938
939 rect.x += rect.width;
940
941 TMP_EditorUtility.DrawColorProperty(rect, bottomRight);
942 break;
943 }
944
945 if (EditorGUI.EndChangeCheck())
946 {
947 m_HavePropertiesChanged = true;
948 if (obj != null)
949 {
950 obj.ApplyModifiedProperties();
951 TMPro_EventManager.ON_COLOR_GRADIENT_PROPERTY_CHANGED(m_FontColorGradientPresetProp.objectReferenceValue as TMP_ColorGradient);
952 }
953 }
954
955 EditorGUI.indentLevel -= 1;
956 }
957
958 EditorGUILayout.PropertyField(m_OverrideHtmlColorProp, k_OverrideTagsLabel);
959
960 EditorGUILayout.Space();
961 }
962
963 void DrawSpacing()
964 {
965 // CHARACTER, LINE & PARAGRAPH SPACING
966 EditorGUI.BeginChangeCheck();
967
968 Rect rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
969
970 EditorGUI.PrefixLabel(rect, k_SpacingOptionsLabel);
971
972 int oldIndent = EditorGUI.indentLevel;
973 EditorGUI.indentLevel = 0;
974
975 float currentLabelWidth = EditorGUIUtility.labelWidth;
976 rect.x += currentLabelWidth;
977 rect.width = (rect.width - currentLabelWidth - 3f) / 2f;
978
979 EditorGUIUtility.labelWidth = Mathf.Min(rect.width * 0.55f, 80f);
980
981 EditorGUI.PropertyField(rect, m_CharacterSpacingProp, k_CharacterSpacingLabel);
982 rect.x += rect.width + 3f;
983 EditorGUI.PropertyField(rect, m_WordSpacingProp, k_WordSpacingLabel);
984
985 rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight);
986
987 rect.x += currentLabelWidth;
988 rect.width = (rect.width - currentLabelWidth -3f) / 2f;
989 EditorGUIUtility.labelWidth = Mathf.Min(rect.width * 0.55f, 80f);
990
991 EditorGUI.PropertyField(rect, m_LineSpacingProp, k_LineSpacingLabel);
992 rect.x += rect.width + 3f;
993 EditorGUI.PropertyField(rect, m_ParagraphSpacingProp, k_ParagraphSpacingLabel);
994
995 EditorGUIUtility.labelWidth = currentLabelWidth;
996 EditorGUI.indentLevel = oldIndent;
997
998 if (EditorGUI.EndChangeCheck())
999 {
1000 m_HavePropertiesChanged = true;
1001 }
1002
1003 EditorGUILayout.Space();
1004 }
1005
1006 void DrawAlignment()
1007 {
1008 // TEXT ALIGNMENT
1009 EditorGUI.BeginChangeCheck();
1010
1011 Rect rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.currentViewWidth > 504 ? 20 : 40 + 3);
1012 EditorGUI.BeginProperty(rect, k_AlignmentLabel, m_HorizontalAlignmentProp);
1013 EditorGUI.BeginProperty(rect, k_AlignmentLabel, m_VerticalAlignmentProp);
1014
1015 EditorGUI.PrefixLabel(rect, k_AlignmentLabel);
1016 rect.x += EditorGUIUtility.labelWidth;
1017
1018 EditorGUI.PropertyField(rect, m_HorizontalAlignmentProp, GUIContent.none);
1019 EditorGUI.PropertyField(rect, m_VerticalAlignmentProp, GUIContent.none);
1020
1021 // WRAPPING RATIOS shown if Justified mode is selected.
1022 if (((HorizontalAlignmentOptions)m_HorizontalAlignmentProp.intValue & HorizontalAlignmentOptions.Justified) == HorizontalAlignmentOptions.Justified || ((HorizontalAlignmentOptions)m_HorizontalAlignmentProp.intValue & HorizontalAlignmentOptions.Flush) == HorizontalAlignmentOptions.Flush)
1023 DrawPropertySlider(k_WrapMixLabel, m_WordWrappingRatiosProp);
1024
1025 if (EditorGUI.EndChangeCheck())
1026 m_HavePropertiesChanged = true;
1027
1028 EditorGUI.EndProperty();
1029 EditorGUI.EndProperty();
1030
1031 EditorGUILayout.Space();
1032 }
1033
1034 void DrawWrappingOverflow()
1035 {
1036 // TEXT WRAPPING
1037 Rect rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
1038 EditorGUI.BeginProperty(rect, k_WrappingLabel, m_TextWrappingModeProp);
1039
1040 EditorGUI.BeginChangeCheck();
1041 EditorGUI.PropertyField(rect, m_TextWrappingModeProp);
1042 if (EditorGUI.EndChangeCheck())
1043 {
1044 m_HavePropertiesChanged = true;
1045 }
1046
1047 EditorGUI.EndProperty();
1048
1049 // TEXT OVERFLOW
1050 EditorGUI.BeginChangeCheck();
1051
1052 if ((TextOverflowModes)m_TextOverflowModeProp.enumValueIndex == TextOverflowModes.Linked)
1053 {
1054 EditorGUILayout.BeginHorizontal();
1055
1056 float fieldWidth = EditorGUIUtility.fieldWidth;
1057 EditorGUIUtility.fieldWidth = 65;
1058 EditorGUILayout.PropertyField(m_TextOverflowModeProp, k_OverflowLabel);
1059 EditorGUIUtility.fieldWidth = fieldWidth;
1060
1061 EditorGUILayout.PropertyField(m_LinkedTextComponentProp, GUIContent.none);
1062
1063 EditorGUILayout.EndHorizontal();
1064
1065 if (GUI.changed)
1066 {
1067 TMP_Text linkedComponent = m_LinkedTextComponentProp.objectReferenceValue as TMP_Text;
1068
1069 if (linkedComponent == null)
1070 {
1071 m_LinkedTextComponentProp.objectReferenceValue = null;
1072
1073 if (m_PreviousLinkedTextComponent != null)
1074 m_TextComponent.ReleaseLinkedTextComponent(m_PreviousLinkedTextComponent);
1075 }
1076 else if (m_TextComponent.IsSelfOrLinkedAncestor(linkedComponent))
1077 {
1078 m_LinkedTextComponentProp.objectReferenceValue = m_PreviousLinkedTextComponent;
1079 }
1080 else
1081 {
1082 if (m_PreviousLinkedTextComponent != null)
1083 m_TextComponent.ReleaseLinkedTextComponent(m_PreviousLinkedTextComponent);
1084
1085 m_LinkedTextComponentProp.objectReferenceValue = linkedComponent;
1086 linkedComponent.parentLinkedComponent = m_TextComponent;
1087 m_PreviousLinkedTextComponent = linkedComponent;
1088 }
1089 }
1090 }
1091 else if ((TextOverflowModes)m_TextOverflowModeProp.enumValueIndex == TextOverflowModes.Page)
1092 {
1093 EditorGUILayout.BeginHorizontal();
1094 EditorGUILayout.PropertyField(m_TextOverflowModeProp, k_OverflowLabel);
1095 EditorGUILayout.PropertyField(m_PageToDisplayProp, GUIContent.none);
1096 EditorGUILayout.EndHorizontal();
1097
1098 if (m_PreviousLinkedTextComponent)
1099 {
1100 m_TextComponent.ReleaseLinkedTextComponent(m_PreviousLinkedTextComponent);
1101
1102 m_TextComponent.linkedTextComponent = null;
1103 }
1104 }
1105 else
1106 {
1107 EditorGUILayout.PropertyField(m_TextOverflowModeProp, k_OverflowLabel);
1108
1109 if (m_PreviousLinkedTextComponent)
1110 {
1111 m_TextComponent.ReleaseLinkedTextComponent(m_PreviousLinkedTextComponent);
1112
1113 m_TextComponent.linkedTextComponent = null;
1114 }
1115 }
1116
1117 if (EditorGUI.EndChangeCheck())
1118 {
1119 m_HavePropertiesChanged = true;
1120 }
1121
1122 EditorGUILayout.Space();
1123 }
1124
1125 protected abstract void DrawExtraSettings();
1126
1127 protected void DrawMargins()
1128 {
1129 EditorGUI.BeginChangeCheck();
1130 DrawMarginProperty(m_MarginProp, k_MarginsLabel);
1131 if (EditorGUI.EndChangeCheck())
1132 {
1133 // Value range check on margins to make sure they are not excessive.
1134 Vector4 margins = m_MarginProp.vector4Value;
1135 Rect textContainerSize = m_RectTransform.rect;
1136
1137 margins.x = Mathf.Clamp(margins.x, -textContainerSize.width, textContainerSize.width);
1138 margins.z = Mathf.Clamp(margins.z, -textContainerSize.width, textContainerSize.width);
1139
1140 margins.y = Mathf.Clamp(margins.y, -textContainerSize.height, textContainerSize.height);
1141 margins.w = Mathf.Clamp(margins.w, -textContainerSize.height, textContainerSize.height);
1142
1143 m_MarginProp.vector4Value = margins;
1144
1145 m_HavePropertiesChanged = true;
1146 }
1147
1148 EditorGUILayout.Space();
1149 }
1150
1151 protected void DrawGeometrySorting()
1152 {
1153 EditorGUI.BeginChangeCheck();
1154
1155 EditorGUILayout.PropertyField(m_GeometrySortingOrderProp, k_GeometrySortingLabel);
1156
1157 if (EditorGUI.EndChangeCheck())
1158 m_HavePropertiesChanged = true;
1159
1160 EditorGUILayout.Space();
1161 }
1162
1163 protected void DrawIsTextObjectScaleStatic()
1164 {
1165 EditorGUI.BeginChangeCheck();
1166
1167 EditorGUILayout.PropertyField(m_IsTextObjectScaleStaticProp, k_IsTextObjectScaleStatic);
1168
1169 if (EditorGUI.EndChangeCheck())
1170 {
1171 m_TextComponent.isTextObjectScaleStatic = m_IsTextObjectScaleStaticProp.boolValue;
1172 m_HavePropertiesChanged = true;
1173 }
1174
1175 EditorGUILayout.Space();
1176 }
1177
1178
1179 protected void DrawRichText()
1180 {
1181 EditorGUI.BeginChangeCheck();
1182
1183 EditorGUILayout.PropertyField(m_IsRichTextProp, k_RichTextLabel);
1184 if (EditorGUI.EndChangeCheck())
1185 m_HavePropertiesChanged = true;
1186 }
1187
1188 protected void DrawParsing()
1189 {
1190 EditorGUI.BeginChangeCheck();
1191 EditorGUILayout.PropertyField(m_EnableEscapeCharacterParsingProp, k_EscapeCharactersLabel);
1192 EditorGUILayout.PropertyField(m_UseMaxVisibleDescenderProp, k_VisibleDescenderLabel);
1193
1194 if (EditorGUI.EndChangeCheck())
1195 m_HavePropertiesChanged = true;
1196
1197 EditorGUILayout.Space();
1198 }
1199
1200 protected void DrawEmojiFallbackSupport()
1201 {
1202 EditorGUI.BeginChangeCheck();
1203
1204 EditorGUILayout.PropertyField(m_EmojiFallbackSupportProp, k_EmojiFallbackSupportLabel);
1205 if (EditorGUI.EndChangeCheck())
1206 m_HavePropertiesChanged = true;
1207 }
1208
1209 protected void DrawSpriteAsset()
1210 {
1211 EditorGUI.BeginChangeCheck();
1212
1213 EditorGUILayout.PropertyField(m_SpriteAssetProp, k_SpriteAssetLabel, true);
1214
1215 if (EditorGUI.EndChangeCheck())
1216 m_HavePropertiesChanged = true;
1217
1218 EditorGUILayout.Space();
1219 }
1220
1221 protected void DrawStyleSheet()
1222 {
1223 EditorGUI.BeginChangeCheck();
1224
1225 EditorGUILayout.PropertyField(m_StyleSheetAssetProp, k_StyleSheetAssetLabel, true);
1226
1227 if (EditorGUI.EndChangeCheck())
1228 {
1229 m_StyleNames = GetStyleNames();
1230 m_HavePropertiesChanged = true;
1231 }
1232
1233 EditorGUILayout.Space();
1234 }
1235
1236 protected void DrawTextureMapping()
1237 {
1238 // TEXTURE MAPPING OPTIONS
1239 EditorGUI.BeginChangeCheck();
1240 EditorGUILayout.PropertyField(m_HorizontalMappingProp, k_HorizontalMappingLabel);
1241 EditorGUILayout.PropertyField(m_VerticalMappingProp, k_VerticalMappingLabel);
1242 if (EditorGUI.EndChangeCheck())
1243 {
1244 m_HavePropertiesChanged = true;
1245 }
1246
1247 // UV OPTIONS
1248 if (m_HorizontalMappingProp.enumValueIndex > 0)
1249 {
1250 EditorGUI.BeginChangeCheck();
1251 EditorGUILayout.PropertyField(m_UvLineOffsetProp, k_LineOffsetLabel, GUILayout.MinWidth(70f));
1252 if (EditorGUI.EndChangeCheck())
1253 {
1254 m_HavePropertiesChanged = true;
1255 }
1256 }
1257
1258 EditorGUILayout.Space();
1259 }
1260
1261 protected void DrawFontFeatures()
1262 {
1263 int srcMask = 0;
1264
1265 int featureCount = m_FontFeaturesActiveProp.arraySize;
1266 for (int i = 0; i < featureCount; i++)
1267 {
1268 SerializedProperty activeFeatureProperty = m_FontFeaturesActiveProp.GetArrayElementAtIndex(i);
1269
1270 for (int j = 0; j < k_FontFeatures.Length; j++)
1271 {
1272 if (activeFeatureProperty.intValue == k_FontFeatures[j].TagToInt())
1273 {
1274 srcMask |= 0x1 << j;
1275 break;
1276 }
1277 }
1278 }
1279
1280 EditorGUI.BeginChangeCheck();
1281
1282 int mask = EditorGUILayout.MaskField(k_FontFeaturesLabel, srcMask, k_FontFeatures);
1283
1284 if (EditorGUI.EndChangeCheck())
1285 {
1286 m_FontFeaturesActiveProp.ClearArray();
1287
1288 int writeIndex = 0;
1289
1290 for (int i = 0; i < k_FontFeatures.Length; i++)
1291 {
1292 int bit = 0x1 << i;
1293 if ((mask & bit) == bit)
1294 {
1295 m_FontFeaturesActiveProp.InsertArrayElementAtIndex(writeIndex);
1296 SerializedProperty newFeature = m_FontFeaturesActiveProp.GetArrayElementAtIndex(writeIndex);
1297 newFeature.intValue = k_FontFeatures[i].TagToInt();
1298
1299 writeIndex += 1;
1300 }
1301 }
1302
1303 m_HavePropertiesChanged = true;
1304 }
1305 }
1306
1307 protected void DrawPadding()
1308 {
1309 // EXTRA PADDING
1310 EditorGUI.BeginChangeCheck();
1311 EditorGUILayout.PropertyField(m_EnableExtraPaddingProp, k_PaddingLabel);
1312 if (EditorGUI.EndChangeCheck())
1313 {
1314 m_HavePropertiesChanged = true;
1315 m_CheckPaddingRequiredProp.boolValue = true;
1316 }
1317 }
1318
1319 /// <summary>
1320 /// Method to retrieve the material presets that match the currently selected font asset.
1321 /// </summary>
1322 protected GUIContent[] GetMaterialPresets()
1323 {
1324 TMP_FontAsset fontAsset = m_FontAssetProp.objectReferenceValue as TMP_FontAsset;
1325 if (fontAsset == null) return null;
1326
1327 m_MaterialPresets = TMP_EditorUtility.FindMaterialReferences(fontAsset);
1328 m_MaterialPresetNames = new GUIContent[m_MaterialPresets.Length];
1329
1330 m_MaterialPresetIndexLookup.Clear();
1331
1332 for (int i = 0; i < m_MaterialPresetNames.Length; i++)
1333 {
1334 m_MaterialPresetNames[i] = new GUIContent(m_MaterialPresets[i].name);
1335
1336 m_MaterialPresetIndexLookup.Add(m_MaterialPresets[i].GetInstanceID(), i);
1337
1338 //if (m_TargetMaterial.GetInstanceID() == m_MaterialPresets[i].GetInstanceID())
1339 // m_MaterialPresetSelectionIndex = i;
1340 }
1341
1342 m_IsPresetListDirty = false;
1343
1344 return m_MaterialPresetNames;
1345 }
1346
1347 protected GUIContent[] GetStyleNames()
1348 {
1349 k_AvailableStyles.Clear();
1350 m_TextStyleIndexLookup.Clear();
1351 m_Styles.Clear();
1352
1353 // First style on the list is always the Normal default style.
1354 TMP_Style styleNormal = TMP_Style.NormalStyle;
1355
1356 m_Styles.Add(styleNormal);
1357 m_TextStyleIndexLookup.Add(styleNormal.hashCode, 0);
1358
1359 k_AvailableStyles.Add(styleNormal.hashCode, styleNormal);
1360
1361 // Get styles from Style Sheet potentially assigned to the text object.
1362 TMP_StyleSheet localStyleSheet = (TMP_StyleSheet)m_StyleSheetAssetProp.objectReferenceValue;
1363
1364 if (localStyleSheet != null)
1365 {
1366 int styleCount = localStyleSheet.styles.Count;
1367
1368 for (int i = 0; i < styleCount; i++)
1369 {
1370 TMP_Style style = localStyleSheet.styles[i];
1371
1372 if (k_AvailableStyles.ContainsKey(style.hashCode) == false)
1373 {
1374 k_AvailableStyles.Add(style.hashCode, style);
1375 m_Styles.Add(style);
1376 m_TextStyleIndexLookup.Add(style.hashCode, m_TextStyleIndexLookup.Count);
1377 }
1378 }
1379 }
1380
1381 // Get styles from TMP Settings' default style sheet.
1382 TMP_StyleSheet globalStyleSheet = TMP_Settings.defaultStyleSheet;
1383
1384 if (globalStyleSheet != null)
1385 {
1386 int styleCount = globalStyleSheet.styles.Count;
1387
1388 for (int i = 0; i < styleCount; i++)
1389 {
1390 TMP_Style style = globalStyleSheet.styles[i];
1391
1392 if (k_AvailableStyles.ContainsKey(style.hashCode) == false)
1393 {
1394 k_AvailableStyles.Add(style.hashCode, style);
1395 m_Styles.Add(style);
1396 m_TextStyleIndexLookup.Add(style.hashCode, m_TextStyleIndexLookup.Count);
1397 }
1398 }
1399 }
1400
1401 // Create array that will contain the list of available styles.
1402 GUIContent[] styleNames = k_AvailableStyles.Values.Select(item => new GUIContent(item.name)).ToArray();
1403
1404 // Set text style index
1405 m_TextStyleIndexLookup.TryGetValue(m_TextStyleHashCodeProp.intValue, out m_StyleSelectionIndex);
1406
1407 return styleNames;
1408 }
1409
1410 // DRAW MARGIN PROPERTY
1411 protected void DrawMarginProperty(SerializedProperty property, GUIContent label)
1412 {
1413 Rect rect = EditorGUILayout.GetControlRect(false, 2 * 18);
1414
1415 EditorGUI.BeginProperty(rect, label, property);
1416
1417 Rect pos0 = new Rect(rect.x, rect.y + 2, rect.width - 15, 18);
1418
1419 float width = rect.width + 3;
1420 pos0.width = EditorGUIUtility.labelWidth;
1421 EditorGUI.PrefixLabel(pos0, label);
1422
1423 Vector4 margins = property.vector4Value;
1424
1425 float widthB = width - EditorGUIUtility.labelWidth;
1426 float fieldWidth = widthB / 4;
1427 pos0.width = Mathf.Max(fieldWidth - 5, 45f);
1428
1429 // Labels
1430 pos0.x = EditorGUIUtility.labelWidth + 15;
1431 margins.x = DrawMarginField(pos0, "Left", margins.x);
1432
1433 pos0.x += fieldWidth;
1434 margins.y = DrawMarginField(pos0, "Top", margins.y);
1435
1436 pos0.x += fieldWidth;
1437 margins.z = DrawMarginField(pos0, "Right", margins.z);
1438
1439 pos0.x += fieldWidth;
1440 margins.w = DrawMarginField(pos0, "Bottom", margins.w);
1441
1442 property.vector4Value = margins;
1443
1444 EditorGUI.EndProperty();
1445 }
1446
1447 float DrawMarginField(Rect position, string label, float value)
1448 {
1449 int controlId = GUIUtility.GetControlID(FocusType.Keyboard, position);
1450 EditorGUI.PrefixLabel(position, controlId, new GUIContent(label));
1451
1452 Rect dragZone = new Rect(position.x, position.y, position.width, position.height);
1453 position.y += EditorGUIUtility.singleLineHeight;
1454
1455 return EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor, position, dragZone, controlId, value, EditorGUI.kFloatFieldFormatString, EditorStyles.numberField, true);
1456 }
1457
1458 protected void DrawPropertySlider(GUIContent label, SerializedProperty property)
1459 {
1460 Rect rect = EditorGUILayout.GetControlRect(false, 17);
1461
1462 GUIContent content = label ?? GUIContent.none;
1463 EditorGUI.Slider(new Rect(rect.x, rect.y, rect.width, rect.height), property, 0.0f, 1.0f, content);
1464 }
1465
1466 protected abstract bool IsMixSelectionTypes();
1467
1468 // Special Handling of Undo / Redo Events.
1469 protected abstract void OnUndoRedo();
1470
1471 }
1472}