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 .github/workflows/build-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Empty file modified .husky/pre-commit
100755 → 100644
Empty file.
56 changes: 31 additions & 25 deletions Silksong.ModMenu.sln
Original file line number Diff line number Diff line change
@@ -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
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,50 @@ namespace Silksong.ModMenu.Elements;
/// <summary>
/// Common functionality shared by most entity groups.
/// </summary>
public abstract class AbstractGroup : INavigableMenuEntity
public abstract class AbstractGroup : MenuDisposable, INavigableMenuEntity
{
private readonly VisibilityManager visibility = new(false);

/// <summary>
/// Construct an AbstractGroup.
/// </summary>
protected AbstractGroup()
{
OnDispose += () =>
{
foreach (var disposable in AllEntities().OfType<MenuDisposable>())
disposable.Dispose();
};
}

/// <inheritdoc/>
public VisibilityManager Visibility => visibility;

/// <summary>
/// Enumerate all child entities within this group.
/// </summary>
protected abstract IEnumerable<IMenuEntity> AllEntities();
public abstract IEnumerable<IMenuEntity> AllEntities();

/// <inheritdoc/>
public IEnumerable<MenuElement> AllElements() => AllEntities().SelectMany(e => e.AllElements());

/// <summary>
/// Whether this entity is directly contained within thie group.
/// </summary>
public abstract bool Contains(IMenuEntity entity);

/// <summary>
/// Register `entity` as a child of this group.
/// </summary>
protected void AddChild(IMenuEntity entity) => entity.SetParents(this, gameObjectParent);

/// <summary>
/// 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.
/// </summary>
public abstract void Clear();

/// <summary>
/// Enumerate all navigables which should be directly connected in `direction`.
/// </summary>
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ private static Text SetupRightDescription(Text descriptionText, Text choiceText)
return rightText;
}

/// <inheritdoc />
/// <inheritdoc/>
public override void SetFontSizes(FontSizes fontSizes)
{
base.SetFontSizes(fontSizes);
RightText.fontSize = fontSizes.DescriptionSize();
}

/// <inheritdoc />
/// <inheritdoc/>
public override void SetMainColor(Color color)
{
base.SetMainColor(color);
Expand Down
File renamed without changes.
File renamed without changes.
26 changes: 24 additions & 2 deletions Elements/FreeGroup.cs → Silksong.ModMenu/Elements/FreeGroup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
Expand All @@ -18,7 +17,21 @@ public class FreeGroup : AbstractGroup
private readonly LinkedDictionary<IMenuEntity, Vector2> entities = [];

/// <inheritdoc/>
protected override IEnumerable<IMenuEntity> AllEntities() => entities.Keys;
public override IEnumerable<IMenuEntity> AllEntities() => entities.Keys;

/// <summary>
/// The total number of entities in this group.
/// </summary>
public int Count => entities.Count;

/// <inheritdoc/>
public override bool Contains(IMenuEntity entity) => entities.ContainsKey(entity);

/// <summary>
/// Gets the positional offset of the given entity, if present.
/// </summary>
public bool TryGetOffset(IMenuEntity entity, out Vector2 offset) =>
entities.TryGetValue(entity, out offset);

/// <summary>
/// Add an entity to this free group at the specified position.
Expand Down Expand Up @@ -54,6 +67,15 @@ public bool Remove(IMenuEntity entity)
return false;
}

/// <inheritdoc/>
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
Expand Down
39 changes: 38 additions & 1 deletion Elements/GridGroup.cs → Silksong.ModMenu/Elements/GridGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,32 @@ public class GridGroup(int columns) : AbstractGroup
/// </summary>
public bool WrapHorizontal = false;

/// <inheritdoc/>
public override bool Contains(IMenuEntity entity) => index.ContainsKey(entity);

/// <summary>
/// Returns the row and column of the given entity.
/// </summary>
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;
}

/// <summary>
/// Returns the entity at the given row and column, if present.
/// </summary>
public bool TryGetEntity(int row, int column, [MaybeNullWhen(false)] out IMenuEntity entity) =>
TryGetValue(new(row, column), out entity);

/// <summary>
/// Add this entity to the next available empty cell in the grid.
/// </summary>
Expand Down Expand Up @@ -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);

/// <inheritdoc/>
public override void Clear()
{
foreach (var entity in index.Keys)
entity.ClearParents();

rows.Clear();
index.Clear();
nextEmptyCell = new(0, 0);
}

/// <inheritdoc/>
public override bool GetSelectable(
NavigationDirection direction,
Expand Down Expand Up @@ -236,7 +273,7 @@ static bool ClosestColumn(
}

/// <inheritdoc/>
protected override IEnumerable<IMenuEntity> AllEntities() =>
public override IEnumerable<IMenuEntity> AllEntities() =>
rows.SelectMany(row => row.WhereNonNull());

private ListView<ListView<IMenuEntity?>> GetColumns() =>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using Silksong.ModMenu.Internal;
using UnityEngine;
using UObject = UnityEngine.Object;

namespace Silksong.ModMenu.Elements;

Expand All @@ -18,6 +19,8 @@ public abstract class MenuElement : MenuDisposable, IMenuEntity
protected MenuElement(GameObject container)
{
Container = container;
OnDispose += () => UObject.Destroy(container);

RectTransform = container.GetComponent<RectTransform>();

visibility.OnVisibilityChanged += container.SetActive;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ public class VerticalGroup : AbstractGroup
public bool HideInactiveElements = true;

/// <inheritdoc/>
protected override IEnumerable<IMenuEntity> AllEntities() => entities;
public override IEnumerable<IMenuEntity> AllEntities() => entities;

/// <inheritdoc/>
public override bool Contains(IMenuEntity entity) => entities.Contains(entity);

/// <summary>
/// Add an entity to this vertical column group.
Expand Down Expand Up @@ -76,6 +79,15 @@ public void RemoveAt(int index)
entity.ClearParents();
}

/// <inheritdoc/>
public override void Clear()
{
foreach (var entity in entities)
entity.ClearParents();

entities.Clear();
}

/// <inheritdoc/>
public override bool GetSelectable(
NavigationDirection direction,
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal class LinkedDictionary<K, V> : IDictionary<K, V>
public V this[K key]
{
get => data[key].Item2;
set => data[key] = (data[key].Item1, value);
set => Set(key, value);
}

public ICollection<K> Keys => new LinkedDictionaryKeys(this);
Expand All @@ -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<K, V> 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<K, V> item) => Add(item.Key, item.Value);

public void Clear()
{
data.Clear();
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
-->
<Import Condition="Exists('SilksongPath.props')" Project="SilksongPath.props" />
<Import Condition="Exists('../SilksongPath.props')" Project="../SilksongPath.props" />
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>latest</LangVersion>
Expand Down Expand Up @@ -64,9 +64,8 @@
<Reference Include="@(LocalReferences)" Private="false" Publicize="true" />
</ItemGroup>
<ItemGroup>
<Folder Remove="thunderstore/tmp;thunderstore/dist" />
<None Include="README.md" Pack="True" PackagePath="README.md" />
<None Include="thunderstore/icon.png" Pack="True" PackagePath="icon.png" />
<None Include="../thunderstore/icon.png" Pack="True" PackagePath="icon.png" />
</ItemGroup>
<Target Name="CopyAndPackageMod" AfterTargets="PostBuildEvent">
<ItemGroup>
Expand All @@ -75,7 +74,7 @@
<Binaries Include="$(TargetDir)/$(TargetName).xml" />
</ItemGroup>
<PropertyGroup>
<ThunderstoreDir>$(ProjectDir)/thunderstore</ThunderstoreDir>
<ThunderstoreDir>$(SolutionDir)/thunderstore</ThunderstoreDir>
</PropertyGroup>
<Copy
SourceFiles="@(Binaries)"
Expand All @@ -102,7 +101,7 @@
Command="dotnet husky install"
StandardOutputImportance="Low"
StandardErrorImportance="High"
WorkingDirectory="."
WorkingDirectory="../."
/>
</Target>
</Project>
File renamed without changes.
16 changes: 16 additions & 0 deletions Silksong.ModMenuTesting/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project>
<PropertyGroup>
<!-- These properties will control the generated plugin info and Thunderstore manifest. -->
<!--
This is the name of your plugin as it would appear in-game and in a mod installer.
Allowed characters are A-Z, a-z, 0-9 and _
-->
<AssemblyTitle>ModMenuTesting</AssemblyTitle>
<!--
This is the version of your plugin as it would appear in-game and in a mod installer.
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.1.0</Version>
</PropertyGroup>
</Project>
10 changes: 10 additions & 0 deletions Silksong.ModMenuTesting/ModMenuTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Silksong.ModMenu.Screens;

namespace Silksong.ModMenuTesting;

internal abstract class ModMenuTest
{
internal abstract string Name { get; }

internal abstract AbstractMenuScreen BuildMenuScreen();
}
Loading