From dd2cc405c5ec0ca215ee69c6ccafb905ba2643c0 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Wed, 13 Dec 2023 13:26:32 +0800 Subject: [PATCH] Add KeyboardShortcut support in options --- .../Patches/Dynamic/UIOptionWindow_Patch.cs | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/NebulaPatcher/Patches/Dynamic/UIOptionWindow_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIOptionWindow_Patch.cs index c68ba5d0f..5117ecc29 100644 --- a/NebulaPatcher/Patches/Dynamic/UIOptionWindow_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIOptionWindow_Patch.cs @@ -1,4 +1,5 @@ -using HarmonyLib; +using BepInEx.Configuration; +using HarmonyLib; using NebulaModel; using NebulaModel.Attributes; using NebulaModel.Logger; @@ -165,7 +166,6 @@ public static void _OnCreate_Postfix(UIOptionWindow __instance) checkboxTemplate = contentTemplate.Find("fullscreen").GetComponent(); comboBoxTemplate = contentTemplate.Find("resolution").GetComponent(); sliderTemplate = contentTemplate.Find("dofblur").GetComponent(); - inputTemplate = Object.Instantiate(checkboxTemplate, listContent, false); Object.Destroy(inputTemplate.Find("CheckBox").gameObject); RectTransform inputField = Object.Instantiate(UIRoot.instance.saveGameWindow.transform.Find("input-filename/InputField").GetComponent(), inputTemplate, false); @@ -305,6 +305,10 @@ private static void AddMultiplayerOptionsProperties() { CreateEnumControl(displayAttr, descriptionAttr, prop, anchorPosition, container); } + else if (prop.PropertyType == typeof(BepInEx.Configuration.KeyboardShortcut)) + { + CreateHotkeyControl(displayAttr, descriptionAttr, prop, anchorPosition, container); + } else { Log.Warn($"MultiplayerOption property \"${prop.Name}\" of type \"{prop.PropertyType}\" not supported."); @@ -396,7 +400,7 @@ private static void CreateNumberControl(DisplayNameAttribute control, Descriptio { try { - TypeConverter converter = TypeDescriptor.GetConverter(prop.PropertyType); + System.ComponentModel.TypeConverter converter = TypeDescriptor.GetConverter(prop.PropertyType); System.IComparable value = (System.IComparable)converter.ConvertFromString(str); if (rangeAttr != null) @@ -479,6 +483,48 @@ private static void CreateEnumControl(DisplayNameAttribute control, DescriptionA }; } + private static void CreateHotkeyControl(DisplayNameAttribute control, DescriptionAttribute descriptionAttr, PropertyInfo prop, Vector2 anchorPosition, Transform container) + { + UICharacterLimitAttribute characterLimitAttr = prop.GetCustomAttribute(); + UIContentTypeAttribute contentTypeAttr = prop.GetCustomAttribute(); + + RectTransform element = Object.Instantiate(inputTemplate, container, false); + SetupUIElement(element, control, descriptionAttr, prop, anchorPosition); + + InputField input = element.GetComponentInChildren(); + if (characterLimitAttr != null) + { + input.characterLimit = characterLimitAttr.Max; + } + if (contentTypeAttr != null) + { + input.contentType = contentTypeAttr.ContentType; + } + + input.onValueChanged.RemoveAllListeners(); + input.onValueChanged.AddListener((value) => { + if (!string.IsNullOrEmpty(value)) + { + KeyboardShortcut hotkey = KeyboardShortcut.Deserialize(value); + if (hotkey.Equals(KeyboardShortcut.Empty)) + { + // Show text color in red when the shortcut is not valid + input.textComponent.color = Color.red; + } + else + { + input.textComponent.color = Color.white; + prop.SetValue(tempMultiplayerOptions, hotkey, null); + } + } + }); + + tempToUICallbacks[prop.Name] = () => + { + input.text = ((KeyboardShortcut)prop.GetValue(tempMultiplayerOptions, null)).ToString(); + }; + } + private static void SetupUIElement(RectTransform element, DisplayNameAttribute display, DescriptionAttribute descriptionAttr, PropertyInfo prop, Vector2 anchorPosition) { element.gameObject.SetActive(true);