using System; using System.Collections; using System.Collections.Generic; using Ichni.RhythmGame; using TMPro; using UnityEngine; using UnityEngine.Events; namespace Ichni.Editor { public class DynamicUIInputField : DynamicUIElement, IHaveAutoUpdate { public TMP_InputField inputField; public bool isAutoUpdate { get; set; } public bool isReceiving { get; set; } private UnityAction customAction; public override void Initialize(IBaseElement baseElement, string title, string parameterName) { // 精确重置可交互状态,防止从对象池取回到被禁用的废弃输入框 if (inputField != null) inputField.interactable = true; // [对象池安全] inputField.onEndEdit.RemoveListener(OnEndEditNode); inputField.onSelect.RemoveListener(OnSelectNode); inputField.onDeselect.RemoveListener(OnDeselectNode); customAction = null; base.Initialize(baseElement, title, parameterName); if (parameterName != string.Empty) { ApplyContent(); inputField.onEndEdit.AddListener(OnEndEditNode); } } private void OnEndEditNode(string str) { ApplyParameters(str); customAction?.Invoke(str); } private void OnSelectNode(string str) { isReceiving = false; } private void OnDeselectNode(string str) { isReceiving = true; } private void Update() { (this as IHaveAutoUpdate).UpdateContent(); } public void SetDefaultValue(string text) { inputField.text = text; } public T GetValue() { return (T)Convert.ChangeType(inputField.text, typeof(T)); } public void SetAutoUpdate(bool enable) { isAutoUpdate = enable; isReceiving = true; inputField.onSelect.RemoveListener(OnSelectNode); inputField.onSelect.AddListener(OnSelectNode); inputField.onDeselect.RemoveListener(OnDeselectNode); inputField.onDeselect.AddListener(OnDeselectNode); } public void ApplyContent() { object value = ReflectionHelper.GetDeepValue(connectedBaseElement, parameterName); inputField.text = value != null ? value.ToString() : string.Empty; } private void ApplyParameters(string text) { Type type = null; // 优先获取字段/属性类型 var baseType = connectedBaseElement.GetType(); var field = baseType.GetField(parameterName); if (field != null) type = field.FieldType; else { var prop = baseType.GetProperty(parameterName); if (prop != null) type = prop.PropertyType; } // 如果都没有,fallback 到当前值类型 if (type == null) { var val = ReflectionHelper.GetDeepValue(connectedBaseElement, parameterName); type = val != null ? val.GetType() : typeof(string); } object value = null; if (type == typeof(int)) { value = int.Parse(text); } else if (type == typeof(float)) { value = float.Parse(text); } else if (type == typeof(string)) { value = text; } if (value != null) { Ichni.Editor.Commands.CommandManager.ExecuteCommand(new Ichni.Editor.Commands.ChangeValueCommand(connectedBaseElement, parameterName, value)); } connectedBaseElement.Refresh(); } public override DynamicUIElement AddListenerFunction(UnityAction action) { customAction += _ => action(); return this; } } }