111 lines
3.0 KiB
C#
111 lines
3.0 KiB
C#
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<int, InputVector>();
|
|
}
|
|
|
|
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<int, InputVector> _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));
|
|
}
|
|
}
|
|
}
|