Files
XericUIActionVessel/Runtime/OverrideUI/AvrgValues/XUIAvrgMDInputFieldValue.cs
2026-07-25 23:45:29 +08:00

168 lines
6.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using UnityEngine;
using UnityEngine.UI;
namespace XericUI.ReflectionUIGenerator
{
/// <summary>
/// InputField 值组件 — 处理 string / float / int / double 类型的文本输入交互
/// </summary>
[AddComponentMenu("Xeric Library/UI Action Vessel/Values/XUIAvrgMDInputFieldValue")]
public class XUIAvrgMDInputFieldValue : XUIAvrgMDValue
{
[SerializeField]
[Tooltip("关联的 InputField 组件")]
#if dUI_TextMeshPro
private TMPro.TMP_InputField _inputField;
#else
private InputField _inputField;
#endif
[Header("InputField 专属插槽")]
[SerializeField, Tooltip("增加按钮(点击按步进值 +")]
private Button _incrementButton;
[SerializeField, Tooltip("减少按钮(点击按步进值 -")]
private Button _decrementButton;
private const float DefaultStep = 1f;
private void Awake()
{
#if dUI_TextMeshPro
if (_inputField == null) _inputField = GetComponent<TMPro.TMP_InputField>();
#else
if (_inputField == null) _inputField = GetComponent<InputField>();
#endif
}
// ============ 对象池生命周期 ============
public override void OnPoolRelease()
{
if (_incrementButton != null)
_incrementButton.onClick.RemoveAllListeners();
if (_decrementButton != null)
_decrementButton.onClick.RemoveAllListeners();
if (_inputField != null)
_inputField.onEndEdit.RemoveAllListeners();
base.OnPoolRelease();
}
// ============ 核心绑定 ============
public override void BindToAccessor(
IAvrgValueAccessor accessor,
AvrgMvvmBinding binding,
AvrgMvvmScheduler scheduler)
{
CurrentAccessor = accessor;
CurrentBinding = binding;
if (binding == null || accessor == null || _inputField == null) return;
// 根据类型设置输入模式
#if dUI_TextMeshPro
if (accessor.ValueType == typeof(float) || accessor.ValueType == typeof(int)
|| accessor.ValueType == typeof(double))
{
_inputField.contentType = TMPro.TMP_InputField.ContentType.DecimalNumber;
}
#else
if (accessor.ValueType == typeof(float) || accessor.ValueType == typeof(int)
|| accessor.ValueType == typeof(double))
{
_inputField.contentType = InputField.ContentType.DecimalNumber;
}
#endif
// 增减按钮
if (_incrementButton != null)
_incrementButton.onClick.AddListener(OnIncrementClicked);
if (_decrementButton != null)
_decrementButton.onClick.AddListener(OnDecrementClicked);
// UI → 数据
_inputField.onEndEdit.AddListener(val =>
{
object convertedVal = ConvertStringToValue(val, accessor.ValueType);
binding.WriteFromUI(convertedVal);
scheduler?.MarkUIDirty(binding);
});
// 数据 → UI(带验证状态)
binding.OnUIDataChanged += (value, state) =>
{
_inputField.SetTextWithoutNotify(accessor.FormatDisplay(value));
base.UpdateValueDisplay(value, state);
};
// 验证状态变更
binding.OnValidationStateChanged += OnValidationStateChanged;
// 首次同步
var initialValue = accessor.GetValue();
_inputField.SetTextWithoutNotify(accessor.FormatDisplay(initialValue));
UpdateValueDisplay(initialValue, ValidationState.Normal);
}
// ============ 步进 ============
private void OnIncrementClicked()
{
if (CurrentAccessor?.IsReadOnly == true || _inputField == null) return;
if (!float.TryParse(_inputField.text, out float current)) return;
float newVal = current + DefaultStep;
_inputField.text = CurrentAccessor.FormatDisplay(
ConvertValueForAccessor(newVal, CurrentAccessor.ValueType));
}
private void OnDecrementClicked()
{
if (CurrentAccessor?.IsReadOnly == true || _inputField == null) return;
if (!float.TryParse(_inputField.text, out float current)) return;
float newVal = current - DefaultStep;
_inputField.text = CurrentAccessor.FormatDisplay(
ConvertValueForAccessor(newVal, CurrentAccessor.ValueType));
}
// ============ 验证状态回调 ============
protected override void OnValidationStateChanged(ValidationState state)
{
base.OnValidationStateChanged(state);
// InputField 文字颜色随验证状态变化(通过 Text 组件)
if (_inputField != null)
{
var textComponent = _inputField.textComponent;
if (textComponent != null)
{
textComponent.color = state == ValidationState.Invalid
? Color.red
: state == ValidationState.Warning
? new Color(1f, 0.92f, 0.016f)
: Color.white;
}
}
}
private static object ConvertValueForAccessor(float val, Type targetType)
{
if (targetType == typeof(int)) return (int)val;
if (targetType == typeof(double)) return (double)val;
return val;
}
private static object ConvertStringToValue(string s, Type targetType)
{
if (targetType == typeof(string)) return s;
if (targetType == typeof(float) && float.TryParse(s, out float fVal)) return fVal;
if (targetType == typeof(int) && int.TryParse(s, out int iVal)) return iVal;
if (targetType == typeof(double) && double.TryParse(s, out double dVal)) return dVal;
return s;
}
}
}