1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-09 02:13:29 +08:00
Files
DSP_Mods/UXAssist/UI/MyKeyBinder.cs
2024-09-25 21:00:24 +08:00

238 lines
6.8 KiB
C#

using System;
using System.Linq;
using BepInEx.Configuration;
using UnityEngine;
using UnityEngine.UI;
namespace UXAssist.UI;
// MyKeyBinder modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyKeyBinder.cs
public class MyKeyBinder : MonoBehaviour
{
private ConfigEntry<KeyboardShortcut> _config;
protected event Action OnFree;
[SerializeField]
public Text functionText;
[SerializeField]
public Text keyText;
[SerializeField]
public InputField setTheKeyInput;
[SerializeField]
public Toggle setTheKeyToggle;
[SerializeField]
public RectTransform rectTrans;
[SerializeField]
public UIButton inputUIButton;
[SerializeField]
public Text conflictText;
[SerializeField]
public Text waitingText;
[SerializeField]
public UIButton setDefaultUIButton;
[SerializeField]
public UIButton setNoneKeyUIButton;
private bool _nextNotOn;
protected void OnDestroy()
{
OnFree?.Invoke();
}
public static RectTransform CreateKeyBinder(float x, float y, RectTransform parent, ConfigEntry<KeyboardShortcut> config, string label = "", int fontSize = 17)
{
var optionWindow = UIRoot.instance.optionWindow;
var uikeyEntry = Instantiate(optionWindow.entryPrefab);
GameObject go;
(go = uikeyEntry.gameObject).SetActive(true);
go.name = "my-keybinder";
var kb = go.AddComponent<MyKeyBinder>();
kb._config = config;
kb.functionText = uikeyEntry.functionText;
kb.keyText = uikeyEntry.keyText;
kb.setTheKeyInput = uikeyEntry.setTheKeyInput;
kb.setTheKeyToggle = uikeyEntry.setTheKeyToggle;
kb.rectTrans = uikeyEntry.rectTrans;
kb.inputUIButton = uikeyEntry.inputUIButton;
kb.conflictText = uikeyEntry.conflictText;
kb.waitingText = uikeyEntry.waitingText;
kb.setDefaultUIButton = uikeyEntry.setDefaultUIButton;
kb.setNoneKeyUIButton = uikeyEntry.setNoneKeyUIButton;
kb.functionText.text = label.Translate();
kb.functionText.fontSize = 17;
((RectTransform)kb.keyText.transform).anchoredPosition = new Vector2(20f, -27f);
//kb.keyText.alignment = TextAnchor.MiddleRight;
kb.keyText.fontSize = 17;
((RectTransform)kb.inputUIButton.transform.parent.transform).anchoredPosition = new Vector2(0f + 20f, -57f);
((RectTransform)kb.setDefaultUIButton.transform).anchoredPosition = new Vector2(140f + 20f, -57f);
((RectTransform)kb.setNoneKeyUIButton.transform).anchoredPosition = new Vector2(240f + 20f, -57f);
var rect = Util.NormalizeRectWithTopLeft(kb, x, y, parent);
kb.rectTrans = rect;
//rect.sizeDelta = new Vector2(240f, 64f);
Destroy(uikeyEntry);
kb.setNoneKeyUIButton.gameObject.SetActive(false);
EventHandler func = (_, _) => kb.SettingChanged();
kb.SettingChanged();
config.SettingChanged += func;
kb.OnFree += () => config.SettingChanged -= func;
kb.inputUIButton.onClick += kb.OnInputUIButtonClick;
kb.setDefaultUIButton.onClick += kb.OnSetDefaultKeyClick;
//kb.setNoneKeyUIButton.onClick += kb.OnSetNoneKeyClick;
return go.transform as RectTransform;
}
private void Update()
{
if (!setTheKeyToggle.isOn && inputUIButton.highlighted)
{
setTheKeyToggle.isOn = true;
}
if (!setTheKeyToggle.isOn) return;
if (!inputUIButton._isPointerEnter && Input.GetKeyDown(KeyCode.Mouse0))
{
inputUIButton.highlighted = false;
setTheKeyToggle.isOn = false;
Reset();
}
else if (!inputUIButton.highlighted)
{
setTheKeyToggle.isOn = false;
Reset();
}
else
{
waitingText.gameObject.SetActive(true);
if (!TrySetValue()) return;
setTheKeyToggle.isOn = false;
inputUIButton.highlighted = false;
Reset();
}
}
private bool TrySetValue()
{
if (Input.GetKey(KeyCode.Escape))
{
VFInput.UseEscape();
return true;
}
if (Input.GetKey(KeyCode.Mouse0) || Input.GetKey(KeyCode.Mouse1))
{
return true;
}
var anyKey = GetIunptKeys();
if (anyKey || _lastKey == KeyCode.None) return false;
var k = GetPressedKey();
if (string.IsNullOrEmpty(k))
{
return false;
}
_lastKey = KeyCode.None;
_config.Value = KeyboardShortcut.Deserialize(k);
//keyText.text = k;
return true;
}
private KeyCode _lastKey;
private static readonly KeyCode[] ModKeys = { KeyCode.RightShift, KeyCode.LeftShift,
KeyCode.RightControl, KeyCode.LeftControl,
KeyCode.RightAlt, KeyCode.LeftAlt,
KeyCode.LeftCommand, KeyCode.LeftApple, KeyCode.LeftWindows,
KeyCode.RightCommand, KeyCode.RightApple, KeyCode.RightWindows };
private string GetPressedKey()
{
var key = _lastKey.ToString();
if (string.IsNullOrEmpty(key))
{
return null;
}
var mod = "";
foreach (var modKey in ModKeys)
{
if (Input.GetKey(modKey))
{
mod += "+" + modKey;
}
}
if (!string.IsNullOrEmpty(mod))
{
key += mod;
}
return key;
}
//通常キーが押されているかチェック _lastKey に保存
private bool GetIunptKeys()
{
var anyKey = false;
foreach (KeyCode item in Enum.GetValues(typeof(KeyCode)))
{
if (item == KeyCode.None || ModKeys.Contains(item) || !Input.GetKey(item)) continue;
_lastKey = item;
anyKey = true;
}
return anyKey;
}
public void Reset()
{
conflictText.gameObject.SetActive(false);
waitingText.gameObject.SetActive(false);
setDefaultUIButton.button.Select(); // InputFieldのフォーカス外す
_lastKey = KeyCode.None;
}
public void OnInputUIButtonClick(int data)
{
inputUIButton.highlighted = true;
if (!_nextNotOn) return;
_nextNotOn = false;
inputUIButton.highlighted = false;
setTheKeyToggle.isOn = false;
waitingText.gameObject.SetActive(false);
}
public void OnSetDefaultKeyClick(int data)
{
_config.Value = (KeyboardShortcut)_config.DefaultValue;
keyText.text = _config.Value.Serialize();
}
public void OnSetNoneKeyClick(int data)
{
_config.Value = (KeyboardShortcut)_config.DefaultValue;
keyText.text = _config.Value.Serialize();
}
public void SettingChanged()
{
keyText.text = _config.Value.Serialize();
}
}