using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Vanguard.UI
{
/// Переключение фокуса между полями по Tab / Shift+Tab.
public static class TabFocus
{
public static void Move(
InputField first,
InputField second,
bool reverse,
EventSystem events = null)
{
if (first == null || second == null)
return;
events = events != null ? events : EventSystem.current;
if (events == null)
return;
var selected = events.currentSelectedGameObject;
InputField target;
if (selected == first.gameObject)
target = reverse ? first : second;
else if (selected == second.gameObject)
target = first;
else
target = first;
events.SetSelectedGameObject(target.gameObject);
target.ActivateInputField();
target.caretPosition = target.text.Length;
}
public static bool TabPressed(out bool reverse)
{
reverse = false;
#if ENABLE_INPUT_SYSTEM
var keyboard = UnityEngine.InputSystem.Keyboard.current;
if (keyboard != null && keyboard.tabKey.wasPressedThisFrame)
{
reverse = keyboard.shiftKey.isPressed;
return true;
}
return false;
#elif ENABLE_LEGACY_INPUT_MANAGER
if (Input.GetKeyDown(KeyCode.Tab))
{
reverse = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
return true;
}
return false;
#else
return false;
#endif
}
/// Enter или Enter на цифровой клавиатуре.
public static bool EnterPressed()
{
#if ENABLE_INPUT_SYSTEM
var keyboard = UnityEngine.InputSystem.Keyboard.current;
return keyboard != null
&& (keyboard.enterKey.wasPressedThisFrame
|| keyboard.numpadEnterKey.wasPressedThisFrame);
#elif ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter);
#else
return false;
#endif
}
public static bool EscapePressed()
{
#if ENABLE_INPUT_SYSTEM
var keyboard = UnityEngine.InputSystem.Keyboard.current;
return keyboard != null && keyboard.escapeKey.wasPressedThisFrame;
#elif ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKeyDown(KeyCode.Escape);
#else
return false;
#endif
}
}
///
/// Ставится на корень экрана: связывает поля по Tab, отправляет форму по Enter
/// и закрывает меню по Esc.
///
public sealed class TabFocusDriver : MonoBehaviour
{
public InputField First;
public InputField Second;
public Action Submit;
public Action Cancel;
private void Update()
{
if (TabFocus.TabPressed(out var reverse))
TabFocus.Move(First, Second, reverse);
Handle(TabFocus.EnterPressed(), TabFocus.EscapePressed());
}
/// Выполняет действия клавиш; вынесено для EditMode-теста.
public void Handle(bool submit, bool cancel)
{
if (submit)
Submit?.Invoke();
if (cancel)
Cancel?.Invoke();
}
}
/// Esc/Enter для экранов без полей ввода (лобби, оверлеи).
public sealed class HotkeysDriver : MonoBehaviour
{
public Action Submit;
public Action Cancel;
private void Update() => Handle(TabFocus.EnterPressed(), TabFocus.EscapePressed());
public void Handle(bool submit, bool cancel)
{
if (submit)
Submit?.Invoke();
if (cancel)
Cancel?.Invoke();
}
}
}