diff --git a/Silksong.ModMenu/Directory.Build.props b/Silksong.ModMenu/Directory.Build.props
index 38caff4..04fadb4 100644
--- a/Silksong.ModMenu/Directory.Build.props
+++ b/Silksong.ModMenu/Directory.Build.props
@@ -11,6 +11,6 @@
It should follow the format major.minor.patch (semantic versioning). If you publish your mod
as a library to NuGet, this version will also be used as the package version.
-->
- 0.4.5
+ 0.4.6
diff --git a/Silksong.ModMenu/Elements/FontSizeConstants.cs b/Silksong.ModMenu/Elements/FontSizeConstants.cs
index 89567e3..f673995 100644
--- a/Silksong.ModMenu/Elements/FontSizeConstants.cs
+++ b/Silksong.ModMenu/Elements/FontSizeConstants.cs
@@ -35,17 +35,17 @@ public static int ChoiceSize(this FontSizes self) =>
///
/// Small font size for a choice description string.
///
- public const int DESCRIPTION_SMALL = 4;
+ public const int DESCRIPTION_SMALL = 27;
///
/// Standard font size for a choice description string.
///
- public const int DESCRIPTION_MEDIUM = 6;
+ public const int DESCRIPTION_MEDIUM = 41;
///
/// Large font size for a choice description string.
///
- public const int DESCRIPTION_LARGE = 9;
+ public const int DESCRIPTION_LARGE = 55;
///
/// Corresponding font size for a choice description string.
@@ -72,7 +72,7 @@ public static int DescriptionSize(this FontSizes self) =>
///
/// Large font size for a basic label string.
///
- public const int LABEL_LARGE = 68;
+ public const int LABEL_LARGE = 60;
///
/// Corresponding font size for a basic label string.
diff --git a/Silksong.ModMenu/Elements/MenuElement.cs b/Silksong.ModMenu/Elements/MenuElement.cs
index 5f6e7b3..59d5cce 100644
--- a/Silksong.ModMenu/Elements/MenuElement.cs
+++ b/Silksong.ModMenu/Elements/MenuElement.cs
@@ -116,5 +116,6 @@ public void SetGameObjectParent(GameObject container) =>
Container.transform.SetParent(container.transform, false);
///
- public void ClearGameObjectParent() => Container.transform.SetParent(null);
+ public void ClearGameObjectParent() =>
+ Container.transform.SetParent(null, worldPositionStays: false);
}
diff --git a/Silksong.ModMenu/Internal/IndexedList.cs b/Silksong.ModMenu/Internal/IndexedList.cs
index b2f9f4c..6f3d313 100644
--- a/Silksong.ModMenu/Internal/IndexedList.cs
+++ b/Silksong.ModMenu/Internal/IndexedList.cs
@@ -21,7 +21,7 @@ public T this[int index]
if (index < 0 || index >= list.Count)
throw new IndexOutOfRangeException($"{index} (Count: {list.Count})");
- if (lookup.TryGetValue(list[index], out var prev))
+ if (lookup.TryGetValue(value, out var prev))
{
if (prev == index)
return;
@@ -95,6 +95,7 @@ public bool TryRemoveAt(int index, [MaybeNullWhen(false)] out T item)
item = list[index];
list.RemoveAt(index);
+ lookup.Remove(item);
UpdateIndex(index);
return true;
}
diff --git a/Silksong.ModMenu/Internal/MenuPrefabs.cs b/Silksong.ModMenu/Internal/MenuPrefabs.cs
index a2712fc..d972177 100644
--- a/Silksong.ModMenu/Internal/MenuPrefabs.cs
+++ b/Silksong.ModMenu/Internal/MenuPrefabs.cs
@@ -44,14 +44,14 @@ private MenuPrefabs(UIManager uiManager)
menuTemplate = Object.Instantiate(optionsScreen);
menuTemplate.SetActive(false);
menuTemplate.name = "ModMenuScreen";
- Object.Destroy(menuTemplate.GetComponent());
- Object.Destroy(menuTemplate.FindChild("Title")!.GetComponent());
+ menuTemplate.RemoveComponent();
+ menuTemplate.FindChild("Title")!.RemoveComponent();
Object.DontDestroyOnLoad(menuTemplate);
emptyContentPane = menuTemplate.FindChild("Content")!;
emptyContentPane.DestroyAllChildren();
- Object.Destroy(emptyContentPane.GetComponent());
- Object.Destroy(emptyContentPane.GetComponent());
+ emptyContentPane.RemoveComponent();
+ emptyContentPane.RemoveComponent();
Object.DontDestroyOnLoad(emptyContentPane);
// MappableKey.OnEnable() breaks when instantiated outside the UIButtonSkins hierarchy.
@@ -62,9 +62,9 @@ private MenuPrefabs(UIManager uiManager)
);
}
keyBindTemplate.SetActive(false);
- Object.Destroy(
- keyBindTemplate.FindChild("Input Button Text")!.GetComponent()
- );
+ keyBindTemplate
+ .FindChild("Input Button Text")!
+ .RemoveComponent();
Object.DontDestroyOnLoad(keyBindTemplate);
textButtonTemplate = Object.Instantiate(optionsScreen.FindChild("Content/GameOptions")!);
@@ -74,12 +74,16 @@ private MenuPrefabs(UIManager uiManager)
var buttonChild = textButtonTemplate.FindChild("GameOptionsButton")!;
buttonChild.name = "TextButton";
- Object.Destroy(buttonChild.GetComponent());
+ // We have to remove this component as it's on a different GameObject to the Text,
+ // so it won't be removed by the LocalizedTextExtensions
+ buttonChild.RemoveComponent();
+ buttonChild.FindChild("Menu Button Text")!.RemoveComponent();
textLabelTemplate = Object.Instantiate(
optionsScreen.FindChild("Content/GameOptions/GameOptionsButton/Menu Button Text")!
);
textLabelTemplate.SetActive(false);
+ textLabelTemplate.RemoveComponent();
textLabelTemplate.name = "TextLabel";
Object.DontDestroyOnLoad(textLabelTemplate);
@@ -92,15 +96,17 @@ private MenuPrefabs(UIManager uiManager)
var choiceChild = textChoiceTemplate.FindChild("CamShakePopupOption")!;
choiceChild.name = "ValueChoice";
- Object.Destroy(choiceChild.GetComponent());
+ choiceChild.RemoveComponent();
var moh = choiceChild.GetComponent();
moh.optionList = ["###INTERNAL###"];
moh.menuSetting = null;
moh.localizeText = false;
moh.applyButton = null;
- Object.Destroy(
- choiceChild.FindChild("Menu Option Label")!.GetComponent()
- );
+ choiceChild
+ .FindChild("Menu Option Label")!
+ .RemoveComponent();
+ choiceChild.FindChild("Menu Option Text")!.RemoveComponent();
+ choiceChild.FindChild("Description")!.RemoveComponent();
textInputTemplate = Object.Instantiate(textChoiceTemplate);
textInputTemplate.SetActive(false);
@@ -109,10 +115,10 @@ private MenuPrefabs(UIManager uiManager)
var textInputChild = textInputTemplate.FindChild("ValueChoice")!;
textInputChild.name = "TextInput";
- Object.Destroy(textInputChild.GetComponent());
- Object.Destroy(textInputChild.GetComponent());
+ textInputChild.RemoveComponent();
+ textInputChild.RemoveComponent();
Object.DestroyImmediate(textInputChild.GetComponent()); // We must delete the Selectable immediately to add a new one.
- Object.Destroy(textInputChild.GetComponent());
+ textInputChild.RemoveComponent();
var textInputField = textInputChild.AddComponent();
textInputField.textComponent = textInputChild
.FindChild("Menu Option Text")!
@@ -132,11 +138,11 @@ private MenuPrefabs(UIManager uiManager)
var sliderChild = sliderTemplate.FindChild("MasterSlider")!;
sliderChild.name = "Slider";
sliderChild.GetComponent().onValueChanged = new();
- Object.Destroy(sliderChild.GetComponent());
+ sliderChild.RemoveComponent();
sliderChild.GetOrAddComponent();
- Object.Destroy(
- sliderChild.FindChild("Menu Option Label")!.GetComponent()
- );
+ sliderChild
+ .FindChild("Menu Option Label")!
+ .RemoveComponent();
sliderChild.FindChild("MasterVolValue")!.name = "Value";
}
diff --git a/Silksong.ModMenu/Silksong.ModMenu.csproj b/Silksong.ModMenu/Silksong.ModMenu.csproj
index 2e9fbd8..efdf61c 100644
--- a/Silksong.ModMenu/Silksong.ModMenu.csproj
+++ b/Silksong.ModMenu/Silksong.ModMenu.csproj
@@ -41,7 +41,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
diff --git a/Silksong.ModMenuTesting/ModMenuTestingPlugin.cs b/Silksong.ModMenuTesting/ModMenuTestingPlugin.cs
index 5017188..12a656c 100644
--- a/Silksong.ModMenuTesting/ModMenuTestingPlugin.cs
+++ b/Silksong.ModMenuTesting/ModMenuTestingPlugin.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Reflection;
using BepInEx;
+using BepInEx.Logging;
using Silksong.ModMenu.Elements;
using Silksong.ModMenu.Plugin;
using Silksong.ModMenu.Screens;
@@ -12,9 +13,11 @@ namespace Silksong.ModMenuTesting;
[BepInAutoPlugin(id: "org.silksong_modding.modmenutesting")]
public partial class ModMenuTestingPlugin : BaseUnityPlugin, IModMenuCustomMenu
{
+ internal static ManualLogSource InstanceLogger = null!;
+
private void Awake()
{
- // Put your initialization logic here
+ InstanceLogger = this.Logger;
Logger.LogInfo($"Plugin {Name} ({Id}) has loaded!");
}
diff --git a/Silksong.ModMenuTesting/Tests/ElementSizesTest.cs b/Silksong.ModMenuTesting/Tests/ElementSizesTest.cs
new file mode 100644
index 0000000..df0358c
--- /dev/null
+++ b/Silksong.ModMenuTesting/Tests/ElementSizesTest.cs
@@ -0,0 +1,34 @@
+using Silksong.ModMenu.Elements;
+using Silksong.ModMenu.Screens;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Silksong.ModMenuTesting.Tests;
+
+internal class ElementSizesTest : ModMenuTest
+{
+ internal override string Name => "Element Sizes Test";
+
+ internal override AbstractMenuScreen BuildMenuScreen()
+ {
+ PaginatedMenuScreenBuilder builder = new(Name);
+
+ TextButton makeSmall = new("Make Small");
+ TextButton makeMedium = new("Make Medium");
+ TextButton makeLarge = new("Make Large");
+
+ builder.Add(makeSmall);
+ builder.Add(makeMedium);
+ builder.Add(makeLarge);
+
+ List elements = StandardElementsTest.CreateUnboundElements().ToList();
+
+ makeSmall.OnSubmit += () => elements.ForEach(x => x.SetFontSizes(FontSizes.Small));
+ makeMedium.OnSubmit += () => elements.ForEach(x => x.SetFontSizes(FontSizes.Medium));
+ makeLarge.OnSubmit += () => elements.ForEach(x => x.SetFontSizes(FontSizes.Large));
+
+ builder.AddRange(elements);
+
+ return builder.Build();
+ }
+}
diff --git a/Silksong.ModMenuTesting/Tests/StandardElementsTest.cs b/Silksong.ModMenuTesting/Tests/StandardElementsTest.cs
new file mode 100644
index 0000000..9c8df1a
--- /dev/null
+++ b/Silksong.ModMenuTesting/Tests/StandardElementsTest.cs
@@ -0,0 +1,68 @@
+using Silksong.ModMenu.Elements;
+using Silksong.ModMenu.Models;
+using Silksong.ModMenu.Screens;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Silksong.ModMenuTesting.Tests;
+
+internal class StandardElementsTest : ModMenuTest
+{
+ private static void Log(string message) => ModMenuTestingPlugin.InstanceLogger.LogInfo(message);
+
+ internal override string Name => "Standard Elements";
+
+ ///
+ /// Yields common elements that log their value when changed.
+ ///
+ internal static IEnumerable CreateUnboundElements()
+ {
+ {
+ TextButton button = new("The Text Button");
+ button.OnSubmit += () => Log($"Pressed text button");
+ yield return button;
+ }
+
+ {
+ IntSliderModel sliderModel = new(3, 8);
+ SliderElement intSliderElement = new("The Int Slider", sliderModel);
+ sliderModel.SetValue(6);
+ sliderModel.OnValueChanged += n => Log($"Int slider -> {n}");
+ yield return intSliderElement;
+ }
+
+ {
+ ListChoiceModel listChoiceModel = new(["First", "Second", "Third"]);
+ ChoiceElement choiceElement = new("The List Choice", listChoiceModel, "Here is where to choose option(s)");
+ listChoiceModel.OnValueChanged += v => Log($"List choice -> {v}");
+ yield return choiceElement;
+ }
+
+ {
+ TextLabel label = new("The Label");
+ // Commented out because this is bugged ATM
+ // yield return label;
+ }
+
+ {
+ KeyBindElement keybindElement = new("The Keybind");
+ keybindElement.Model.OnValueChanged += k => Log($"Keybind value -> {k}");
+ yield return keybindElement;
+ }
+
+ {
+ ITextModel textModel = TextModels.ForStrings();
+ TextInput stringInput = new("The Text Input", textModel, "Here is where to input text");
+ textModel.OnValueChanged += s => Log($"Text model -> {s}");
+ yield return stringInput;
+ }
+ }
+
+ internal override AbstractMenuScreen BuildMenuScreen()
+ {
+ PaginatedMenuScreenBuilder builder = new(Name);
+ builder.AddRange(CreateUnboundElements());
+ return builder.Build();
+ }
+}