123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- using UnityEngine;
- using UnityEngine.Events;
- using UnityEngine.EventSystems;
- using System;
- namespace TMPro
- {
- public class TMP_TextEventHandler : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
- {
- [Serializable]
- public class CharacterSelectionEvent : UnityEvent<char, int> { }
- [Serializable]
- public class SpriteSelectionEvent : UnityEvent<char, int> { }
- [Serializable]
- public class WordSelectionEvent : UnityEvent<string, int, int> { }
- [Serializable]
- public class LineSelectionEvent : UnityEvent<string, int, int> { }
- [Serializable]
- public class LinkSelectionEvent : UnityEvent<string, string, int> { }
- /// <summary>
- /// Event delegate triggered when pointer is over a character.
- /// </summary>
- public CharacterSelectionEvent onCharacterSelection
- {
- get { return m_OnCharacterSelection; }
- set { m_OnCharacterSelection = value; }
- }
- [SerializeField]
- private CharacterSelectionEvent m_OnCharacterSelection = new CharacterSelectionEvent();
- /// <summary>
- /// Event delegate triggered when pointer is over a sprite.
- /// </summary>
- public SpriteSelectionEvent onSpriteSelection
- {
- get { return m_OnSpriteSelection; }
- set { m_OnSpriteSelection = value; }
- }
- [SerializeField]
- private SpriteSelectionEvent m_OnSpriteSelection = new SpriteSelectionEvent();
- /// <summary>
- /// Event delegate triggered when pointer is over a word.
- /// </summary>
- public WordSelectionEvent onWordSelection
- {
- get { return m_OnWordSelection; }
- set { m_OnWordSelection = value; }
- }
- [SerializeField]
- private WordSelectionEvent m_OnWordSelection = new WordSelectionEvent();
- /// <summary>
- /// Event delegate triggered when pointer is over a line.
- /// </summary>
- public LineSelectionEvent onLineSelection
- {
- get { return m_OnLineSelection; }
- set { m_OnLineSelection = value; }
- }
- [SerializeField]
- private LineSelectionEvent m_OnLineSelection = new LineSelectionEvent();
- /// <summary>
- /// Event delegate triggered when pointer is over a link.
- /// </summary>
- public LinkSelectionEvent onLinkSelection
- {
- get { return m_OnLinkSelection; }
- set { m_OnLinkSelection = value; }
- }
- [SerializeField]
- private LinkSelectionEvent m_OnLinkSelection = new LinkSelectionEvent();
- private TMP_Text m_TextComponent;
- private Camera m_Camera;
- private Canvas m_Canvas;
- private int m_selectedLink = -1;
- private int m_lastCharIndex = -1;
- private int m_lastWordIndex = -1;
- private int m_lastLineIndex = -1;
- void Awake()
- {
- // Get a reference to the text component.
- m_TextComponent = gameObject.GetComponent<TMP_Text>();
- // Get a reference to the camera rendering the text taking into consideration the text component type.
- if (m_TextComponent.GetType() == typeof(TextMeshProUGUI))
- {
- m_Canvas = gameObject.GetComponentInParent<Canvas>();
- if (m_Canvas != null)
- {
- if (m_Canvas.renderMode == RenderMode.ScreenSpaceOverlay)
- m_Camera = null;
- else
- m_Camera = m_Canvas.worldCamera;
- }
- }
- else
- {
- m_Camera = Camera.main;
- }
- }
- void LateUpdate()
- {
- if (TMP_TextUtilities.IsIntersectingRectTransform(m_TextComponent.rectTransform, Input.mousePosition, m_Camera))
- {
- #region Example of Character or Sprite Selection
- int charIndex = TMP_TextUtilities.FindIntersectingCharacter(m_TextComponent, Input.mousePosition, m_Camera, true);
- if (charIndex != -1 && charIndex != m_lastCharIndex)
- {
- m_lastCharIndex = charIndex;
- TMP_TextElementType elementType = m_TextComponent.textInfo.characterInfo[charIndex].elementType;
- // Send event to any event listeners depending on whether it is a character or sprite.
- if (elementType == TMP_TextElementType.Character)
- SendOnCharacterSelection(m_TextComponent.textInfo.characterInfo[charIndex].character, charIndex);
- else if (elementType == TMP_TextElementType.Sprite)
- SendOnSpriteSelection(m_TextComponent.textInfo.characterInfo[charIndex].character, charIndex);
- }
- #endregion
- #region Example of Word Selection
- // Check if Mouse intersects any words and if so assign a random color to that word.
- int wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextComponent, Input.mousePosition, m_Camera);
- if (wordIndex != -1 && wordIndex != m_lastWordIndex)
- {
- m_lastWordIndex = wordIndex;
- // Get the information about the selected word.
- TMP_WordInfo wInfo = m_TextComponent.textInfo.wordInfo[wordIndex];
- // Send the event to any listeners.
- SendOnWordSelection(wInfo.GetWord(), wInfo.firstCharacterIndex, wInfo.characterCount);
- }
- #endregion
- #region Example of Line Selection
- // Check if Mouse intersects any words and if so assign a random color to that word.
- int lineIndex = TMP_TextUtilities.FindIntersectingLine(m_TextComponent, Input.mousePosition, m_Camera);
- if (lineIndex != -1 && lineIndex != m_lastLineIndex)
- {
- m_lastLineIndex = lineIndex;
- // Get the information about the selected word.
- TMP_LineInfo lineInfo = m_TextComponent.textInfo.lineInfo[lineIndex];
- // Send the event to any listeners.
- char[] buffer = new char[lineInfo.characterCount];
- for (int i = 0; i < lineInfo.characterCount && i < m_TextComponent.textInfo.characterInfo.Length; i++)
- {
- buffer[i] = m_TextComponent.textInfo.characterInfo[i + lineInfo.firstCharacterIndex].character;
- }
- string lineText = new string(buffer);
- SendOnLineSelection(lineText, lineInfo.firstCharacterIndex, lineInfo.characterCount);
- }
- #endregion
- #region Example of Link Handling
- // Check if mouse intersects with any links.
- int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextComponent, Input.mousePosition, m_Camera);
- // Handle new Link selection.
- if (linkIndex != -1 && linkIndex != m_selectedLink)
- {
- m_selectedLink = linkIndex;
- // Get information about the link.
- TMP_LinkInfo linkInfo = m_TextComponent.textInfo.linkInfo[linkIndex];
- // Send the event to any listeners.
- SendOnLinkSelection(linkInfo.GetLinkID(), linkInfo.GetLinkText(), linkIndex);
- }
- #endregion
- }
- else
- {
- // Reset all selections given we are hovering outside the text container bounds.
- m_selectedLink = -1;
- m_lastCharIndex = -1;
- m_lastWordIndex = -1;
- m_lastLineIndex = -1;
- }
- }
- public void OnPointerEnter(PointerEventData eventData)
- {
- //Debug.Log("OnPointerEnter()");
- }
- public void OnPointerExit(PointerEventData eventData)
- {
- //Debug.Log("OnPointerExit()");
- }
- private void SendOnCharacterSelection(char character, int characterIndex)
- {
- if (onCharacterSelection != null)
- onCharacterSelection.Invoke(character, characterIndex);
- }
- private void SendOnSpriteSelection(char character, int characterIndex)
- {
- if (onSpriteSelection != null)
- onSpriteSelection.Invoke(character, characterIndex);
- }
- private void SendOnWordSelection(string word, int charIndex, int length)
- {
- if (onWordSelection != null)
- onWordSelection.Invoke(word, charIndex, length);
- }
- private void SendOnLineSelection(string line, int charIndex, int length)
- {
- if (onLineSelection != null)
- onLineSelection.Invoke(line, charIndex, length);
- }
- private void SendOnLinkSelection(string linkID, string linkText, int linkIndex)
- {
- if (onLinkSelection != null)
- onLinkSelection.Invoke(linkID, linkText, linkIndex);
- }
- }
- }
|