using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace RR.Common.UI
{
///
/// Меняет цвет TMP-текста внутри кнопки при фокусе и наведении.
///
public class ButtonTextFocusColor : MonoBehaviour, ISelectHandler, IDeselectHandler, IPointerEnterHandler, IPointerExitHandler
{
[SerializeField] private TextMeshProUGUI targetText;
[SerializeField] private Color normalColor = new(0f, 0.29411766f, 0.1882353f, 1f);
[SerializeField] private Color focusedColor = Color.white;
private Selectable _selectable;
private bool _isPointerInside;
private bool _lastFocusedState;
private bool _hasAppliedState;
private void Awake()
{
ResolveReferences();
RefreshVisualState(force: true);
}
private void OnEnable()
{
ResolveReferences();
RefreshVisualState(force: true);
}
private void OnDisable()
{
_isPointerInside = false;
_lastFocusedState = false;
_hasAppliedState = false;
ApplyTextColor(normalColor);
}
private void LateUpdate()
{
RefreshVisualState();
}
public void OnSelect(BaseEventData eventData)
{
RefreshVisualState(force: true);
}
public void OnDeselect(BaseEventData eventData)
{
RefreshVisualState(force: true);
}
public void OnPointerEnter(PointerEventData eventData)
{
_isPointerInside = true;
RefreshVisualState(force: true);
}
public void OnPointerExit(PointerEventData eventData)
{
_isPointerInside = false;
RefreshVisualState(force: true);
}
private void RefreshVisualState(bool force = false)
{
ResolveReferences();
bool isFocused = IsFocusedNow();
if (!force && _hasAppliedState && _lastFocusedState == isFocused)
{
return;
}
_lastFocusedState = isFocused;
_hasAppliedState = true;
ApplyTextColor(isFocused ? focusedColor : normalColor);
}
private bool IsFocusedNow()
{
if (!isActiveAndEnabled)
{
return false;
}
if (_selectable != null && (!_selectable.IsActive() || !_selectable.IsInteractable()))
{
return false;
}
bool isSelected = EventSystem.current != null
&& EventSystem.current.currentSelectedGameObject == gameObject;
return isSelected || _isPointerInside;
}
private void ApplyTextColor(Color color)
{
if (targetText == null)
{
return;
}
targetText.color = color;
}
private void ResolveReferences()
{
if (_selectable == null)
{
_selectable = GetComponent();
}
if (targetText == null)
{
targetText = GetComponentInChildren(true);
}
}
#if UNITY_EDITOR
private void Reset()
{
ResolveReferences();
}
private void OnValidate()
{
ResolveReferences();
if (!Application.isPlaying)
{
RefreshVisualState(force: true);
}
}
#endif
}
}