Skip to content

Commit

Permalink
added a simple configuration menu
Browse files Browse the repository at this point in the history
  • Loading branch information
m1el committed Jan 31, 2021
1 parent e571b14 commit c1f1791
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 16 deletions.
1 change: 1 addition & 0 deletions Configuration/PluginConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace SliceVisualizer.Configuration
{
internal class PluginConfig
{
internal static PluginConfig Instance = null!;
public virtual bool Enabled { get; set; } = true;
public virtual float SliceWidth { get; set; } = 0.05f;

Expand Down
51 changes: 47 additions & 4 deletions Core/NsvController.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
using System;
using SliceVisualizer.Configuration;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zenject;
using HMUI;
using BeatSaberMarkupLanguage.Tags;
using BeatSaberMarkupLanguage.Components.Settings;
using SiraUtil.Tools;

namespace SliceVisualizer.Core
{
internal class NsvController : IInitializable, ITickable, IDisposable
{
private readonly PluginConfig _config;
private readonly SiraLog _logger;
private readonly BeatmapObjectManager _beatmapObjectManager;
private readonly NsvSlicedBlock[] _slicedBlockPool;
private readonly Factories.NsvBlockFactory _blockFactory;
Expand All @@ -17,9 +23,10 @@ internal class NsvController : IInitializable, ITickable, IDisposable

private static readonly int MaxItems = 12;

public NsvController(PluginConfig config, BeatmapObjectManager beatmapObjectManager, Factories.NsvBlockFactory blockFactory)
public NsvController(BeatmapObjectManager beatmapObjectManager, Factories.NsvBlockFactory blockFactory, SiraLog logger)
{
_config = config;
_config = PluginConfig.Instance;
_logger = logger;
_beatmapObjectManager = beatmapObjectManager;
_slicedBlockPool = new NsvSlicedBlock[MaxItems];
_blockFactory = blockFactory;
Expand All @@ -30,16 +37,23 @@ public void Initialize()
_canvasGO = new GameObject("SliceVisualizerCanvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
var canvas = _canvasGO.GetComponent<Canvas>();
canvas.renderMode = RenderMode.WorldSpace;

_canvasGO.transform.localScale = Vector3.one * _config.CanvasScale;
_canvasGO.transform.localPosition = _config.CanvasOffset;
_beatmapObjectManager.noteWasCutEvent += OnNoteCut;

for (var i = 0; i < MaxItems; i++)
{
_slicedBlockPool[i] = _blockFactory.Create();
_slicedBlockPool[i].Init(_canvasGO.transform);
}

try
{
CreateCheckbox();
}
catch (Exception err)
{
_logger.Info(string.Format("Cannot create checkbox: {0}", err));
}
}

public void Tick()
Expand All @@ -66,6 +80,11 @@ public void Dispose()

private void OnNoteCut(NoteController noteController, NoteCutInfo noteCutInfo)
{
if (!_config.Enabled)
{
return;
}

// Re-use cubes at the same column & layer to avoid UI cluttering
var noteData = noteController.noteData;
// doing the modulus twice is required for negative indices
Expand All @@ -75,5 +94,29 @@ private void OnNoteCut(NoteController noteController, NoteCutInfo noteCutInfo)
var slicedBlock = _slicedBlockPool[blockIndex];
slicedBlock.SetData(noteController, noteCutInfo, noteData);
}

public void CreateCheckbox()
{
var canvas = GameObject.Find("Wrapper/StandardGameplay/PauseMenu/Wrapper/MenuWrapper/Canvas").GetComponent<Canvas>();
if (!canvas)
{
return;
}

var toggleObject = new ToggleSettingTag().CreateObject(canvas.transform);
toggleObject.GetComponentInChildren<CurvedTextMeshPro>().text = "SliceVisualizer";

if (!(toggleObject.transform is RectTransform toggleObjectTransform))
{
return;
}

toggleObjectTransform.anchoredPosition = new Vector2(27, -7);
toggleObjectTransform.sizeDelta = new Vector2(-130, 7);

var toggleSetting = toggleObject.GetComponent<ToggleSetting>();
toggleSetting.Value = _config.Enabled;
toggleSetting.toggle.onValueChanged.AddListener(enabled => _config.Enabled = enabled);
}
}
}
4 changes: 2 additions & 2 deletions Core/NsvSlicedBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ internal class NsvSlicedBlock : MonoBehaviour, IDisposable
private bool _needsUpdate;

[Inject]
internal void Construct(PluginConfig config, NsvAssetLoader assetLoader, ColorManager colorManager)
internal void Construct(NsvAssetLoader assetLoader, ColorManager colorManager)
{
_colorManager = colorManager;
_config = config;
_config = PluginConfig.Instance;

BuildNote(assetLoader);
}
Expand Down
3 changes: 3 additions & 0 deletions Installers/NsvAppInstaller.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using IPA.Logging;
using SiraUtil;
using SliceVisualizer.Configuration;
using SliceVisualizer.UI;
using Zenject;

namespace SliceVisualizer.Installers
Expand All @@ -14,6 +15,8 @@ public NsvAppInstaller(Logger logger, PluginConfig config)
{
_logger = logger;
_config = config;
PluginConfig.Instance = config;
SettingsUI.CreateMenu();
}

public override void InstallBindings()
Expand Down
10 changes: 1 addition & 9 deletions Installers/NsvGameInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,12 @@ namespace SliceVisualizer.Installers
{
internal class NsvGameInstaller : Installer<NsvGameInstaller>
{
private readonly PluginConfig _pluginConfig;

public NsvGameInstaller(PluginConfig pluginConfig)
public NsvGameInstaller()
{
_pluginConfig = pluginConfig;
}

public override void InstallBindings()
{
if (!_pluginConfig.Enabled)
{
return;
}

Container.BindFactory<NsvSlicedBlock, NsvBlockFactory>().AsSingle();
Container.BindInterfacesAndSelfTo<NsvController>().AsSingle();
}
Expand Down
2 changes: 2 additions & 0 deletions Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace SliceVisualizer
[Plugin(RuntimeOptions.DynamicInit)]
public class Plugin
{
internal static Logger Log = null!;
/// <summary>
/// Called when the plugin is first loaded by IPA (either when the game starts or when the plugin is enabled if it starts disabled).
/// [Init] methods that use a Constructor or called before regular methods like InitWithConfig.
Expand All @@ -20,6 +21,7 @@ public class Plugin
[Init]
public void Init(Logger logger, Config conf, Zenjector zenject)
{
Log = logger;
zenject.OnApp<NsvAppInstaller>().WithParameters(logger, conf.Generated<PluginConfig>());
zenject.OnGame<NsvGameInstaller>(false).ShortCircuitForTutorial();
}
Expand Down
13 changes: 13 additions & 0 deletions SliceVisualizer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@
</PropertyGroup>

<ItemGroup>
<Reference Include="BSML">
<HintPath>$(BeatSaberDir)\Plugins\BSML.dll</HintPath>
</Reference>
<Reference Include="HMLib">
<HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\HMLib.dll</HintPath>
</Reference>
<Reference Include="HMUI">
<HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\HMUI.dll</HintPath>
</Reference>
<Reference Include="Unity.TextMeshPro">
<HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\Unity.TextMeshPro.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
Expand Down Expand Up @@ -89,6 +101,7 @@

<ItemGroup>
<EmbeddedResource Include="Assets\*.png" />
<EmbeddedResource Include="Views\*.bsml" />
<EmbeddedResource Include="manifest.json" />
</ItemGroup>
<ItemGroup>
Expand Down
30 changes: 30 additions & 0 deletions UI/SettingsUI.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using BeatSaberMarkupLanguage;
using BeatSaberMarkupLanguage.MenuButtons;

namespace SliceVisualizer.UI
{
internal class SettingsUI
{
public static SliceVisualizerFlowCoordinator? SliceVisualizerFlowCoordinator;
public static bool Created;

public static void CreateMenu()
{
if (!Created)
{
var menuButton = new MenuButton("SliceVisualizer", "Chase the perfect slice", ShowFlow);
MenuButtons.instance.RegisterButton(menuButton);
Created = true;
}
}

public static void ShowFlow()
{
if (SliceVisualizerFlowCoordinator == null)
{
SliceVisualizerFlowCoordinator = BeatSaberUI.CreateFlowCoordinator<SliceVisualizerFlowCoordinator>();
}
BeatSaberUI.MainFlowCoordinator.PresentFlowCoordinator(SliceVisualizerFlowCoordinator);
}
}
}
46 changes: 46 additions & 0 deletions UI/SliceVisualizerFlowCoordinator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using BeatSaberMarkupLanguage;
using HMUI;
using SliceVisualizer.ViewControllers;

namespace SliceVisualizer.UI
{
internal class SliceVisualizerFlowCoordinator : FlowCoordinator
{
private MainViewController? _mainViewController;
// private BindingsViewController _bindingsViewController;
// private MiscViewController _miscViewController;
// private ThresholdViewController _thresholdViewController;

public void Awake()
{
if (!_mainViewController)
{
_mainViewController = BeatSaberUI.CreateViewController<MainViewController>();
}
}

protected override void DidActivate(bool firstActivation, bool addedToHierarchy, bool screenSystemEnabling)
{
try
{
if (firstActivation)
{
SetTitle("SliceVisualizer settings");
showBackButton = true;
ProvideInitialViewControllers(_mainViewController);
}
_mainViewController?.Activated();
}
catch (Exception e)
{
Plugin.Log.Error(e);
}
}

protected override void BackButtonWasPressed(ViewController topViewController)
{
BeatSaberUI.MainFlowCoordinator.DismissFlowCoordinator(this);
}
}
}
25 changes: 25 additions & 0 deletions ViewControllers/MainViewController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using BeatSaberMarkupLanguage.Attributes;
using BeatSaberMarkupLanguage.ViewControllers;
using SliceVisualizer.Configuration;

namespace SliceVisualizer.ViewControllers
{
internal class MainViewController : BSMLResourceViewController
{
public void Activated()
{
NotifyPropertyChanged("EnabledValue");
}
[UIValue("Enabled-value")]
public bool EnabledValue
{
get => PluginConfig.Instance.Enabled;
set
{
PluginConfig.Instance.Enabled = value;
}
}

public override string ResourceName => "SliceVisualizer.Views.Main.bsml";
}
}
10 changes: 10 additions & 0 deletions Views/Main.bsml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vertical child-control-height='false'>
<horizontal horizontal-fit='PreferredSize' spacing='10'>
<checkbox-setting
preferred-width='60'
text='Enabled'
value='Enabled-value'
apply-on-change='true'
hover-hint='Enable SliceVisualizer' />
</horizontal>
</vertical>
3 changes: 2 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
"id": "SliceVisualizer",
"name": "SliceVisualizer",
"author": "Igor null <[email protected]>",
"version": "0.0.7",
"version": "0.1.0",
"description": "Shows your cut data to train your accuracy",
"gameVersion": "1.13.2",
"dependsOn": {
"BeatSaberMarkupLanguage": "^1.4.5",
"BSIPA": "^4.1.4",
"SiraUtil": "^2.4.0"
}
Expand Down

0 comments on commit c1f1791

Please sign in to comment.