Files
A-Fairytale-Gone-Bad-Briar-…/Assets/Scripts/UI/Menus/ConfirmActionWindow.cs

316 lines
7.1 KiB
C#

using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using PrimeTween;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace BriarQueen.UI.Menus
{
public class ConfirmActionWindow : MonoBehaviour
{
[Header("Root")]
[SerializeField]
private GameObject _root;
[SerializeField]
private CanvasGroup _canvasGroup;
[SerializeField]
private RectTransform _panelTransform;
[Header("Text")]
[SerializeField]
private TextMeshProUGUI _titleText;
[SerializeField]
private TextMeshProUGUI _messageText;
[SerializeField]
private TextMeshProUGUI _confirmLabel;
[SerializeField]
private TextMeshProUGUI _cancelLabel;
[Header("Buttons")]
[SerializeField]
private Button _confirmButton;
[SerializeField]
private Button _cancelButton;
[Header("Tween Settings")]
[SerializeField]
private TweenSettings _tweenSettings = new()
{
duration = 0.18f,
ease = Ease.OutBack,
useUnscaledTime = true
};
[SerializeField]
private float _hiddenScale = 0.92f;
private Action _onCancel;
private Action _onConfirm;
private CancellationTokenSource _cts;
private Sequence _sequence;
public bool IsOpen { get; private set; }
private void Awake()
{
ResolveReferences();
if (_confirmButton != null)
{
_confirmButton.onClick.AddListener(Confirm);
}
if (_cancelButton != null)
{
_cancelButton.onClick.AddListener(Cancel);
}
CloseImmediate();
}
private void OnDestroy()
{
if (_confirmButton != null)
{
_confirmButton.onClick.RemoveListener(Confirm);
}
if (_cancelButton != null)
{
_cancelButton.onClick.RemoveListener(Cancel);
}
StopAndDispose();
}
public void Open(
string title,
string message,
string confirmText,
string cancelText,
Action onConfirm,
Action onCancel)
{
_onConfirm = onConfirm;
_onCancel = onCancel;
if (_titleText != null)
{
_titleText.text = title;
}
if (_messageText != null)
{
_messageText.text = message;
}
if (_confirmLabel != null)
{
_confirmLabel.text = confirmText;
}
if (_cancelLabel != null)
{
_cancelLabel.text = cancelText;
}
OpenInternal().Forget();
}
public void CancelFromBack()
{
Cancel();
}
public void CloseImmediate()
{
StopAndDispose();
IsOpen = false;
_onConfirm = null;
_onCancel = null;
if (_root != null)
{
_root.SetActive(false);
}
if (_canvasGroup != null)
{
_canvasGroup.alpha = 0f;
_canvasGroup.interactable = false;
_canvasGroup.blocksRaycasts = false;
}
if (_panelTransform != null)
{
_panelTransform.localScale = Vector3.one;
}
}
private async UniTaskVoid OpenInternal()
{
ResolveReferences();
StopAndDispose();
_cts = new CancellationTokenSource();
if (_root != null)
{
_root.SetActive(true);
}
if (_canvasGroup != null)
{
_canvasGroup.alpha = 0f;
_canvasGroup.interactable = false;
_canvasGroup.blocksRaycasts = false;
}
if (_panelTransform != null)
{
_panelTransform.localScale = Vector3.one * _hiddenScale;
}
IsOpen = true;
_sequence = Sequence.Create(useUnscaledTime: true);
if (_canvasGroup != null)
{
_sequence.Group(Tween.Alpha(_canvasGroup, new TweenSettings<float>
{
startValue = 0f,
endValue = 1f,
settings = _tweenSettings
}));
}
if (_panelTransform != null)
{
_sequence.Group(Tween.Scale(_panelTransform, new TweenSettings<Vector3>
{
startValue = Vector3.one * _hiddenScale,
endValue = Vector3.one,
settings = _tweenSettings
}));
}
try
{
await _sequence.ToUniTask(cancellationToken: _cts.Token);
}
catch (OperationCanceledException)
{
return;
}
finally
{
_sequence = default;
}
if (_canvasGroup != null)
{
_canvasGroup.alpha = 1f;
_canvasGroup.interactable = true;
_canvasGroup.blocksRaycasts = true;
}
SelectCancelButton();
}
private void Confirm()
{
if (!IsOpen)
{
return;
}
var onConfirm = _onConfirm;
CloseImmediate();
onConfirm?.Invoke();
}
private void Cancel()
{
if (!IsOpen)
{
return;
}
var onCancel = _onCancel;
CloseImmediate();
onCancel?.Invoke();
}
private void ResolveReferences()
{
if (_root == null)
{
_root = gameObject;
}
if (_canvasGroup == null)
{
_canvasGroup = _root.GetComponent<CanvasGroup>();
}
if (_panelTransform == null)
{
_panelTransform = transform as RectTransform;
}
}
private void SelectCancelButton()
{
if (_cancelButton == null)
{
return;
}
if (EventSystem.current != null)
{
EventSystem.current.SetSelectedGameObject(_cancelButton.gameObject);
return;
}
_cancelButton.Select();
}
private void StopAndDispose()
{
if (_sequence.isAlive)
{
_sequence.Stop();
}
_sequence = default;
if (_cts == null)
{
return;
}
try
{
_cts.Cancel();
}
catch
{
}
_cts.Dispose();
_cts = null;
}
}
}