diff --git a/Attributes/AttributeFieldTypes.cs b/Attributes/AttributeFieldTypes.cs index 768c7a5..1da1161 100644 --- a/Attributes/AttributeFieldTypes.cs +++ b/Attributes/AttributeFieldTypes.cs @@ -24,7 +24,7 @@ private static ICollection Union(ICollection left, ICollection internal static bool IsFloatType(Type type) => floatTypes.Contains(type); internal static bool IsChoiceType(Type type) => choiceTypes.Contains(type); internal static bool IsSliderType(Type type) => sliderTypes.Contains(type); - internal static bool IsSupportedType(Type type) => type.IsEnum || supportedTypes.Contains(type); + internal static bool IsSupportedType(Type type) => type.IsEnum || supportedTypes.Contains(type) || type == typeof(string); internal static long MaxValue(Type numericType) { if (numericType == typeof(bool)) diff --git a/GUI/CustomStringInputField.cs b/GUI/CustomStringInputField.cs new file mode 100644 index 0000000..ab37012 --- /dev/null +++ b/GUI/CustomStringInputField.cs @@ -0,0 +1,47 @@ +using Il2Cpp; +using Il2CppInterop.Runtime.Attributes; +using Il2CppInterop.Runtime.Injection; +using UnityEngine; + +namespace ModSettings { + internal class CustomStringInputField : MonoBehaviour { + static CustomStringInputField() => ClassInjector.RegisterTypeInIl2Cpp(); + public CustomStringInputField(System.IntPtr intPtr) : base(intPtr) { } + + internal string currentString = string.Empty; + internal KeyRebindingButton keyRebindingButton; + internal System.Action OnChange; + internal string fieldName = ""; + + + public void Update() { + if (gameObject.activeSelf && keyRebindingButton.m_ValueLabel.text != currentString) { + RefreshLabelValue(); + } + } + + public void OpenInputField() + { + InterfaceManager.GetPanel().AddConfirmation(Panel_Confirmation.ConfirmationType.Rename, fieldName, currentString, Panel_Confirmation.ButtonLayout.Button_2, "GAMEPLAY_Apply", "GAMEPLAY_Cancel", Panel_Confirmation.Background.Transperent, new Action(MaybeUpdateKey), null); + } + + [HideFromIl2Cpp] + internal void OnClick() { + GameAudioManager.PlayGUIButtonClick(); + OpenInputField(); + } + + [HideFromIl2Cpp] + internal void RefreshLabelValue() { + keyRebindingButton.SetValueLabel(currentString); + } + + [HideFromIl2Cpp] + private void MaybeUpdateKey() { + + currentString = InterfaceManager.GetPanel().m_CurrentGroup.m_InputField.GetText(); + keyRebindingButton.SetValueLabel(currentString); + OnChange.Invoke(); + } + } +} diff --git a/GUI/GUIBuilder.cs b/GUI/GUIBuilder.cs index 7129c1d..37ae7b6 100644 --- a/GUI/GUIBuilder.cs +++ b/GUI/GUIBuilder.cs @@ -48,7 +48,9 @@ internal virtual void AddSettings(ModSettingsBase modSettings) { AddSliderSetting(modSettings, field, name, description, SliderAttribute.DefaultFloatRange); } else if (IsIntegerType(fieldType)) { AddSliderSetting(modSettings, field, name, description, SliderAttribute.DefaultIntRange); - } else { + } else if (fieldType == typeof(string)) { + AddStringSetting(modSettings, field, name, description); + } else { throw new ArgumentException("Unsupported field type: " + fieldType.Name); } } @@ -96,17 +98,50 @@ private void AddKeySetting(ModSettingsBase modSettings, FieldInfo field, NameAtt SetVisibilityListener(modSettings, field, setting, lastHeader); } - private void UpdateKeyValue(ModSettingsBase modSettings, FieldInfo field, CustomKeybinding customKeybinding) { + private void AddStringSetting(ModSettingsBase modSettings, FieldInfo field, NameAttribute name, DescriptionAttribute description) + { + // Create menu item + GameObject setting = CreateSetting(name, description, ObjectPrefabs.KeyEntryPrefab, "Label"); + GameObject keyButtonObject = setting.transform.FindChild("Keybinding_Button").gameObject; + + CustomStringInputField customInputField = setting.AddComponent(); + customInputField.keyRebindingButton = keyButtonObject.GetComponent(); + customInputField.fieldName = name.Name; + customInputField.currentString = (string)field.GetValue(modSettings); + customInputField.RefreshLabelValue(); + + UIButton uiButton = keyButtonObject.GetComponent(); + EventDelegate.Set(uiButton.onClick, new Action(customInputField.OnClick)); + customInputField.OnChange = new Action(() => UpdateStringValue(modSettings, field, customInputField)); + modSettings.AddRefreshAction(() => UpdateStringChoice(modSettings, field, customInputField)); + + // Control visibility + SetVisibilityListener(modSettings, field, setting, lastHeader); + } + + private void UpdateKeyValue(ModSettingsBase modSettings, FieldInfo field, CustomKeybinding customKeybinding) { SetSettingsField(modSettings, field, customKeybinding.currentKeycodeSetting); } - private void UpdateKeyChoice(ModSettingsBase modSettings, FieldInfo field, CustomKeybinding customKeybinding) { + private void UpdateStringValue(ModSettingsBase modSettings, FieldInfo field, CustomStringInputField customInputField) + { + SetSettingsField(modSettings, field, customInputField.currentString); + } + + private void UpdateKeyChoice(ModSettingsBase modSettings, FieldInfo field, CustomKeybinding customKeybinding) { KeyCode keyCode = (KeyCode)field.GetValue(modSettings); customKeybinding.currentKeycodeSetting = keyCode; customKeybinding.keyRebindingButton.SetValueLabel(keyCode.ToString()); } - private void AddChoiceSetting(ModSettingsBase modSettings, FieldInfo field, NameAttribute name, DescriptionAttribute description, ChoiceAttribute choice) { + private void UpdateStringChoice(ModSettingsBase modSettings, FieldInfo field, CustomStringInputField customInputField) + { + string StringVal = (string)field.GetValue(modSettings); + customInputField.currentString = StringVal; + customInputField.keyRebindingButton.SetValueLabel(StringVal); + } + + private void AddChoiceSetting(ModSettingsBase modSettings, FieldInfo field, NameAttribute name, DescriptionAttribute description, ChoiceAttribute choice) { // Create menu item GameObject setting = CreateSetting(name, description, ObjectPrefabs.ComboBoxPrefab, "Label"); ConsoleComboBox comboBox = setting.GetComponent();