using Cryville.Input; using System; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace Cryville.Crtr.Config.UI { internal class InputDialogEntry : MonoBehaviour, IPointerClickHandler { [SerializeField] Button m_button; [SerializeField] TextMeshProUGUI m_nameText; [SerializeField] Graphic m_iNull; [SerializeField] Graphic m_iX; [SerializeField] Graphic m_iY; [SerializeField] Graphic m_iZ; [SerializeField] Graphic m_iW; [SerializeField] Color m_invalidColor; [SerializeField] Color m_inactiveColor; [SerializeField] Color m_hungColor; [SerializeField] Color m_activeColor; [SerializeField] Color m_restColor; [SerializeField] Color m_motionColor; private InputDeviceStatus status; public event Action Clicked; public InputDeviceStatus Status { get { return status; } set { status = value; m_button.interactable = value == InputDeviceStatus.Default; } } byte _dim; void Awake() { _activeInputs = new Dictionary(); } public void Init(InputSource? src) { m_nameText.text = src == null ? "(None)" : src.Value.Handler.GetTypeName(src.Value.Type); if (src == null) { m_iNull.color = m_invalidColor; m_iX.color = m_invalidColor; m_iY.color = m_invalidColor; m_iZ.color = m_invalidColor; m_iW.color = m_invalidColor; } else { var tsrc = src.Value; _dim = tsrc.Handler.Dimension; m_iNull.color = m_inactiveColor; m_iX.color = _dim >= 1 ? m_restColor : m_invalidColor; m_iY.color = _dim >= 2 ? m_restColor : m_invalidColor; m_iZ.color = _dim >= 3 ? m_restColor : m_invalidColor; m_iW.color = _dim >= 4 ? m_restColor : m_invalidColor; } } public void OnPointerClick(PointerEventData eventData) { if (status != InputDeviceStatus.Default) return; Clicked?.Invoke(); } bool _hung; void Update() { if (_activeInputs.Count > 0) { if (_hung) m_iNull.color = m_hungColor; else _hung = true; } } float _maxScalar = float.Epsilon; Dictionary _activeInputs; public void OnInputEvent(InputEvent ev) { var id = ev.Identifier.Id; if (!_activeInputs.TryGetValue(id, out InputVector lastVec)) { if (ev.To.IsNull) return; _activeInputs.Add(id, lastVec = ev.To.Vector); } if (ev.To.IsNull) { _activeInputs.Remove(id); } else { var vec = ev.To.Vector; var delta = vec - lastVec; if (_dim >= 1) { UpdateVectorIndicator(m_iX, delta.X); if (_dim >= 2) { UpdateVectorIndicator(m_iY, delta.Y); if (_dim >= 3) { UpdateVectorIndicator(m_iZ, delta.Z); if (_dim >= 4) { UpdateVectorIndicator(m_iW, delta.W); } } } } _activeInputs[id] = vec; } m_iNull.color = _activeInputs.Count > 0 ? m_activeColor : m_inactiveColor; _hung = false; } void UpdateVectorIndicator(Graphic i, float v) { float a = MathF.Abs(v); if (a > _maxScalar) _maxScalar = a; i.color = Color.Lerp(m_restColor, m_motionColor, MathF.Sqrt(a / _maxScalar)); } } }