You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/3rd/StompyRobot/SRDebugger/Scripts/UI/Controls/PinEntryControl.cs

215 lines
4.8 KiB
C#

3 months ago
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace SRDebugger.UI.Controls
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SRF;
using UnityEngine;
using UnityEngine.UI;
public delegate void PinEntryControlCallback(IList<int> result, bool didCancel);
public class PinEntryControl : SRMonoBehaviourEx
{
private bool _isVisible = true;
private List<int> _numbers = new List<int>(4);
[RequiredField] public Image Background;
public bool CanCancel = true;
[RequiredField] public UnityEngine.UI.Button CancelButton;
[RequiredField] public Text CancelButtonText;
[RequiredField] public CanvasGroup CanvasGroup;
[RequiredField] public Animator DotAnimator;
public UnityEngine.UI.Button[] NumberButtons;
public Toggle[] NumberDots;
[RequiredField] public Text PromptText;
public event PinEntryControlCallback Complete;
protected override void Awake()
{
base.Awake();
for (var i = 0; i < NumberButtons.Length; i++)
{
var number = i;
NumberButtons[i].onClick.AddListener(() => { PushNumber(number); });
}
CancelButton.onClick.AddListener(CancelButtonPressed);
RefreshState();
}
protected override void OnEnable()
{
#if ENABLE_INPUT_SYSTEM
Keyboard.current.onTextInput += HandleCharacter;
#endif
}
protected override void OnDisable()
{
#if ENABLE_INPUT_SYSTEM
Keyboard.current.onTextInput -= HandleCharacter;
#endif
}
protected override void Update()
{
base.Update();
if (!_isVisible)
{
return;
}
#if ENABLE_INPUT_SYSTEM
bool delete = Keyboard.current.deleteKey.wasPressedThisFrame || Keyboard.current.backspaceKey.wasPressedThisFrame;
#else
bool delete = (Input.GetKeyDown(KeyCode.Backspace) || Input.GetKeyDown(KeyCode.Delete));
#endif
if (_numbers.Count > 0 && delete)
{
_numbers.PopLast();
RefreshState();
}
#if !ENABLE_INPUT_SYSTEM
var input = Input.inputString;
for (var i = 0; i < input.Length; i++)
{
HandleCharacter(input[i]);
}
#endif
}
private void HandleCharacter(char i)
{
if (!_isVisible)
{
return;
}
if (!char.IsNumber(i))
{
return;
}
var num = (int) char.GetNumericValue(i);
if (num > 9 || num < 0)
{
return;
}
PushNumber(num);
}
public void Show()
{
CanvasGroup.alpha = 1f;
CanvasGroup.blocksRaycasts = CanvasGroup.interactable = true;
_isVisible = true;
}
public void Hide()
{
CanvasGroup.alpha = 0f;
CanvasGroup.blocksRaycasts = CanvasGroup.interactable = false;
_isVisible = false;
}
public void Clear()
{
_numbers.Clear();
RefreshState();
}
public void PlayInvalidCodeAnimation()
{
DotAnimator.SetTrigger("Invalid");
}
protected void OnComplete()
{
if (Complete != null)
{
Complete(new ReadOnlyCollection<int>(_numbers), false);
}
}
protected void OnCancel()
{
if (Complete != null)
{
Complete(new int[] {}, true);
}
}
private void CancelButtonPressed()
{
if (_numbers.Count > 0)
{
_numbers.PopLast();
}
else
{
OnCancel();
}
RefreshState();
}
public void PushNumber(int number)
{
if (_numbers.Count >= 4)
{
Debug.LogWarning("[PinEntry] Expected 4 numbers");
return;
}
_numbers.Add(number);
if (_numbers.Count >= 4)
{
OnComplete();
}
RefreshState();
}
private void RefreshState()
{
for (var i = 0; i < NumberDots.Length; i++)
{
NumberDots[i].isOn = i < _numbers.Count;
}
if (_numbers.Count > 0)
{
CancelButtonText.text = "Delete";
}
else
{
CancelButtonText.text = CanCancel ? "Cancel" : "";
}
}
}
}