diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml
index a3db1f9..a67ee0f 100644
--- a/.github/workflows/build-publish.yml
+++ b/.github/workflows/build-publish.yml
@@ -46,7 +46,7 @@ jobs:
- name: Get Version
id: version
run: |-
- VERSION=$(dotnet build Silksong.ModMenu.csproj -getProperty:Version)
+ VERSION=$(dotnet build Silksong.ModMenu/Silksong.ModMenu.csproj -getProperty:Version)
echo Version is $VERSION
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Upload thunderstore artifact
diff --git a/.husky/pre-commit b/.husky/pre-commit
old mode 100755
new mode 100644
diff --git a/Silksong.ModMenu.sln b/Silksong.ModMenu.sln
index a12f5c2..1d71fb2 100644
--- a/Silksong.ModMenu.sln
+++ b/Silksong.ModMenu.sln
@@ -1,25 +1,31 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.14.36623.8 d17.14
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silksong.ModMenu", "Silksong.ModMenu.csproj", "{2DB486FC-5E09-737A-CED6-80241230DE8A}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {2DB486FC-5E09-737A-CED6-80241230DE8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2DB486FC-5E09-737A-CED6-80241230DE8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2DB486FC-5E09-737A-CED6-80241230DE8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2DB486FC-5E09-737A-CED6-80241230DE8A}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {B9C2DFAE-63A6-4317-A691-A213FAC4D73A}
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 18
+VisualStudioVersion = 18.4.11519.219 insiders
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silksong.ModMenu", "Silksong.ModMenu\Silksong.ModMenu.csproj", "{2DB486FC-5E09-737A-CED6-80241230DE8A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silksong.ModMenuTesting", "Silksong.ModMenuTesting\Silksong.ModMenuTesting.csproj", "{51062B71-1574-6F9F-4C4B-238385402476}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2DB486FC-5E09-737A-CED6-80241230DE8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2DB486FC-5E09-737A-CED6-80241230DE8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2DB486FC-5E09-737A-CED6-80241230DE8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2DB486FC-5E09-737A-CED6-80241230DE8A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {51062B71-1574-6F9F-4C4B-238385402476}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {51062B71-1574-6F9F-4C4B-238385402476}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {51062B71-1574-6F9F-4C4B-238385402476}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {51062B71-1574-6F9F-4C4B-238385402476}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B9C2DFAE-63A6-4317-A691-A213FAC4D73A}
+ EndGlobalSection
+EndGlobal
diff --git a/Directory.Build.props b/Silksong.ModMenu/Directory.Build.props
similarity index 100%
rename from Directory.Build.props
rename to Silksong.ModMenu/Directory.Build.props
diff --git a/Elements/AbstractGroup.cs b/Silksong.ModMenu/Elements/AbstractGroup.cs
similarity index 76%
rename from Elements/AbstractGroup.cs
rename to Silksong.ModMenu/Elements/AbstractGroup.cs
index 85a608a..915b891 100644
--- a/Elements/AbstractGroup.cs
+++ b/Silksong.ModMenu/Elements/AbstractGroup.cs
@@ -10,26 +10,50 @@ namespace Silksong.ModMenu.Elements;
///
/// Common functionality shared by most entity groups.
///
-public abstract class AbstractGroup : INavigableMenuEntity
+public abstract class AbstractGroup : MenuDisposable, INavigableMenuEntity
{
private readonly VisibilityManager visibility = new(false);
+ ///
+ /// Construct an AbstractGroup.
+ ///
+ protected AbstractGroup()
+ {
+ OnDispose += () =>
+ {
+ foreach (var disposable in AllEntities().OfType())
+ disposable.Dispose();
+ };
+ }
+
///
public VisibilityManager Visibility => visibility;
///
/// Enumerate all child entities within this group.
///
- protected abstract IEnumerable AllEntities();
+ public abstract IEnumerable AllEntities();
///
public IEnumerable AllElements() => AllEntities().SelectMany(e => e.AllElements());
+ ///
+ /// Whether this entity is directly contained within thie group.
+ ///
+ public abstract bool Contains(IMenuEntity entity);
+
///
/// Register `entity` as a child of this group.
///
protected void AddChild(IMenuEntity entity) => entity.SetParents(this, gameObjectParent);
+ ///
+ /// Clear all entities from this group.
+ ///
+ /// This does not destroy the corresponding game objects. The caller should call `Dispose()` on the entities after `Clear()` if they are no longer wanted.
+ ///
+ public abstract void Clear();
+
///
/// Enumerate all navigables which should be directly connected in `direction`.
///
diff --git a/Elements/BaseSelectableValueElement.cs b/Silksong.ModMenu/Elements/BaseSelectableValueElement.cs
similarity index 100%
rename from Elements/BaseSelectableValueElement.cs
rename to Silksong.ModMenu/Elements/BaseSelectableValueElement.cs
diff --git a/Elements/ChoiceElement.cs b/Silksong.ModMenu/Elements/ChoiceElement.cs
similarity index 100%
rename from Elements/ChoiceElement.cs
rename to Silksong.ModMenu/Elements/ChoiceElement.cs
diff --git a/Elements/Colors.cs b/Silksong.ModMenu/Elements/Colors.cs
similarity index 100%
rename from Elements/Colors.cs
rename to Silksong.ModMenu/Elements/Colors.cs
diff --git a/Elements/DynamicDescriptionChoiceElement.cs b/Silksong.ModMenu/Elements/DynamicDescriptionChoiceElement.cs
similarity index 99%
rename from Elements/DynamicDescriptionChoiceElement.cs
rename to Silksong.ModMenu/Elements/DynamicDescriptionChoiceElement.cs
index 9283bc3..ea678ac 100644
--- a/Elements/DynamicDescriptionChoiceElement.cs
+++ b/Silksong.ModMenu/Elements/DynamicDescriptionChoiceElement.cs
@@ -88,14 +88,14 @@ private static Text SetupRightDescription(Text descriptionText, Text choiceText)
return rightText;
}
- ///
+ ///
public override void SetFontSizes(FontSizes fontSizes)
{
base.SetFontSizes(fontSizes);
RightText.fontSize = fontSizes.DescriptionSize();
}
- ///
+ ///
public override void SetMainColor(Color color)
{
base.SetMainColor(color);
diff --git a/Elements/ElementState.cs b/Silksong.ModMenu/Elements/ElementState.cs
similarity index 100%
rename from Elements/ElementState.cs
rename to Silksong.ModMenu/Elements/ElementState.cs
diff --git a/Elements/FontSizeConstants.cs b/Silksong.ModMenu/Elements/FontSizeConstants.cs
similarity index 100%
rename from Elements/FontSizeConstants.cs
rename to Silksong.ModMenu/Elements/FontSizeConstants.cs
diff --git a/Elements/FontSizes.cs b/Silksong.ModMenu/Elements/FontSizes.cs
similarity index 100%
rename from Elements/FontSizes.cs
rename to Silksong.ModMenu/Elements/FontSizes.cs
diff --git a/Elements/FreeGroup.cs b/Silksong.ModMenu/Elements/FreeGroup.cs
similarity index 80%
rename from Elements/FreeGroup.cs
rename to Silksong.ModMenu/Elements/FreeGroup.cs
index 52c6816..bac9da0 100644
--- a/Elements/FreeGroup.cs
+++ b/Silksong.ModMenu/Elements/FreeGroup.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@@ -18,7 +17,21 @@ public class FreeGroup : AbstractGroup
private readonly LinkedDictionary entities = [];
///
- protected override IEnumerable AllEntities() => entities.Keys;
+ public override IEnumerable AllEntities() => entities.Keys;
+
+ ///
+ /// The total number of entities in this group.
+ ///
+ public int Count => entities.Count;
+
+ ///
+ public override bool Contains(IMenuEntity entity) => entities.ContainsKey(entity);
+
+ ///
+ /// Gets the positional offset of the given entity, if present.
+ ///
+ public bool TryGetOffset(IMenuEntity entity, out Vector2 offset) =>
+ entities.TryGetValue(entity, out offset);
///
/// Add an entity to this free group at the specified position.
@@ -54,6 +67,15 @@ public bool Remove(IMenuEntity entity)
return false;
}
+ ///
+ public override void Clear()
+ {
+ foreach (var entity in entities.Keys)
+ entity.ClearParents();
+
+ entities.Clear();
+ }
+
// Sort low values first.
private static float SortKey(NavigationDirection direction, Vector2 pos) =>
direction switch
diff --git a/Elements/GridGroup.cs b/Silksong.ModMenu/Elements/GridGroup.cs
similarity index 90%
rename from Elements/GridGroup.cs
rename to Silksong.ModMenu/Elements/GridGroup.cs
index bd3263f..52f4b2a 100644
--- a/Elements/GridGroup.cs
+++ b/Silksong.ModMenu/Elements/GridGroup.cs
@@ -42,6 +42,32 @@ public class GridGroup(int columns) : AbstractGroup
///
public bool WrapHorizontal = false;
+ ///
+ public override bool Contains(IMenuEntity entity) => index.ContainsKey(entity);
+
+ ///
+ /// Returns the row and column of the given entity.
+ ///
+ public bool TryGetCell(IMenuEntity entity, out int row, out int column)
+ {
+ if (index.TryGetValue(entity, out var c))
+ {
+ row = c.Row;
+ column = c.Column;
+ return true;
+ }
+
+ row = -1;
+ column = -1;
+ return false;
+ }
+
+ ///
+ /// Returns the entity at the given row and column, if present.
+ ///
+ public bool TryGetEntity(int row, int column, [MaybeNullWhen(false)] out IMenuEntity entity) =>
+ TryGetValue(new(row, column), out entity);
+
///
/// Add this entity to the next available empty cell in the grid.
///
@@ -112,6 +138,17 @@ public bool Remove(IMenuEntity entity)
public bool RemoveAt(int row, int column) =>
TryGetValue(new(row, column), out var entity) && Remove(entity);
+ ///
+ public override void Clear()
+ {
+ foreach (var entity in index.Keys)
+ entity.ClearParents();
+
+ rows.Clear();
+ index.Clear();
+ nextEmptyCell = new(0, 0);
+ }
+
///
public override bool GetSelectable(
NavigationDirection direction,
@@ -236,7 +273,7 @@ static bool ClosestColumn(
}
///
- protected override IEnumerable AllEntities() =>
+ public override IEnumerable AllEntities() =>
rows.SelectMany(row => row.WhereNonNull());
private ListView> GetColumns() =>
diff --git a/Elements/IMenuEntity.cs b/Silksong.ModMenu/Elements/IMenuEntity.cs
similarity index 100%
rename from Elements/IMenuEntity.cs
rename to Silksong.ModMenu/Elements/IMenuEntity.cs
diff --git a/Elements/IMenuEntityExtensions.cs b/Silksong.ModMenu/Elements/IMenuEntityExtensions.cs
similarity index 100%
rename from Elements/IMenuEntityExtensions.cs
rename to Silksong.ModMenu/Elements/IMenuEntityExtensions.cs
diff --git a/Elements/INavigable.cs b/Silksong.ModMenu/Elements/INavigable.cs
similarity index 100%
rename from Elements/INavigable.cs
rename to Silksong.ModMenu/Elements/INavigable.cs
diff --git a/Elements/INavigableExtensions.cs b/Silksong.ModMenu/Elements/INavigableExtensions.cs
similarity index 100%
rename from Elements/INavigableExtensions.cs
rename to Silksong.ModMenu/Elements/INavigableExtensions.cs
diff --git a/Elements/INavigableMenuEntity.cs b/Silksong.ModMenu/Elements/INavigableMenuEntity.cs
similarity index 100%
rename from Elements/INavigableMenuEntity.cs
rename to Silksong.ModMenu/Elements/INavigableMenuEntity.cs
diff --git a/Elements/KeyBindElement.cs b/Silksong.ModMenu/Elements/KeyBindElement.cs
similarity index 100%
rename from Elements/KeyBindElement.cs
rename to Silksong.ModMenu/Elements/KeyBindElement.cs
diff --git a/Elements/LocalizedText.cs b/Silksong.ModMenu/Elements/LocalizedText.cs
similarity index 100%
rename from Elements/LocalizedText.cs
rename to Silksong.ModMenu/Elements/LocalizedText.cs
diff --git a/Elements/LocalizedTextExtensions.cs b/Silksong.ModMenu/Elements/LocalizedTextExtensions.cs
similarity index 100%
rename from Elements/LocalizedTextExtensions.cs
rename to Silksong.ModMenu/Elements/LocalizedTextExtensions.cs
diff --git a/Elements/MenuDisposable.cs b/Silksong.ModMenu/Elements/MenuDisposable.cs
similarity index 100%
rename from Elements/MenuDisposable.cs
rename to Silksong.ModMenu/Elements/MenuDisposable.cs
diff --git a/Elements/MenuElement.cs b/Silksong.ModMenu/Elements/MenuElement.cs
similarity index 97%
rename from Elements/MenuElement.cs
rename to Silksong.ModMenu/Elements/MenuElement.cs
index 6589aea..5f6e7b3 100644
--- a/Elements/MenuElement.cs
+++ b/Silksong.ModMenu/Elements/MenuElement.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using Silksong.ModMenu.Internal;
using UnityEngine;
+using UObject = UnityEngine.Object;
namespace Silksong.ModMenu.Elements;
@@ -18,6 +19,8 @@ public abstract class MenuElement : MenuDisposable, IMenuEntity
protected MenuElement(GameObject container)
{
Container = container;
+ OnDispose += () => UObject.Destroy(container);
+
RectTransform = container.GetComponent();
visibility.OnVisibilityChanged += container.SetActive;
diff --git a/Elements/NavigationDirection.cs b/Silksong.ModMenu/Elements/NavigationDirection.cs
similarity index 100%
rename from Elements/NavigationDirection.cs
rename to Silksong.ModMenu/Elements/NavigationDirection.cs
diff --git a/Elements/NavigationDirectionExtensions.cs b/Silksong.ModMenu/Elements/NavigationDirectionExtensions.cs
similarity index 100%
rename from Elements/NavigationDirectionExtensions.cs
rename to Silksong.ModMenu/Elements/NavigationDirectionExtensions.cs
diff --git a/Elements/SelectableElement.cs b/Silksong.ModMenu/Elements/SelectableElement.cs
similarity index 100%
rename from Elements/SelectableElement.cs
rename to Silksong.ModMenu/Elements/SelectableElement.cs
diff --git a/Elements/SelectableValueElement.cs b/Silksong.ModMenu/Elements/SelectableValueElement.cs
similarity index 100%
rename from Elements/SelectableValueElement.cs
rename to Silksong.ModMenu/Elements/SelectableValueElement.cs
diff --git a/Elements/SliderElement.cs b/Silksong.ModMenu/Elements/SliderElement.cs
similarity index 100%
rename from Elements/SliderElement.cs
rename to Silksong.ModMenu/Elements/SliderElement.cs
diff --git a/Elements/SpacingConstants.cs b/Silksong.ModMenu/Elements/SpacingConstants.cs
similarity index 100%
rename from Elements/SpacingConstants.cs
rename to Silksong.ModMenu/Elements/SpacingConstants.cs
diff --git a/Elements/TextButton.cs b/Silksong.ModMenu/Elements/TextButton.cs
similarity index 100%
rename from Elements/TextButton.cs
rename to Silksong.ModMenu/Elements/TextButton.cs
diff --git a/Elements/TextInput.cs b/Silksong.ModMenu/Elements/TextInput.cs
similarity index 100%
rename from Elements/TextInput.cs
rename to Silksong.ModMenu/Elements/TextInput.cs
diff --git a/Elements/TextLabel.cs b/Silksong.ModMenu/Elements/TextLabel.cs
similarity index 100%
rename from Elements/TextLabel.cs
rename to Silksong.ModMenu/Elements/TextLabel.cs
diff --git a/Elements/VerticalGroup.cs b/Silksong.ModMenu/Elements/VerticalGroup.cs
similarity index 92%
rename from Elements/VerticalGroup.cs
rename to Silksong.ModMenu/Elements/VerticalGroup.cs
index d67a993..c756f93 100644
--- a/Elements/VerticalGroup.cs
+++ b/Silksong.ModMenu/Elements/VerticalGroup.cs
@@ -26,7 +26,10 @@ public class VerticalGroup : AbstractGroup
public bool HideInactiveElements = true;
///
- protected override IEnumerable AllEntities() => entities;
+ public override IEnumerable AllEntities() => entities;
+
+ ///
+ public override bool Contains(IMenuEntity entity) => entities.Contains(entity);
///
/// Add an entity to this vertical column group.
@@ -76,6 +79,15 @@ public void RemoveAt(int index)
entity.ClearParents();
}
+ ///
+ public override void Clear()
+ {
+ foreach (var entity in entities)
+ entity.ClearParents();
+
+ entities.Clear();
+ }
+
///
public override bool GetSelectable(
NavigationDirection direction,
diff --git a/Elements/VisibilityManager.cs b/Silksong.ModMenu/Elements/VisibilityManager.cs
similarity index 100%
rename from Elements/VisibilityManager.cs
rename to Silksong.ModMenu/Elements/VisibilityManager.cs
diff --git a/Internal/CollectionsUtil.cs b/Silksong.ModMenu/Internal/CollectionsUtil.cs
similarity index 100%
rename from Internal/CollectionsUtil.cs
rename to Silksong.ModMenu/Internal/CollectionsUtil.cs
diff --git a/Internal/CustomInputField.cs b/Silksong.ModMenu/Internal/CustomInputField.cs
similarity index 100%
rename from Internal/CustomInputField.cs
rename to Silksong.ModMenu/Internal/CustomInputField.cs
diff --git a/Internal/CustomMappableKey.cs b/Silksong.ModMenu/Internal/CustomMappableKey.cs
similarity index 100%
rename from Internal/CustomMappableKey.cs
rename to Silksong.ModMenu/Internal/CustomMappableKey.cs
diff --git a/Internal/CustomMenuOptionHorizontal.cs b/Silksong.ModMenu/Internal/CustomMenuOptionHorizontal.cs
similarity index 100%
rename from Internal/CustomMenuOptionHorizontal.cs
rename to Silksong.ModMenu/Internal/CustomMenuOptionHorizontal.cs
diff --git a/Internal/EnumUtil.cs b/Silksong.ModMenu/Internal/EnumUtil.cs
similarity index 100%
rename from Internal/EnumUtil.cs
rename to Silksong.ModMenu/Internal/EnumUtil.cs
diff --git a/Internal/EventSuppressor.cs b/Silksong.ModMenu/Internal/EventSuppressor.cs
similarity index 100%
rename from Internal/EventSuppressor.cs
rename to Silksong.ModMenu/Internal/EventSuppressor.cs
diff --git a/Internal/EventTriggerUtil.cs b/Silksong.ModMenu/Internal/EventTriggerUtil.cs
similarity index 100%
rename from Internal/EventTriggerUtil.cs
rename to Silksong.ModMenu/Internal/EventTriggerUtil.cs
diff --git a/Internal/ExceptionUtil.cs b/Silksong.ModMenu/Internal/ExceptionUtil.cs
similarity index 100%
rename from Internal/ExceptionUtil.cs
rename to Silksong.ModMenu/Internal/ExceptionUtil.cs
diff --git a/Internal/GameObjectUtil.cs b/Silksong.ModMenu/Internal/GameObjectUtil.cs
similarity index 100%
rename from Internal/GameObjectUtil.cs
rename to Silksong.ModMenu/Internal/GameObjectUtil.cs
diff --git a/Internal/IEnumeratorUtil.cs b/Silksong.ModMenu/Internal/IEnumeratorUtil.cs
similarity index 100%
rename from Internal/IEnumeratorUtil.cs
rename to Silksong.ModMenu/Internal/IEnumeratorUtil.cs
diff --git a/Internal/IndexedList.cs b/Silksong.ModMenu/Internal/IndexedList.cs
similarity index 100%
rename from Internal/IndexedList.cs
rename to Silksong.ModMenu/Internal/IndexedList.cs
diff --git a/Internal/KeyCodeUtil.cs b/Silksong.ModMenu/Internal/KeyCodeUtil.cs
similarity index 100%
rename from Internal/KeyCodeUtil.cs
rename to Silksong.ModMenu/Internal/KeyCodeUtil.cs
diff --git a/Internal/LateUpdateHelper.cs b/Silksong.ModMenu/Internal/LateUpdateHelper.cs
similarity index 100%
rename from Internal/LateUpdateHelper.cs
rename to Silksong.ModMenu/Internal/LateUpdateHelper.cs
diff --git a/Internal/LinkedDictionary.cs b/Silksong.ModMenu/Internal/LinkedDictionary.cs
similarity index 93%
rename from Internal/LinkedDictionary.cs
rename to Silksong.ModMenu/Internal/LinkedDictionary.cs
index 63a9c2e..f59f170 100644
--- a/Internal/LinkedDictionary.cs
+++ b/Silksong.ModMenu/Internal/LinkedDictionary.cs
@@ -13,7 +13,7 @@ internal class LinkedDictionary : IDictionary
public V this[K key]
{
get => data[key].Item2;
- set => data[key] = (data[key].Item1, value);
+ set => Set(key, value);
}
public ICollection Keys => new LinkedDictionaryKeys(this);
@@ -24,14 +24,21 @@ public V this[K key]
public bool IsReadOnly => false;
- public void Add(K key, V value) =>
+ public void Add(K key, V value)
+ {
+ if (data.ContainsKey(key))
+ throw new ArgumentException($"An element with the same key already exists: {key}");
+ data.Add(key, (keyOrder.AddLast(key), value));
+ }
+
+ public void Add(KeyValuePair item) => Add(item.Key, item.Value);
+
+ public void Set(K key, V value) =>
data[key] = (
data.TryGetValue(key, out var pair) ? pair.Item1 : keyOrder.AddLast(key),
value
);
- public void Add(KeyValuePair item) => Add(item.Key, item.Value);
-
public void Clear()
{
data.Clear();
diff --git a/Internal/ListView.cs b/Silksong.ModMenu/Internal/ListView.cs
similarity index 100%
rename from Internal/ListView.cs
rename to Silksong.ModMenu/Internal/ListView.cs
diff --git a/Internal/MenuPrefabs.cs b/Silksong.ModMenu/Internal/MenuPrefabs.cs
similarity index 100%
rename from Internal/MenuPrefabs.cs
rename to Silksong.ModMenu/Internal/MenuPrefabs.cs
diff --git a/Internal/OnDestroyHelper.cs b/Silksong.ModMenu/Internal/OnDestroyHelper.cs
similarity index 100%
rename from Internal/OnDestroyHelper.cs
rename to Silksong.ModMenu/Internal/OnDestroyHelper.cs
diff --git a/Internal/OnSelectHelper.cs b/Silksong.ModMenu/Internal/OnSelectHelper.cs
similarity index 100%
rename from Internal/OnSelectHelper.cs
rename to Silksong.ModMenu/Internal/OnSelectHelper.cs
diff --git a/Internal/RectTransformUtil.cs b/Silksong.ModMenu/Internal/RectTransformUtil.cs
similarity index 100%
rename from Internal/RectTransformUtil.cs
rename to Silksong.ModMenu/Internal/RectTransformUtil.cs
diff --git a/Internal/SelectableWrapper.cs b/Silksong.ModMenu/Internal/SelectableWrapper.cs
similarity index 100%
rename from Internal/SelectableWrapper.cs
rename to Silksong.ModMenu/Internal/SelectableWrapper.cs
diff --git a/Internal/StringUtil.cs b/Silksong.ModMenu/Internal/StringUtil.cs
similarity index 100%
rename from Internal/StringUtil.cs
rename to Silksong.ModMenu/Internal/StringUtil.cs
diff --git a/Internal/ThreadLocalContext.cs b/Silksong.ModMenu/Internal/ThreadLocalContext.cs
similarity index 100%
rename from Internal/ThreadLocalContext.cs
rename to Silksong.ModMenu/Internal/ThreadLocalContext.cs
diff --git a/Internal/UIManagerUtil.cs b/Silksong.ModMenu/Internal/UIManagerUtil.cs
similarity index 100%
rename from Internal/UIManagerUtil.cs
rename to Silksong.ModMenu/Internal/UIManagerUtil.cs
diff --git a/ModMenuPlugin.cs b/Silksong.ModMenu/ModMenuPlugin.cs
similarity index 100%
rename from ModMenuPlugin.cs
rename to Silksong.ModMenu/ModMenuPlugin.cs
diff --git a/Models/AbstractValueModel.cs b/Silksong.ModMenu/Models/AbstractValueModel.cs
similarity index 100%
rename from Models/AbstractValueModel.cs
rename to Silksong.ModMenu/Models/AbstractValueModel.cs
diff --git a/Models/Attributes.cs b/Silksong.ModMenu/Models/Attributes.cs
similarity index 100%
rename from Models/Attributes.cs
rename to Silksong.ModMenu/Models/Attributes.cs
diff --git a/Models/ChoiceModels.cs b/Silksong.ModMenu/Models/ChoiceModels.cs
similarity index 100%
rename from Models/ChoiceModels.cs
rename to Silksong.ModMenu/Models/ChoiceModels.cs
diff --git a/Models/Delegates.cs b/Silksong.ModMenu/Models/Delegates.cs
similarity index 100%
rename from Models/Delegates.cs
rename to Silksong.ModMenu/Models/Delegates.cs
diff --git a/Models/IBaseChoiceModel.cs b/Silksong.ModMenu/Models/IBaseChoiceModel.cs
similarity index 100%
rename from Models/IBaseChoiceModel.cs
rename to Silksong.ModMenu/Models/IBaseChoiceModel.cs
diff --git a/Models/IBaseValueModel.cs b/Silksong.ModMenu/Models/IBaseValueModel.cs
similarity index 100%
rename from Models/IBaseValueModel.cs
rename to Silksong.ModMenu/Models/IBaseValueModel.cs
diff --git a/Models/IChoiceModel.cs b/Silksong.ModMenu/Models/IChoiceModel.cs
similarity index 100%
rename from Models/IChoiceModel.cs
rename to Silksong.ModMenu/Models/IChoiceModel.cs
diff --git a/Models/IDisplayable.cs b/Silksong.ModMenu/Models/IDisplayable.cs
similarity index 100%
rename from Models/IDisplayable.cs
rename to Silksong.ModMenu/Models/IDisplayable.cs
diff --git a/Models/ITextModel.cs b/Silksong.ModMenu/Models/ITextModel.cs
similarity index 100%
rename from Models/ITextModel.cs
rename to Silksong.ModMenu/Models/ITextModel.cs
diff --git a/Models/IValueModel.cs b/Silksong.ModMenu/Models/IValueModel.cs
similarity index 100%
rename from Models/IValueModel.cs
rename to Silksong.ModMenu/Models/IValueModel.cs
diff --git a/Models/IntRangeChoiceModel.cs b/Silksong.ModMenu/Models/IntRangeChoiceModel.cs
similarity index 100%
rename from Models/IntRangeChoiceModel.cs
rename to Silksong.ModMenu/Models/IntRangeChoiceModel.cs
diff --git a/Models/IntSliderModel.cs b/Silksong.ModMenu/Models/IntSliderModel.cs
similarity index 100%
rename from Models/IntSliderModel.cs
rename to Silksong.ModMenu/Models/IntSliderModel.cs
diff --git a/Models/LinearFloatSliderModel.cs b/Silksong.ModMenu/Models/LinearFloatSliderModel.cs
similarity index 100%
rename from Models/LinearFloatSliderModel.cs
rename to Silksong.ModMenu/Models/LinearFloatSliderModel.cs
diff --git a/Models/ListChoiceModel.cs b/Silksong.ModMenu/Models/ListChoiceModel.cs
similarity index 100%
rename from Models/ListChoiceModel.cs
rename to Silksong.ModMenu/Models/ListChoiceModel.cs
diff --git a/Models/ListSliderModel.cs b/Silksong.ModMenu/Models/ListSliderModel.cs
similarity index 100%
rename from Models/ListSliderModel.cs
rename to Silksong.ModMenu/Models/ListSliderModel.cs
diff --git a/Models/ParserTextModel.cs b/Silksong.ModMenu/Models/ParserTextModel.cs
similarity index 100%
rename from Models/ParserTextModel.cs
rename to Silksong.ModMenu/Models/ParserTextModel.cs
diff --git a/Models/SliderModel.cs b/Silksong.ModMenu/Models/SliderModel.cs
similarity index 100%
rename from Models/SliderModel.cs
rename to Silksong.ModMenu/Models/SliderModel.cs
diff --git a/Models/SliderModels.cs b/Silksong.ModMenu/Models/SliderModels.cs
similarity index 100%
rename from Models/SliderModels.cs
rename to Silksong.ModMenu/Models/SliderModels.cs
diff --git a/Models/TextModels.cs b/Silksong.ModMenu/Models/TextModels.cs
similarity index 100%
rename from Models/TextModels.cs
rename to Silksong.ModMenu/Models/TextModels.cs
diff --git a/Models/ValueModel.cs b/Silksong.ModMenu/Models/ValueModel.cs
similarity index 100%
rename from Models/ValueModel.cs
rename to Silksong.ModMenu/Models/ValueModel.cs
diff --git a/Plugin/ConfigEntryFactory.cs b/Silksong.ModMenu/Plugin/ConfigEntryFactory.cs
similarity index 100%
rename from Plugin/ConfigEntryFactory.cs
rename to Silksong.ModMenu/Plugin/ConfigEntryFactory.cs
diff --git a/Plugin/IModMenuCustomElement.cs b/Silksong.ModMenu/Plugin/IModMenuCustomElement.cs
similarity index 100%
rename from Plugin/IModMenuCustomElement.cs
rename to Silksong.ModMenu/Plugin/IModMenuCustomElement.cs
diff --git a/Plugin/IModMenuCustomMenu.cs b/Silksong.ModMenu/Plugin/IModMenuCustomMenu.cs
similarity index 100%
rename from Plugin/IModMenuCustomMenu.cs
rename to Silksong.ModMenu/Plugin/IModMenuCustomMenu.cs
diff --git a/Plugin/IModMenuInterface.cs b/Silksong.ModMenu/Plugin/IModMenuInterface.cs
similarity index 100%
rename from Plugin/IModMenuInterface.cs
rename to Silksong.ModMenu/Plugin/IModMenuInterface.cs
diff --git a/Plugin/IModMenuToggle.cs b/Silksong.ModMenu/Plugin/IModMenuToggle.cs
similarity index 100%
rename from Plugin/IModMenuToggle.cs
rename to Silksong.ModMenu/Plugin/IModMenuToggle.cs
diff --git a/Plugin/MenuElementGenerators.cs b/Silksong.ModMenu/Plugin/MenuElementGenerators.cs
similarity index 100%
rename from Plugin/MenuElementGenerators.cs
rename to Silksong.ModMenu/Plugin/MenuElementGenerators.cs
diff --git a/Plugin/PluginRegistry.cs b/Silksong.ModMenu/Plugin/PluginRegistry.cs
similarity index 100%
rename from Plugin/PluginRegistry.cs
rename to Silksong.ModMenu/Plugin/PluginRegistry.cs
diff --git a/README.md b/Silksong.ModMenu/README.md
similarity index 100%
rename from README.md
rename to Silksong.ModMenu/README.md
diff --git a/Registry.cs b/Silksong.ModMenu/Registry.cs
similarity index 100%
rename from Registry.cs
rename to Silksong.ModMenu/Registry.cs
diff --git a/Screens/AbstractMenuScreen.cs b/Silksong.ModMenu/Screens/AbstractMenuScreen.cs
similarity index 100%
rename from Screens/AbstractMenuScreen.cs
rename to Silksong.ModMenu/Screens/AbstractMenuScreen.cs
diff --git a/Screens/BasicMenuScreen.cs b/Silksong.ModMenu/Screens/BasicMenuScreen.cs
similarity index 100%
rename from Screens/BasicMenuScreen.cs
rename to Silksong.ModMenu/Screens/BasicMenuScreen.cs
diff --git a/Screens/HistoryMode.cs b/Silksong.ModMenu/Screens/HistoryMode.cs
similarity index 100%
rename from Screens/HistoryMode.cs
rename to Silksong.ModMenu/Screens/HistoryMode.cs
diff --git a/Screens/MenuScreenNavigation.cs b/Silksong.ModMenu/Screens/MenuScreenNavigation.cs
similarity index 100%
rename from Screens/MenuScreenNavigation.cs
rename to Silksong.ModMenu/Screens/MenuScreenNavigation.cs
diff --git a/Screens/PaginatedMenuScreen.cs b/Silksong.ModMenu/Screens/PaginatedMenuScreen.cs
similarity index 100%
rename from Screens/PaginatedMenuScreen.cs
rename to Silksong.ModMenu/Screens/PaginatedMenuScreen.cs
diff --git a/Screens/PaginatedMenuScreenBuilder.cs b/Silksong.ModMenu/Screens/PaginatedMenuScreenBuilder.cs
similarity index 100%
rename from Screens/PaginatedMenuScreenBuilder.cs
rename to Silksong.ModMenu/Screens/PaginatedMenuScreenBuilder.cs
diff --git a/Screens/SelectOnShowBehaviour.cs b/Silksong.ModMenu/Screens/SelectOnShowBehaviour.cs
similarity index 100%
rename from Screens/SelectOnShowBehaviour.cs
rename to Silksong.ModMenu/Screens/SelectOnShowBehaviour.cs
diff --git a/Screens/SimpleMenuScreen.cs b/Silksong.ModMenu/Screens/SimpleMenuScreen.cs
similarity index 100%
rename from Screens/SimpleMenuScreen.cs
rename to Silksong.ModMenu/Screens/SimpleMenuScreen.cs
diff --git a/Silksong.ModMenu.csproj b/Silksong.ModMenu/Silksong.ModMenu.csproj
similarity index 94%
rename from Silksong.ModMenu.csproj
rename to Silksong.ModMenu/Silksong.ModMenu.csproj
index 384d604..2e9fbd8 100644
--- a/Silksong.ModMenu.csproj
+++ b/Silksong.ModMenu/Silksong.ModMenu.csproj
@@ -3,7 +3,7 @@
Imports silksong path properties only if present in order to allow CI builds. The file should be gitignored.
If you are checking out from git and need to create a new one, you can use `dotnet new silksongpath` to generate one.
-->
-
+
netstandard2.1
latest
@@ -64,9 +64,8 @@
-
-
+
@@ -75,7 +74,7 @@
- $(ProjectDir)/thunderstore
+ $(SolutionDir)/thunderstore
diff --git a/Util/SelectableUtil.cs b/Silksong.ModMenu/Util/SelectableUtil.cs
similarity index 100%
rename from Util/SelectableUtil.cs
rename to Silksong.ModMenu/Util/SelectableUtil.cs
diff --git a/Silksong.ModMenuTesting/Directory.Build.props b/Silksong.ModMenuTesting/Directory.Build.props
new file mode 100644
index 0000000..e898a36
--- /dev/null
+++ b/Silksong.ModMenuTesting/Directory.Build.props
@@ -0,0 +1,16 @@
+
+
+
+
+ ModMenuTesting
+
+ 0.1.0
+
+
diff --git a/Silksong.ModMenuTesting/ModMenuTest.cs b/Silksong.ModMenuTesting/ModMenuTest.cs
new file mode 100644
index 0000000..cc0972e
--- /dev/null
+++ b/Silksong.ModMenuTesting/ModMenuTest.cs
@@ -0,0 +1,10 @@
+using Silksong.ModMenu.Screens;
+
+namespace Silksong.ModMenuTesting;
+
+internal abstract class ModMenuTest
+{
+ internal abstract string Name { get; }
+
+ internal abstract AbstractMenuScreen BuildMenuScreen();
+}
diff --git a/Silksong.ModMenuTesting/ModMenuTestingPlugin.cs b/Silksong.ModMenuTesting/ModMenuTestingPlugin.cs
new file mode 100644
index 0000000..5017188
--- /dev/null
+++ b/Silksong.ModMenuTesting/ModMenuTestingPlugin.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using BepInEx;
+using Silksong.ModMenu.Elements;
+using Silksong.ModMenu.Plugin;
+using Silksong.ModMenu.Screens;
+
+namespace Silksong.ModMenuTesting;
+
+[BepInAutoPlugin(id: "org.silksong_modding.modmenutesting")]
+public partial class ModMenuTestingPlugin : BaseUnityPlugin, IModMenuCustomMenu
+{
+ private void Awake()
+ {
+ // Put your initialization logic here
+ Logger.LogInfo($"Plugin {Name} ({Id}) has loaded!");
+ }
+
+ private static IEnumerable CreateTests()
+ {
+ foreach (
+ var type in Assembly
+ .GetExecutingAssembly()
+ .GetTypes()
+ .Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(ModMenuTest)))
+ )
+ yield return (ModMenuTest)Activator.CreateInstance(type);
+ }
+
+ public AbstractMenuScreen BuildCustomMenu()
+ {
+ PaginatedMenuScreenBuilder builder = new("Mod Menu Testing");
+ foreach (var test in CreateTests().OrderBy(t => t.Name))
+ {
+ TextButton button = new(test.Name);
+
+ List screen = [];
+ var testCopy = test;
+ button.OnSubmit += () =>
+ {
+ if (screen.Count == 0)
+ {
+ try
+ {
+ screen.Add(testCopy.BuildMenuScreen());
+ }
+ catch (Exception ex)
+ {
+ button.State = ElementState.INVALID;
+ UnityEngine.Debug.LogError(
+ $"Failed to build mod menu for '{testCopy.Name}': {ex}"
+ );
+ }
+ }
+
+ if (screen.Count > 0)
+ MenuScreenNavigation.Show(screen[0]);
+ };
+
+ builder.Add(button);
+ }
+
+ return builder.Build();
+ }
+
+ public string ModMenuName() => "Mod Menu Testing";
+}
diff --git a/Silksong.ModMenuTesting/README.md b/Silksong.ModMenuTesting/README.md
new file mode 100644
index 0000000..d2deb5c
--- /dev/null
+++ b/Silksong.ModMenuTesting/README.md
@@ -0,0 +1,3 @@
+# Silksong.ModMenuTesting
+
+Testing plugin for Silksong.ModMenu. Provides examples of the many library features.
diff --git a/Silksong.ModMenuTesting/Silksong.ModMenuTesting.csproj b/Silksong.ModMenuTesting/Silksong.ModMenuTesting.csproj
new file mode 100644
index 0000000..464803c
--- /dev/null
+++ b/Silksong.ModMenuTesting/Silksong.ModMenuTesting.csproj
@@ -0,0 +1,47 @@
+
+
+
+
+ netstandard2.1
+ latest
+ enable
+ True
+ recommended
+
+ $(NoWarn);MSB3270
+
+
+ $(MSBuildProjectDirectory)=/
+
+ false
+ https://github.com/silksong_modding/Silksong.ModMenuTesting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Silksong.ModMenuTesting/Tests/FreeGroupTest.cs b/Silksong.ModMenuTesting/Tests/FreeGroupTest.cs
new file mode 100644
index 0000000..3432755
--- /dev/null
+++ b/Silksong.ModMenuTesting/Tests/FreeGroupTest.cs
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using Silksong.ModMenu.Elements;
+using Silksong.ModMenu.Screens;
+
+namespace Silksong.ModMenuTesting.Tests;
+
+internal class FreeGroupTest : ModMenuTest
+{
+ internal override string Name => "Free Group";
+
+ internal override AbstractMenuScreen BuildMenuScreen()
+ {
+ FreeGroup group = new();
+
+ TextButton topLeft = new("Top Left");
+ group.Add(topLeft, new(-800, 0));
+
+ List toggled = [true];
+ TextButton toggleTopLeft = new("Toggle Top Left");
+ toggleTopLeft.OnSubmit += () =>
+ {
+ toggled[0] = !toggled[0];
+ if (toggled[0])
+ group.Add(topLeft, new(-800, 0));
+ else
+ group.Remove(topLeft);
+ };
+ group.Add(toggleTopLeft, new(-800, -200));
+
+ TextButton middle = new("Middle");
+ group.Add(middle, new(0, -400));
+
+ TextButton moveLeft = new("Move Middle Left");
+ moveLeft.OnSubmit += () =>
+ {
+ group.TryGetOffset(middle, out var offset);
+ offset.x -= 25;
+ group.Update(middle, offset);
+ };
+ group.Add(moveLeft, new(-800, -600));
+
+ TextButton moveRight = new("Move Middle Right");
+ moveRight.OnSubmit += () =>
+ {
+ group.TryGetOffset(middle, out var offset);
+ offset.x += 25;
+ group.Update(middle, offset);
+ };
+ group.Add(moveRight, new(800, -600));
+
+ return new BasicMenuScreen("Free Group Test", group);
+ }
+}
diff --git a/Silksong.ModMenuTesting/Tests/GridGroupTest.cs b/Silksong.ModMenuTesting/Tests/GridGroupTest.cs
new file mode 100644
index 0000000..1b42b0d
--- /dev/null
+++ b/Silksong.ModMenuTesting/Tests/GridGroupTest.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using Silksong.ModMenu.Elements;
+using Silksong.ModMenu.Models;
+using Silksong.ModMenu.Screens;
+
+namespace Silksong.ModMenuTesting.Tests;
+
+internal class GridGroupTest : ModMenuTest
+{
+ private enum Spacing
+ {
+ Small,
+ Medium,
+ Large,
+ }
+
+ internal override string Name => "Grid Group";
+
+ internal override AbstractMenuScreen BuildMenuScreen()
+ {
+ GridGroup group = new(2);
+
+ group.Add(new TextButton("Button 1"));
+ group.Add(new TextButton("Button 2"));
+
+ ChoiceElement hSpacing = new(
+ "Horizontal Spacing",
+ ChoiceModels.ForEnum()
+ );
+ hSpacing.OnValueChanged += value =>
+ group.HorizontalSpacing = value switch
+ {
+ Spacing.Small => SpacingConstants.HSPACE_SMALL,
+ Spacing.Medium => SpacingConstants.HSPACE_MEDIUM,
+ Spacing.Large => SpacingConstants.HSPACE_LARGE,
+ _ => throw new ArgumentException($"{value}"),
+ };
+ hSpacing.Value = Spacing.Medium;
+ group.HorizontalSpacing = SpacingConstants.HSPACE_MEDIUM;
+ group.Add(hSpacing);
+ group.Add(new TextButton(""));
+
+ ChoiceElement vSpacing = new("Vertical Spacing", ChoiceModels.ForEnum());
+ vSpacing.OnValueChanged += value =>
+ group.VerticalSpacing = value switch
+ {
+ Spacing.Small => SpacingConstants.VSPACE_SMALL,
+ Spacing.Medium => SpacingConstants.VSPACE_MEDIUM,
+ Spacing.Large => SpacingConstants.VSPACE_LARGE,
+ _ => throw new ArgumentException($"{value}"),
+ };
+ vSpacing.Value = Spacing.Medium;
+ group.VerticalSpacing = SpacingConstants.VSPACE_MEDIUM;
+ group.Add(vSpacing);
+ group.Add(new TextButton(""));
+
+ Stack addedButtons = [];
+
+ TextButton addButton = new("Add");
+ addButton.OnSubmit += () =>
+ {
+ TextButton button = new("New Button");
+ group.Add(button);
+ addedButtons.Push(button);
+ };
+ group.Add(addButton);
+
+ TextButton removeButton = new("Remove");
+ removeButton.OnSubmit += () =>
+ {
+ if (addedButtons.Count > 0)
+ {
+ TextButton button = addedButtons.Pop();
+ group.Remove(button);
+ button.Dispose();
+ }
+ };
+ group.Add(removeButton);
+
+ return new BasicMenuScreen("Grid Group Test", group);
+ }
+}
diff --git a/Silksong.ModMenuTesting/Tests/VerticalGroupTest.cs b/Silksong.ModMenuTesting/Tests/VerticalGroupTest.cs
new file mode 100644
index 0000000..535f44c
--- /dev/null
+++ b/Silksong.ModMenuTesting/Tests/VerticalGroupTest.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Linq;
+using Silksong.ModMenu.Elements;
+using Silksong.ModMenu.Models;
+using Silksong.ModMenu.Screens;
+
+namespace Silksong.ModMenuTesting.Tests;
+
+internal enum VerticalGroupSpacing
+{
+ Small,
+ Medium,
+ Large,
+}
+
+internal class VerticalGroupTest : ModMenuTest
+{
+ internal override string Name => "Vertical Group";
+
+ internal override AbstractMenuScreen BuildMenuScreen()
+ {
+ VerticalGroup group = new();
+
+ TextButton resetButton = new("Reset");
+ void Reset()
+ {
+ foreach (var element in group.AllElements())
+ if (element != resetButton)
+ element.Dispose();
+ group.Clear();
+
+ ChoiceElement spacing = new(
+ "Spacing",
+ ChoiceModels.ForEnum()
+ );
+ spacing.OnValueChanged += value =>
+ group.VerticalSpacing = value switch
+ {
+ VerticalGroupSpacing.Small => SpacingConstants.VSPACE_SMALL,
+ VerticalGroupSpacing.Medium => SpacingConstants.VSPACE_MEDIUM,
+ VerticalGroupSpacing.Large => SpacingConstants.VSPACE_LARGE,
+ _ => throw new ArgumentException($"{value}"),
+ };
+ spacing.Value = VerticalGroupSpacing.Medium;
+ group.VerticalSpacing = SpacingConstants.VSPACE_MEDIUM;
+ group.Add(spacing);
+
+ TextButton insertBelow = new("Insert Below");
+ insertBelow.OnSubmit += () => group.Insert(2, new TextButton("New Button"));
+ group.Add(insertBelow);
+
+ TextButton removeThird = new("Remove Third Button");
+ removeThird.OnSubmit += () => group.RemoveAt(2);
+ group.Add(removeThird);
+
+ TextButton maybeVisible = new("Maybe Visible");
+ group.Add(maybeVisible);
+
+ ChoiceElement isAboveVisible = new("Is Above Visible?", ChoiceModels.ForBool());
+ isAboveVisible.OnValueChanged += value => maybeVisible.VisibleSelf = value;
+ isAboveVisible.Value = true;
+ group.Add(isAboveVisible);
+
+ ChoiceElement hideGaps = new("Hide Gaps", ChoiceModels.ForBool());
+ hideGaps.OnValueChanged += value => group.HideInactiveElements = value;
+ group.HideInactiveElements = false;
+ hideGaps.Value = false;
+ group.Add(hideGaps);
+
+ group.Add(resetButton);
+ }
+ resetButton.OnSubmit += Reset;
+ Reset();
+
+ return new BasicMenuScreen("Vertical Group Test", group);
+ }
+}
diff --git a/nuget.config b/nuget.config
new file mode 100644
index 0000000..ec22c2a
--- /dev/null
+++ b/nuget.config
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/thunderstore/thunderstore.toml b/thunderstore/thunderstore.toml
index 7b6bcb1..c29c6af 100644
--- a/thunderstore/thunderstore.toml
+++ b/thunderstore/thunderstore.toml
@@ -21,7 +21,7 @@ silksong_modding-UnityHelper = "1.0.1"
# by other build scripts
[build]
icon = "./icon.png"
-readme = "../README.md"
+readme = "../Silksong.ModMenu/README.md"
outdir = "./dist"
[[build.copy]]