diff --git a/Scripts/ToolTips/ToolTip.cs b/Scripts/ToolTips/ToolTip.cs index 902fcc2..3d67cd3 100644 --- a/Scripts/ToolTips/ToolTip.cs +++ b/Scripts/ToolTips/ToolTip.cs @@ -30,17 +30,17 @@ namespace UnityEngine.UI.Extensions private Text _text; private RectTransform _rectTransform, canvasRectTransform; - [Tooltip("The canvas used by the tooltip as positioning and scaling reference. Should usually be the root Canvas of the hierarchy this component is in")] - public Canvas canvas; + [Tooltip("The canvas used by the tooltip as positioning and scaling reference. Should usually be the root Canvas of the hierarchy this component is in")] + public Canvas canvas; - [Tooltip("Sets if tooltip triggers will run ForceUpdateCanvases and refresh the tooltip's layout group " + - "(if any) when hovered, in order to prevent momentaneous misplacement sometimes caused by ContentSizeFitters")] - public bool tooltipTriggersCanForceCanvasUpdate = false; + [Tooltip("Sets if tooltip triggers will run ForceUpdateCanvases and refresh the tooltip's layout group " + + "(if any) when hovered, in order to prevent momentaneous misplacement sometimes caused by ContentSizeFitters")] + public bool tooltipTriggersCanForceCanvasUpdate = false; - /// - /// the tooltip's Layout Group, if any - /// - private LayoutGroup _layoutGroup; + /// + /// the tooltip's Layout Group, if any + /// + private LayoutGroup _layoutGroup; //if the tooltip is inside a UI element private bool _inside; @@ -49,72 +49,72 @@ namespace UnityEngine.UI.Extensions public float YShift,xShift; - [HideInInspector] + [HideInInspector] public RenderMode guiMode; private Camera _guiCamera; - public Camera GuiCamera - { - get - { - if (!_guiCamera) { - _guiCamera = Camera.main; - } - - return _guiCamera; - } - } - - private Vector3 screenLowerLeft, screenUpperRight, shiftingVector; - - /// - /// a screen-space point where the tooltip would be placed before applying X and Y shifts and border checks - /// - private Vector3 baseTooltipPos; - - private Vector3 newTTPos; - private Vector3 adjustedNewTTPos; - private Vector3 adjustedTTLocalPos; - private Vector3 shifterForBorders; - - private float borderTest; - - // Standard Singleton Access - private static ToolTip instance; - - public static ToolTip Instance - { - get - { - if (instance == null) - instance = FindObjectOfType(); - return instance; - } - } - - - void Reset() { - canvas = GetComponentInParent(); - canvas = canvas.rootCanvas; - } - - // Use this for initialization - public void Awake() + public Camera GuiCamera { - instance = this; - if (!canvas) { - canvas = GetComponentInParent(); - canvas = canvas.rootCanvas; - } + get + { + if (!_guiCamera) { + _guiCamera = Camera.main; + } - _guiCamera = canvas.worldCamera; + return _guiCamera; + } + } + + private Vector3 screenLowerLeft, screenUpperRight, shiftingVector; + + /// + /// a screen-space point where the tooltip would be placed before applying X and Y shifts and border checks + /// + private Vector3 baseTooltipPos; + + private Vector3 newTTPos; + private Vector3 adjustedNewTTPos; + private Vector3 adjustedTTLocalPos; + private Vector3 shifterForBorders; + + private float borderTest; + + // Standard Singleton Access + private static ToolTip instance; + + public static ToolTip Instance + { + get + { + if (instance == null) + instance = FindObjectOfType(); + return instance; + } + } + + + void Reset() { + canvas = GetComponentInParent(); + canvas = canvas.rootCanvas; + } + + // Use this for initialization + public void Awake() + { + instance = this; + if (!canvas) { + canvas = GetComponentInParent(); + canvas = canvas.rootCanvas; + } + + _guiCamera = canvas.worldCamera; guiMode = canvas.renderMode; _rectTransform = GetComponent(); - canvasRectTransform = canvas.GetComponent(); - _layoutGroup = GetComponentInChildren(); + canvasRectTransform = canvas.GetComponent(); + _layoutGroup = GetComponentInChildren(); - _text = GetComponentInChildren(); + _text = GetComponentInChildren(); _inside = false; @@ -125,19 +125,19 @@ namespace UnityEngine.UI.Extensions public void SetTooltip(string ttext, Vector3 basePos, bool refreshCanvasesBeforeGetSize = false) { - baseTooltipPos = basePos; + baseTooltipPos = basePos; - //set the text - if (_text) { - _text.text = ttext; - } - else { - Debug.LogWarning("[ToolTip] Couldn't set tooltip text, tooltip has no child Text component"); - } + //set the text + if (_text) { + _text.text = ttext; + } + else { + Debug.LogWarning("[ToolTip] Couldn't set tooltip text, tooltip has no child Text component"); + } - ContextualTooltipUpdate(refreshCanvasesBeforeGetSize); + ContextualTooltipUpdate(refreshCanvasesBeforeGetSize); - } + } //call this function on mouse exit to deactivate the template public void HideTooltip() @@ -151,165 +151,165 @@ namespace UnityEngine.UI.Extensions { if (_inside) { - ContextualTooltipUpdate(); + ContextualTooltipUpdate(); } } - /// - /// forces rebuilding of Canvases in order to update the tooltip's content size fitting. - /// Can prevent the tooltip from being visibly misplaced for one frame when being resized. - /// Only runs if tooltipTriggersCanForceCanvasUpdate is true - /// - public void RefreshTooltipSize() { - if (tooltipTriggersCanForceCanvasUpdate) { - Canvas.ForceUpdateCanvases(); + /// + /// forces rebuilding of Canvases in order to update the tooltip's content size fitting. + /// Can prevent the tooltip from being visibly misplaced for one frame when being resized. + /// Only runs if tooltipTriggersCanForceCanvasUpdate is true + /// + public void RefreshTooltipSize() { + if (tooltipTriggersCanForceCanvasUpdate) { + Canvas.ForceUpdateCanvases(); - if (_layoutGroup) { - _layoutGroup.enabled = false; - _layoutGroup.enabled = true; - } - - } - - } + if (_layoutGroup) { + _layoutGroup.enabled = false; + _layoutGroup.enabled = true; + } + + } + + } - /// - /// Runs the appropriate tooltip placement method, according to the parent canvas's render mode - /// - /// - public void ContextualTooltipUpdate(bool refreshCanvasesBeforeGettingSize = false) { - switch (guiMode) { - case RenderMode.ScreenSpaceCamera: - OnScreenSpaceCamera(refreshCanvasesBeforeGettingSize); - break; - case RenderMode.ScreenSpaceOverlay: - OnScreenSpaceOverlay(refreshCanvasesBeforeGettingSize); - break; - } - } + /// + /// Runs the appropriate tooltip placement method, according to the parent canvas's render mode + /// + /// + public void ContextualTooltipUpdate(bool refreshCanvasesBeforeGettingSize = false) { + switch (guiMode) { + case RenderMode.ScreenSpaceCamera: + OnScreenSpaceCamera(refreshCanvasesBeforeGettingSize); + break; + case RenderMode.ScreenSpaceOverlay: + OnScreenSpaceOverlay(refreshCanvasesBeforeGettingSize); + break; + } + } //main tooltip edge of screen guard and movement - camera public void OnScreenSpaceCamera(bool refreshCanvasesBeforeGettingSize = false) { - shiftingVector.x = xShift; - shiftingVector.y = YShift; + shiftingVector.x = xShift; + shiftingVector.y = YShift; - baseTooltipPos.z = canvas.planeDistance; + baseTooltipPos.z = canvas.planeDistance; - newTTPos = GuiCamera.ScreenToViewportPoint(baseTooltipPos - shiftingVector); + newTTPos = GuiCamera.ScreenToViewportPoint(baseTooltipPos - shiftingVector); adjustedNewTTPos = GuiCamera.ViewportToWorldPoint(newTTPos); - gameObject.SetActive(true); + gameObject.SetActive(true); - if (refreshCanvasesBeforeGettingSize) RefreshTooltipSize(); + if (refreshCanvasesBeforeGettingSize) RefreshTooltipSize(); - //consider scaled dimensions when comparing against the edges - width = transform.lossyScale.x * _rectTransform.sizeDelta[0]; + //consider scaled dimensions when comparing against the edges + width = transform.lossyScale.x * _rectTransform.sizeDelta[0]; height = transform.lossyScale.y * _rectTransform.sizeDelta[1]; // check and solve problems for the tooltip that goes out of the screen on the horizontal axis RectTransformUtility.ScreenPointToWorldPointInRectangle(canvasRectTransform, Vector2.zero, GuiCamera, out screenLowerLeft); - RectTransformUtility.ScreenPointToWorldPointInRectangle(canvasRectTransform, new Vector2(Screen.width, Screen.height), GuiCamera, out screenUpperRight); + RectTransformUtility.ScreenPointToWorldPointInRectangle(canvasRectTransform, new Vector2(Screen.width, Screen.height), GuiCamera, out screenUpperRight); - //check for right edge of screen - borderTest = (adjustedNewTTPos.x + width / 2); + //check for right edge of screen + borderTest = (adjustedNewTTPos.x + width / 2); if (borderTest > screenUpperRight.x) { - shifterForBorders.x = borderTest - screenUpperRight.x; - adjustedNewTTPos.x -= shifterForBorders.x; + shifterForBorders.x = borderTest - screenUpperRight.x; + adjustedNewTTPos.x -= shifterForBorders.x; } //check for left edge of screen borderTest = (adjustedNewTTPos.x - width / 2); if (borderTest < screenLowerLeft.x) { - shifterForBorders.x = screenLowerLeft.x - borderTest; - adjustedNewTTPos.x += shifterForBorders.x; + shifterForBorders.x = screenLowerLeft.x - borderTest; + adjustedNewTTPos.x += shifterForBorders.x; } - // check and solve problems for the tooltip that goes out of the screen on the vertical axis + // check and solve problems for the tooltip that goes out of the screen on the vertical axis - //check for lower edge of the screen - borderTest = (adjustedNewTTPos.y - height / 2); - if (borderTest < screenLowerLeft.y) { - shifterForBorders.y = screenLowerLeft.y - borderTest; - adjustedNewTTPos.y += shifterForBorders.y; - } + //check for lower edge of the screen + borderTest = (adjustedNewTTPos.y - height / 2); + if (borderTest < screenLowerLeft.y) { + shifterForBorders.y = screenLowerLeft.y - borderTest; + adjustedNewTTPos.y += shifterForBorders.y; + } - //check for upper edge of the screen - borderTest = (adjustedNewTTPos.y + height / 2); + //check for upper edge of the screen + borderTest = (adjustedNewTTPos.y + height / 2); if (borderTest > screenUpperRight.y) { - shifterForBorders.y = borderTest - screenUpperRight.y; - adjustedNewTTPos.y -= shifterForBorders.y; + shifterForBorders.y = borderTest - screenUpperRight.y; + adjustedNewTTPos.y -= shifterForBorders.y; } - //failed attempt to circumvent issues caused when rotating the camera - adjustedNewTTPos = transform.rotation * adjustedNewTTPos; + //failed attempt to circumvent issues caused when rotating the camera + adjustedNewTTPos = transform.rotation * adjustedNewTTPos; - transform.position = adjustedNewTTPos; - adjustedTTLocalPos = transform.localPosition; - adjustedTTLocalPos.z = 0; - transform.localPosition = adjustedTTLocalPos; + transform.position = adjustedNewTTPos; + adjustedTTLocalPos = transform.localPosition; + adjustedTTLocalPos.z = 0; + transform.localPosition = adjustedTTLocalPos; - _inside = true; + _inside = true; } - //main tooltip edge of screen guard and movement - overlay - public void OnScreenSpaceOverlay(bool refreshCanvasesBeforeGettingSize = false) { - shiftingVector.x = xShift; - shiftingVector.y = YShift; - newTTPos = (baseTooltipPos - shiftingVector) / canvas.scaleFactor; - adjustedNewTTPos = newTTPos; + //main tooltip edge of screen guard and movement - overlay + public void OnScreenSpaceOverlay(bool refreshCanvasesBeforeGettingSize = false) { + shiftingVector.x = xShift; + shiftingVector.y = YShift; + newTTPos = (baseTooltipPos - shiftingVector) / canvas.scaleFactor; + adjustedNewTTPos = newTTPos; - gameObject.SetActive(true); + gameObject.SetActive(true); - if (refreshCanvasesBeforeGettingSize) RefreshTooltipSize(); + if (refreshCanvasesBeforeGettingSize) RefreshTooltipSize(); - width = _rectTransform.sizeDelta[0]; - height = _rectTransform.sizeDelta[1]; + width = _rectTransform.sizeDelta[0]; + height = _rectTransform.sizeDelta[1]; - // check and solve problems for the tooltip that goes out of the screen on the horizontal axis - //screen's 0 = overlay canvas's 0 (always?) - screenLowerLeft = Vector3.zero; - screenUpperRight = canvasRectTransform.sizeDelta; + // check and solve problems for the tooltip that goes out of the screen on the horizontal axis + //screen's 0 = overlay canvas's 0 (always?) + screenLowerLeft = Vector3.zero; + screenUpperRight = canvasRectTransform.sizeDelta; - //check for right edge of screen - borderTest = (newTTPos.x + width / 2); - if (borderTest > screenUpperRight.x) { - shifterForBorders.x = borderTest - screenUpperRight.x; - adjustedNewTTPos.x -= shifterForBorders.x; - } - //check for left edge of screen - borderTest = (adjustedNewTTPos.x - width / 2); - if (borderTest < screenLowerLeft.x) { - shifterForBorders.x = screenLowerLeft.x - borderTest; - adjustedNewTTPos.x += shifterForBorders.x; - } + //check for right edge of screen + borderTest = (newTTPos.x + width / 2); + if (borderTest > screenUpperRight.x) { + shifterForBorders.x = borderTest - screenUpperRight.x; + adjustedNewTTPos.x -= shifterForBorders.x; + } + //check for left edge of screen + borderTest = (adjustedNewTTPos.x - width / 2); + if (borderTest < screenLowerLeft.x) { + shifterForBorders.x = screenLowerLeft.x - borderTest; + adjustedNewTTPos.x += shifterForBorders.x; + } - // check and solve problems for the tooltip that goes out of the screen on the vertical axis + // check and solve problems for the tooltip that goes out of the screen on the vertical axis - //check for lower edge of the screen - borderTest = (adjustedNewTTPos.y - height / 2); - if (borderTest < screenLowerLeft.y) { - shifterForBorders.y = screenLowerLeft.y - borderTest; - adjustedNewTTPos.y += shifterForBorders.y; - } + //check for lower edge of the screen + borderTest = (adjustedNewTTPos.y - height / 2); + if (borderTest < screenLowerLeft.y) { + shifterForBorders.y = screenLowerLeft.y - borderTest; + adjustedNewTTPos.y += shifterForBorders.y; + } - //check for upper edge of the screen - borderTest = (adjustedNewTTPos.y + height / 2); - if (borderTest > screenUpperRight.y) { - shifterForBorders.y = borderTest - screenUpperRight.y; - adjustedNewTTPos.y -= shifterForBorders.y; - } + //check for upper edge of the screen + borderTest = (adjustedNewTTPos.y + height / 2); + if (borderTest > screenUpperRight.y) { + shifterForBorders.y = borderTest - screenUpperRight.y; + adjustedNewTTPos.y -= shifterForBorders.y; + } - //remove scale factor for the actual positioning of the TT - adjustedNewTTPos *= canvas.scaleFactor; - transform.position = adjustedNewTTPos; + //remove scale factor for the actual positioning of the TT + adjustedNewTTPos *= canvas.scaleFactor; + transform.position = adjustedNewTTPos; - _inside = true; - } - } + _inside = true; + } + } } \ No newline at end of file diff --git a/Scripts/ToolTips/TooltipTrigger.cs b/Scripts/ToolTips/TooltipTrigger.cs index f8c848b..b199c03 100644 --- a/Scripts/ToolTips/TooltipTrigger.cs +++ b/Scripts/ToolTips/TooltipTrigger.cs @@ -5,104 +5,104 @@ using UnityEngine.EventSystems; namespace UnityEngine.UI.Extensions { - [RequireComponent(typeof(RectTransform))] - [AddComponentMenu("UI/Extensions/Tooltip/Tooltip Trigger")] - public class TooltipTrigger : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, ISelectHandler, IDeselectHandler - { - [TextAreaAttribute] - public string text; + [RequireComponent(typeof(RectTransform))] + [AddComponentMenu("UI/Extensions/Tooltip/Tooltip Trigger")] + public class TooltipTrigger : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, ISelectHandler, IDeselectHandler + { + [TextAreaAttribute] + public string text; - public enum TooltipPositioningType { - mousePosition, - mousePositionAndFollow, - transformPosition - } + public enum TooltipPositioningType { + mousePosition, + mousePositionAndFollow, + transformPosition + } - [Tooltip("Defines where the tooltip will be placed and how that placement will occur. Transform position will always be used if this element wasn't selected via mouse")] - public TooltipPositioningType tooltipPositioningType = TooltipPositioningType.mousePosition; + [Tooltip("Defines where the tooltip will be placed and how that placement will occur. Transform position will always be used if this element wasn't selected via mouse")] + public TooltipPositioningType tooltipPositioningType = TooltipPositioningType.mousePosition; - /// - /// This info is needed to make sure we make the necessary translations if the tooltip and this trigger are children of different space canvases - /// - private bool isChildOfOverlayCanvas = false; + /// + /// This info is needed to make sure we make the necessary translations if the tooltip and this trigger are children of different space canvases + /// + private bool isChildOfOverlayCanvas = false; - private bool hovered = false; + private bool hovered = false; - public Vector3 offset; + public Vector3 offset; - void Start() { - //attempt to check if our canvas is overlay or not and check our "is overlay" accordingly - Canvas ourCanvas = GetComponentInParent(); - if (ourCanvas && ourCanvas.renderMode == RenderMode.ScreenSpaceOverlay) { - isChildOfOverlayCanvas = true; - } - } + void Start() { + //attempt to check if our canvas is overlay or not and check our "is overlay" accordingly + Canvas ourCanvas = GetComponentInParent(); + if (ourCanvas && ourCanvas.renderMode == RenderMode.ScreenSpaceOverlay) { + isChildOfOverlayCanvas = true; + } + } - /// - /// Checks if the tooltip and the transform this trigger is attached to are children of differently-spaced Canvases - /// - public bool WorldToScreenIsRequired - { - get - { - return (isChildOfOverlayCanvas && ToolTip.Instance.guiMode == RenderMode.ScreenSpaceCamera) || - (!isChildOfOverlayCanvas && ToolTip.Instance.guiMode == RenderMode.ScreenSpaceOverlay); - } - } + /// + /// Checks if the tooltip and the transform this trigger is attached to are children of differently-spaced Canvases + /// + public bool WorldToScreenIsRequired + { + get + { + return (isChildOfOverlayCanvas && ToolTip.Instance.guiMode == RenderMode.ScreenSpaceCamera) || + (!isChildOfOverlayCanvas && ToolTip.Instance.guiMode == RenderMode.ScreenSpaceOverlay); + } + } - public void OnPointerEnter(PointerEventData eventData) - { - switch (tooltipPositioningType) { - case TooltipPositioningType.mousePosition: - StartHover(Input.mousePosition + offset, true); - break; - case TooltipPositioningType.mousePositionAndFollow: - StartHover(Input.mousePosition + offset, true); - hovered = true; - StartCoroutine(HoveredMouseFollowingLoop()); - break; - case TooltipPositioningType.transformPosition: - StartHover((WorldToScreenIsRequired ? - ToolTip.Instance.GuiCamera.WorldToScreenPoint(transform.position) : - transform.position) + offset, true); - break; - } - } + public void OnPointerEnter(PointerEventData eventData) + { + switch (tooltipPositioningType) { + case TooltipPositioningType.mousePosition: + StartHover(Input.mousePosition + offset, true); + break; + case TooltipPositioningType.mousePositionAndFollow: + StartHover(Input.mousePosition + offset, true); + hovered = true; + StartCoroutine(HoveredMouseFollowingLoop()); + break; + case TooltipPositioningType.transformPosition: + StartHover((WorldToScreenIsRequired ? + ToolTip.Instance.GuiCamera.WorldToScreenPoint(transform.position) : + transform.position) + offset, true); + break; + } + } - IEnumerator HoveredMouseFollowingLoop() { - while (hovered) { - StartHover(Input.mousePosition + offset); - yield return null; - } - } + IEnumerator HoveredMouseFollowingLoop() { + while (hovered) { + StartHover(Input.mousePosition + offset); + yield return null; + } + } - public void OnSelect(BaseEventData eventData) - { - StartHover((WorldToScreenIsRequired ? - ToolTip.Instance.GuiCamera.WorldToScreenPoint(transform.position) : - transform.position) + offset, true); - } + public void OnSelect(BaseEventData eventData) + { + StartHover((WorldToScreenIsRequired ? + ToolTip.Instance.GuiCamera.WorldToScreenPoint(transform.position) : + transform.position) + offset, true); + } - public void OnPointerExit(PointerEventData eventData) - { - StopHover(); - } + public void OnPointerExit(PointerEventData eventData) + { + StopHover(); + } - public void OnDeselect(BaseEventData eventData) - { - StopHover(); - } + public void OnDeselect(BaseEventData eventData) + { + StopHover(); + } - void StartHover(Vector3 position, bool shouldCanvasUpdate = false) - { - ToolTip.Instance.SetTooltip(text, position, shouldCanvasUpdate); - } + void StartHover(Vector3 position, bool shouldCanvasUpdate = false) + { + ToolTip.Instance.SetTooltip(text, position, shouldCanvasUpdate); + } - void StopHover() - { - hovered = false; - ToolTip.Instance.HideTooltip(); - } - } + void StopHover() + { + hovered = false; + ToolTip.Instance.HideTooltip(); + } + } }