using TMPro;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace AppUI.Util.Input
{
///
/// 挂在包含 的物体上(可与输入框同物体或手动引用)。
/// 绑定清空按钮与密码可见切换按钮;可选为按钮上的 Graphic 设置「两种状态」自定义颜色。
///
[DisallowMultipleComponent]
public class TMP_InputFieldActionBar : MonoBehaviour
{
[Header("输入框")]
[SerializeField]
TMP_InputField inputField;
[Header("清空")]
[SerializeField]
Button clearButton;
[Tooltip("用于变色:可为按钮子物体上的 Image / RawImage 等;不填则尝试用 Button.targetGraphic")]
[SerializeField]
Graphic clearTintTarget;
[SerializeField]
bool clearUseTwoColors = true;
[SerializeField]
Color clearWhenEmptyColor = new Color(1f, 1f, 1f, 0.35f);
[SerializeField]
Color clearWhenHasTextColor = Color.white;
[FormerlySerializedAs("hideClearButtonWhenEmpty")]
[SerializeField]
bool hideClearWhenEmpty;
[Header("密码显示/隐藏")]
[SerializeField]
Button passwordToggleButton;
[Tooltip("用于变色:不填则尝试用 Button.targetGraphic")]
[SerializeField]
Graphic passwordTintTarget;
[SerializeField]
bool passwordUseTwoColors = true;
[SerializeField]
Color passwordConcealedColor = Color.white;
[SerializeField]
Color passwordRevealedColor = new Color(0.4f, 0.75f, 1f, 1f);
[Tooltip("绑定密码切换按钮时:进入界面是否强制为密文(默认隐藏密码)。关闭则可沿用输入框上原有的 Content Type")]
[SerializeField]
bool passwordStartsConcealed = true;
bool _passwordRevealed;
void Awake()
{
if (inputField == null)
inputField = GetComponent();
}
void OnEnable()
{
if (inputField != null)
inputField.onValueChanged.AddListener(OnInputValueChanged);
if (clearButton != null)
clearButton.onClick.AddListener(OnClearClicked);
if (passwordToggleButton != null)
passwordToggleButton.onClick.AddListener(OnPasswordToggleClicked);
ApplyPasswordInitialState();
RefreshClearUi();
RefreshPasswordTint();
}
void OnDisable()
{
if (inputField != null)
inputField.onValueChanged.RemoveListener(OnInputValueChanged);
if (clearButton != null)
clearButton.onClick.RemoveListener(OnClearClicked);
if (passwordToggleButton != null)
passwordToggleButton.onClick.RemoveListener(OnPasswordToggleClicked);
}
void OnInputValueChanged(string _)
{
RefreshClearUi();
}
void OnClearClicked()
{
if (inputField == null)
return;
inputField.text = string.Empty;
inputField.ActivateInputField();
RefreshClearUi();
}
void OnPasswordToggleClicked()
{
if (inputField == null || passwordToggleButton == null)
return;
_passwordRevealed = !_passwordRevealed;
ApplyPasswordContentType();
inputField.ForceLabelUpdate();
RefreshPasswordTint();
}
void ApplyPasswordInitialState()
{
if (inputField == null)
return;
if (passwordToggleButton == null)
return;
if (passwordStartsConcealed)
{
_passwordRevealed = false;
ApplyPasswordContentType();
inputField.ForceLabelUpdate();
}
else
SyncPasswordStateFromField();
}
void SyncPasswordStateFromField()
{
if (inputField == null)
return;
_passwordRevealed = inputField.contentType != TMP_InputField.ContentType.Password;
}
void ApplyPasswordContentType()
{
inputField.contentType = _passwordRevealed
? TMP_InputField.ContentType.Standard
: TMP_InputField.ContentType.Password;
}
void RefreshClearUi()
{
if (inputField == null)
return;
bool hasText = !string.IsNullOrEmpty(inputField.text);
if (hideClearWhenEmpty && clearButton != null)
clearButton.gameObject.SetActive(hasText);
if (clearUseTwoColors)
ApplyTint(GetClearTintGraphic(), hasText ? clearWhenHasTextColor : clearWhenEmptyColor);
}
void RefreshPasswordTint()
{
if (!passwordUseTwoColors || passwordToggleButton == null)
return;
ApplyTint(GetPasswordTintGraphic(), _passwordRevealed ? passwordRevealedColor : passwordConcealedColor);
}
Graphic GetClearTintGraphic()
{
if (clearTintTarget != null)
return clearTintTarget;
return clearButton != null ? clearButton.targetGraphic : null;
}
Graphic GetPasswordTintGraphic()
{
if (passwordTintTarget != null)
return passwordTintTarget;
return passwordToggleButton != null ? passwordToggleButton.targetGraphic : null;
}
static void ApplyTint(Graphic g, Color c)
{
if (g != null)
g.color = c;
}
#if UNITY_EDITOR
void OnValidate()
{
if (inputField == null)
inputField = GetComponent();
}
#endif
}
}