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.

370 lines
12 KiB

  1. using UnityEngine;
  2. using UnityEngine.EventSystems;
  3. using System.Collections;
  4. namespace TMPro
  5. {
  6. public enum TextContainerAnchors { TopLeft = 0, Top = 1, TopRight = 2, Left = 3, Middle = 4, Right = 5, BottomLeft = 6, Bottom = 7, BottomRight = 8, Custom = 9 };
  7. [ExecuteInEditMode]
  8. [RequireComponent(typeof(RectTransform))]
  9. [AddComponentMenu("Layout/Text Container")]
  10. public class TextContainer : UIBehaviour
  11. {
  12. #pragma warning disable 0618 // Disabled warning related to deprecated properties. This is for backwards compatibility.
  13. public bool hasChanged
  14. {
  15. get { return m_hasChanged; }
  16. set { m_hasChanged = value; }
  17. }
  18. private bool m_hasChanged;
  19. // Pivot / Transform Position
  20. public Vector2 pivot
  21. {
  22. get { return m_pivot; }
  23. set { /*Debug.Log("Pivot has changed.");*/ if (m_pivot != value) { m_pivot = value; m_anchorPosition = GetAnchorPosition(m_pivot); m_hasChanged = true; OnContainerChanged(); } }
  24. }
  25. [SerializeField]
  26. private Vector2 m_pivot;
  27. public TextContainerAnchors anchorPosition
  28. {
  29. get { return m_anchorPosition; }
  30. set { /*Debug.Log("Anchor has changed.");*/ if (m_anchorPosition != value) { m_anchorPosition = value; m_pivot = GetPivot(m_anchorPosition); m_hasChanged = true; OnContainerChanged(); } }
  31. }
  32. [SerializeField]
  33. private TextContainerAnchors m_anchorPosition = TextContainerAnchors.Middle;
  34. // Rect which defines the Rectangle
  35. public Rect rect
  36. {
  37. get { return m_rect; }
  38. set { /*Debug.Log("Rectangle has changed.");*/ if (m_rect != value) { m_rect = value; /*m_size = new Vector2(m_rect.width, m_rect.height);*/ m_hasChanged = true; OnContainerChanged(); } }
  39. }
  40. [SerializeField]
  41. private Rect m_rect;
  42. public Vector2 size
  43. {
  44. get { return new Vector2(m_rect.width, m_rect.height); }
  45. set { /*Debug.Log("Size has changed.");*/ if (new Vector2(m_rect.width, m_rect.height) != value) { SetRect(value); m_hasChanged = true; m_isDefaultWidth = false; m_isDefaultHeight = false; OnContainerChanged(); } }
  46. }
  47. // Sets the width of the Text Container.
  48. public float width
  49. {
  50. get { return m_rect.width; }
  51. set { /*Debug.Log("Width has changed.");*/ SetRect(new Vector2(value, m_rect.height)); m_hasChanged = true; m_isDefaultWidth = false; OnContainerChanged(); }
  52. }
  53. // Sets the height of the Text Container.
  54. public float height
  55. {
  56. get { return m_rect.height; }
  57. set { SetRect(new Vector2(m_rect.width, value)); m_hasChanged = true; m_isDefaultHeight = false; OnContainerChanged(); }
  58. }
  59. // Used to determine if the user has changed the width of the Text Container.
  60. public bool isDefaultWidth
  61. {
  62. get { return m_isDefaultWidth; }
  63. }
  64. private bool m_isDefaultWidth;
  65. // Used to determine if the user has changed the height of the Text Container.
  66. public bool isDefaultHeight
  67. {
  68. get { return m_isDefaultHeight; }
  69. }
  70. private bool m_isDefaultHeight;
  71. public bool isAutoFitting
  72. {
  73. get { return m_isAutoFitting; }
  74. set { m_isAutoFitting = value; }
  75. }
  76. private bool m_isAutoFitting = false;
  77. // Corners of the Text Container
  78. public Vector3[] corners
  79. {
  80. get { return m_corners; }
  81. }
  82. private Vector3[] m_corners = new Vector3[4];
  83. public Vector3[] worldCorners
  84. {
  85. get { return m_worldCorners; }
  86. }
  87. private Vector3[] m_worldCorners = new Vector3[4];
  88. //public Vector3 normal
  89. //{
  90. // get { return m_normal; }
  91. //}
  92. //private Vector3 m_normal;
  93. // The margin offset from the Rectangle Bounds
  94. public Vector4 margins
  95. {
  96. get { return m_margins; }
  97. set { if (m_margins != value) { /*Debug.Log("Margins have changed.");*/ m_margins = value; m_hasChanged = true; OnContainerChanged(); } }
  98. }
  99. [SerializeField]
  100. private Vector4 m_margins;
  101. /// <summary>
  102. /// The RectTransform used by the object
  103. /// </summary>
  104. public RectTransform rectTransform
  105. {
  106. get
  107. {
  108. if (m_rectTransform == null) m_rectTransform = GetComponent<RectTransform>();
  109. return m_rectTransform;
  110. }
  111. }
  112. private RectTransform m_rectTransform;
  113. //private Transform m_transform;
  114. //private bool m_isAddingRectTransform;
  115. private static Vector2 k_defaultSize = new Vector2(100, 100);
  116. /// <summary>
  117. ///
  118. /// </summary>
  119. public TextMeshPro textMeshPro
  120. {
  121. get
  122. {
  123. if (m_textMeshPro == null) m_textMeshPro = GetComponent<TextMeshPro>();
  124. return m_textMeshPro;
  125. }
  126. }
  127. private TextMeshPro m_textMeshPro;
  128. protected override void Awake()
  129. {
  130. Debug.LogWarning("The Text Container component is now Obsolete and can safely be removed from [" + gameObject.name + "].", this);
  131. return;
  132. }
  133. /// <summary>
  134. ///
  135. /// </summary>
  136. protected override void OnEnable()
  137. {
  138. //Debug.Log("Text Container OnEnable() called.");
  139. OnContainerChanged();
  140. }
  141. /// <summary>
  142. ///
  143. /// </summary>
  144. protected override void OnDisable()
  145. {
  146. //Debug.Log("OnDisable() called.");
  147. }
  148. /// <summary>
  149. ///
  150. /// </summary>
  151. void OnContainerChanged()
  152. {
  153. //Debug.Log("OnContainerChanged");
  154. UpdateCorners();
  155. //UpdateWorldCorners();
  156. if (this.m_rectTransform != null)
  157. {
  158. m_rectTransform.sizeDelta = this.size;
  159. m_rectTransform.hasChanged = true;
  160. }
  161. if (this.textMeshPro != null)
  162. {
  163. m_textMeshPro.SetVerticesDirty();
  164. m_textMeshPro.margin = m_margins;
  165. }
  166. }
  167. #if UNITY_EDITOR
  168. /// <summary>
  169. ///
  170. /// </summary>
  171. protected override void OnValidate()
  172. {
  173. //Debug.Log("OnValidate() called.");
  174. m_hasChanged = true;
  175. OnContainerChanged();
  176. }
  177. #endif
  178. /*
  179. void LateUpdate()
  180. {
  181. // Used by the Run Time Text Input Component ... This will have to be changed.
  182. if (m_transform.hasChanged)
  183. UpdateWorldCorners();
  184. }
  185. */
  186. /// <summary>
  187. /// Callback from Unity to handle RectTransform changes.
  188. /// </summary>
  189. protected override void OnRectTransformDimensionsChange()
  190. {
  191. // Required to add a RectTransform to objects created in previous releases.
  192. if (this.rectTransform == null) m_rectTransform = gameObject.AddComponent<RectTransform>();
  193. if (m_rectTransform.sizeDelta != k_defaultSize)
  194. this.size = m_rectTransform.sizeDelta;
  195. pivot = m_rectTransform.pivot;
  196. m_hasChanged = true;
  197. OnContainerChanged();
  198. }
  199. private void SetRect(Vector2 size)
  200. {
  201. m_rect = new Rect(m_rect.x, m_rect.y, size.x, size.y);
  202. //UpdateCorners();
  203. }
  204. private void UpdateCorners()
  205. {
  206. m_corners[0] = new Vector3(-m_pivot.x * m_rect.width, (- m_pivot.y) * m_rect.height);
  207. m_corners[1] = new Vector3(-m_pivot.x * m_rect.width, (1 - m_pivot.y) * m_rect.height);
  208. m_corners[2] = new Vector3((1 - m_pivot.x) * m_rect.width, (1 - m_pivot.y) * m_rect.height);
  209. m_corners[3] = new Vector3((1 - m_pivot.x) * m_rect.width, (- m_pivot.y) * m_rect.height);
  210. //Debug.Log("Pivot " + m_pivot + " Corners 0: " + m_corners[0] + " 1: " + m_corners[1] + " 2: " + m_corners[2] + " 3: " + m_corners[3]);
  211. if (m_rectTransform != null)
  212. m_rectTransform.pivot = m_pivot;
  213. }
  214. //private void UpdateWorldCorners()
  215. //{
  216. // if (m_transform == null)
  217. // return;
  218. // Vector3 position = m_transform.position;
  219. // m_worldCorners[0] = position + m_transform.TransformDirection(m_corners[0]);
  220. // m_worldCorners[1] = position + m_transform.TransformDirection(m_corners[1]);
  221. // m_worldCorners[2] = position + m_transform.TransformDirection(m_corners[2]);
  222. // m_worldCorners[3] = position + m_transform.TransformDirection(m_corners[3]);
  223. // m_normal = Vector3.Cross(worldCorners[1] - worldCorners[0], worldCorners[3] - worldCorners[0]);
  224. //}
  225. //public Vector3[] GetWorldCorners()
  226. //{
  227. // UpdateWorldCorners();
  228. // return m_worldCorners;
  229. //}
  230. Vector2 GetPivot(TextContainerAnchors anchor)
  231. {
  232. Vector2 pivot = Vector2.zero;
  233. switch (anchor)
  234. {
  235. case TextContainerAnchors.TopLeft:
  236. pivot = new Vector2(0, 1);
  237. break;
  238. case TextContainerAnchors.Top:
  239. pivot = new Vector2(0.5f, 1);
  240. break;
  241. case TextContainerAnchors.TopRight:
  242. pivot = new Vector2(1, 1);
  243. break;
  244. case TextContainerAnchors.Left:
  245. pivot = new Vector2(0, 0.5f);
  246. break;
  247. case TextContainerAnchors.Middle:
  248. pivot = new Vector2(0.5f, 0.5f);
  249. break;
  250. case TextContainerAnchors.Right:
  251. pivot = new Vector2(1, 0.5f);
  252. break;
  253. case TextContainerAnchors.BottomLeft:
  254. pivot = new Vector2(0, 0);
  255. break;
  256. case TextContainerAnchors.Bottom:
  257. pivot = new Vector2(0.5f, 0);
  258. break;
  259. case TextContainerAnchors.BottomRight:
  260. pivot = new Vector2(1, 0);
  261. break;
  262. }
  263. return pivot;
  264. }
  265. // Method which returns the Anchor position based on pivot value.
  266. TextContainerAnchors GetAnchorPosition(Vector2 pivot)
  267. {
  268. if (pivot == new Vector2(0, 1))
  269. return TextContainerAnchors.TopLeft;
  270. else if (pivot == new Vector2(0.5f, 1))
  271. return TextContainerAnchors.Top;
  272. else if (pivot == new Vector2(1f, 1))
  273. return TextContainerAnchors.TopRight;
  274. else if (pivot == new Vector2(0, 0.5f))
  275. return TextContainerAnchors.Left;
  276. else if (pivot == new Vector2(0.5f, 0.5f))
  277. return TextContainerAnchors.Middle;
  278. else if (pivot == new Vector2(1, 0.5f))
  279. return TextContainerAnchors.Right;
  280. else if (pivot == new Vector2(0, 0))
  281. return TextContainerAnchors.BottomLeft;
  282. else if (pivot == new Vector2(0.5f, 0))
  283. return TextContainerAnchors.Bottom;
  284. else if (pivot == new Vector2(1, 0))
  285. return TextContainerAnchors.BottomRight;
  286. else
  287. return TextContainerAnchors.Custom;
  288. }
  289. }
  290. }