Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Silksong.ModMenu/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -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.
-->
<Version>0.4.5</Version>
<Version>0.4.6</Version>
</PropertyGroup>
</Project>
8 changes: 4 additions & 4 deletions Silksong.ModMenu/Elements/FontSizeConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ public static int ChoiceSize(this FontSizes self) =>
/// <summary>
/// Small font size for a choice description string.
/// </summary>
public const int DESCRIPTION_SMALL = 4;
public const int DESCRIPTION_SMALL = 27;

/// <summary>
/// Standard font size for a choice description string.
/// </summary>
public const int DESCRIPTION_MEDIUM = 6;
public const int DESCRIPTION_MEDIUM = 41;

/// <summary>
/// Large font size for a choice description string.
/// </summary>
public const int DESCRIPTION_LARGE = 9;
public const int DESCRIPTION_LARGE = 55;

/// <summary>
/// Corresponding font size for a choice description string.
Expand All @@ -72,7 +72,7 @@ public static int DescriptionSize(this FontSizes self) =>
/// <summary>
/// Large font size for a basic label string.
/// </summary>
public const int LABEL_LARGE = 68;
public const int LABEL_LARGE = 60;

/// <summary>
/// Corresponding font size for a basic label string.
Expand Down
3 changes: 2 additions & 1 deletion Silksong.ModMenu/Elements/MenuElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,6 @@ public void SetGameObjectParent(GameObject container) =>
Container.transform.SetParent(container.transform, false);

/// <inheritdoc/>
public void ClearGameObjectParent() => Container.transform.SetParent(null);
public void ClearGameObjectParent() =>
Container.transform.SetParent(null, worldPositionStays: false);
}
3 changes: 2 additions & 1 deletion Silksong.ModMenu/Internal/IndexedList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
44 changes: 25 additions & 19 deletions Silksong.ModMenu/Internal/MenuPrefabs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ private MenuPrefabs(UIManager uiManager)
menuTemplate = Object.Instantiate(optionsScreen);
menuTemplate.SetActive(false);
menuTemplate.name = "ModMenuScreen";
Object.Destroy(menuTemplate.GetComponent<MenuButtonList>());
Object.Destroy(menuTemplate.FindChild("Title")!.GetComponent<AutoLocalizeTextUI>());
menuTemplate.RemoveComponent<MenuButtonList>();
menuTemplate.FindChild("Title")!.RemoveComponent<AutoLocalizeTextUI>();
Object.DontDestroyOnLoad(menuTemplate);

emptyContentPane = menuTemplate.FindChild("Content")!;
emptyContentPane.DestroyAllChildren();
Object.Destroy(emptyContentPane.GetComponent<VerticalLayoutGroup>());
Object.Destroy(emptyContentPane.GetComponent<MenuButtonList>());
emptyContentPane.RemoveComponent<VerticalLayoutGroup>();
emptyContentPane.RemoveComponent<MenuButtonList>();
Object.DontDestroyOnLoad(emptyContentPane);

// MappableKey.OnEnable() breaks when instantiated outside the UIButtonSkins hierarchy.
Expand All @@ -62,9 +62,9 @@ private MenuPrefabs(UIManager uiManager)
);
}
keyBindTemplate.SetActive(false);
Object.Destroy(
keyBindTemplate.FindChild("Input Button Text")!.GetComponent<AutoLocalizeTextUI>()
);
keyBindTemplate
.FindChild("Input Button Text")!
.RemoveComponent<ChangeTextFontScaleOnHandHeld>();
Object.DontDestroyOnLoad(keyBindTemplate);

textButtonTemplate = Object.Instantiate(optionsScreen.FindChild("Content/GameOptions")!);
Expand All @@ -74,12 +74,16 @@ private MenuPrefabs(UIManager uiManager)

var buttonChild = textButtonTemplate.FindChild("GameOptionsButton")!;
buttonChild.name = "TextButton";
Object.Destroy(buttonChild.GetComponent<AutoLocalizeTextUI>());
// 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<AutoLocalizeTextUI>();
buttonChild.FindChild("Menu Button Text")!.RemoveComponent<ChangeTextFontScaleOnHandHeld>();

textLabelTemplate = Object.Instantiate(
optionsScreen.FindChild("Content/GameOptions/GameOptionsButton/Menu Button Text")!
);
textLabelTemplate.SetActive(false);
textLabelTemplate.RemoveComponent<ChangeTextFontScaleOnHandHeld>();
textLabelTemplate.name = "TextLabel";
Object.DontDestroyOnLoad(textLabelTemplate);

Expand All @@ -92,15 +96,17 @@ private MenuPrefabs(UIManager uiManager)

var choiceChild = textChoiceTemplate.FindChild("CamShakePopupOption")!;
choiceChild.name = "ValueChoice";
Object.Destroy(choiceChild.GetComponent<MenuSetting>());
choiceChild.RemoveComponent<MenuSetting>();
var moh = choiceChild.GetComponent<MenuOptionHorizontal>();
moh.optionList = ["###INTERNAL###"];
moh.menuSetting = null;
moh.localizeText = false;
moh.applyButton = null;
Object.Destroy(
choiceChild.FindChild("Menu Option Label")!.GetComponent<AutoLocalizeTextUI>()
);
choiceChild
.FindChild("Menu Option Label")!
.RemoveComponent<ChangeTextFontScaleOnHandHeld>();
choiceChild.FindChild("Menu Option Text")!.RemoveComponent<ChangeTextFontScaleOnHandHeld>();
choiceChild.FindChild("Description")!.RemoveComponent<ChangeTextFontScaleOnHandHeld>();

textInputTemplate = Object.Instantiate(textChoiceTemplate);
textInputTemplate.SetActive(false);
Expand All @@ -109,10 +115,10 @@ private MenuPrefabs(UIManager uiManager)

var textInputChild = textInputTemplate.FindChild("ValueChoice")!;
textInputChild.name = "TextInput";
Object.Destroy(textInputChild.GetComponent<EventTrigger>());
Object.Destroy(textInputChild.GetComponent<FixVerticalAlign>());
textInputChild.RemoveComponent<EventTrigger>();
textInputChild.RemoveComponent<FixVerticalAlign>();
Object.DestroyImmediate(textInputChild.GetComponent<MenuOptionHorizontal>()); // We must delete the Selectable immediately to add a new one.
Object.Destroy(textInputChild.GetComponent<MenuSetting>());
textInputChild.RemoveComponent<MenuSetting>();
var textInputField = textInputChild.AddComponent<CustomInputField>();
textInputField.textComponent = textInputChild
.FindChild("Menu Option Text")!
Expand All @@ -132,11 +138,11 @@ private MenuPrefabs(UIManager uiManager)
var sliderChild = sliderTemplate.FindChild("MasterSlider")!;
sliderChild.name = "Slider";
sliderChild.GetComponent<Slider>().onValueChanged = new();
Object.Destroy(sliderChild.GetComponent<MenuAudioSlider>());
sliderChild.RemoveComponent<MenuAudioSlider>();
sliderChild.GetOrAddComponent<SliderRightStickInput>();
Object.Destroy(
sliderChild.FindChild("Menu Option Label")!.GetComponent<AutoLocalizeTextUI>()
);
sliderChild
.FindChild("Menu Option Label")!
.RemoveComponent<ChangeTextFontScaleOnHandHeld>();
sliderChild.FindChild("MasterVolValue")!.name = "Value";
}

Expand Down
2 changes: 1 addition & 1 deletion Silksong.ModMenu/Silksong.ModMenu.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Silksong.UnityHelper" Version="1.1.1" />
<PackageReference Include="Silksong.UnityHelper" Version="1.2.0" />
<PackageReference Include="UnityEngine.Modules" Version="6000.0.50" IncludeAssets="compile" />
<PackageReference Include="CSharpier.MsBuild" Version="1.2.6" PrivateAssets="all" />
</ItemGroup>
Expand Down
5 changes: 4 additions & 1 deletion Silksong.ModMenuTesting/ModMenuTestingPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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!");
}

Expand Down
34 changes: 34 additions & 0 deletions Silksong.ModMenuTesting/Tests/ElementSizesTest.cs
Original file line number Diff line number Diff line change
@@ -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<MenuElement> 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();
}
}
68 changes: 68 additions & 0 deletions Silksong.ModMenuTesting/Tests/StandardElementsTest.cs
Original file line number Diff line number Diff line change
@@ -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";

/// <summary>
/// Yields common elements that log their value when changed.
/// </summary>
internal static IEnumerable<MenuElement> CreateUnboundElements()
{
{
TextButton button = new("The Text Button");
button.OnSubmit += () => Log($"Pressed text button");
yield return button;
}

{
IntSliderModel sliderModel = new(3, 8);
SliderElement<int> intSliderElement = new("The Int Slider", sliderModel);
sliderModel.SetValue(6);
sliderModel.OnValueChanged += n => Log($"Int slider -> {n}");
yield return intSliderElement;
}

{
ListChoiceModel<string> listChoiceModel = new(["First", "Second", "Third"]);
ChoiceElement<string> 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<string> textModel = TextModels.ForStrings();
TextInput<string> 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();
}
}