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(); } } }