|
|
|
|
#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" : "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|