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);
|
|
}
|
|
|
|
}
|
|
}
|