diff --git a/BSIPA-ModList/BSIPA-ModList.csproj b/BSIPA-ModList/BSIPA-ModList.csproj
index c5185fea..c0c14007 100644
--- a/BSIPA-ModList/BSIPA-ModList.csproj
+++ b/BSIPA-ModList/BSIPA-ModList.csproj
@@ -47,6 +47,9 @@
+
+ ..\Refs\UnityEngine.dll
+
..\Refs\UnityEngine.CoreModule.dll
False
@@ -63,6 +66,7 @@
+
diff --git a/BSIPA-ModList/Plugin.cs b/BSIPA-ModList/Plugin.cs
index 5de5c496..bd99ff60 100644
--- a/BSIPA-ModList/Plugin.cs
+++ b/BSIPA-ModList/Plugin.cs
@@ -31,13 +31,8 @@ namespace BSIPA_ModList
{
}
- private MainFlowCoordinator mainFlow;
- private ModListFlowCoordinator menuFlow;
- private MenuButton button;
-
public void OnApplicationStart()
{
- Logger.log.Debug("Creating Menu");
}
public void OnFixedUpdate()
@@ -48,16 +43,11 @@ namespace BSIPA_ModList
{
if (scene.name == "MenuCore")
{
- if (mainFlow == null)
- mainFlow = Resources.FindObjectsOfTypeAll().First();
- if (menuFlow == null)
- menuFlow = new GameObject("BSIPA Mod List Flow Coordinator").AddComponent();
- if (button == null)
- button = MenuButtonUI.AddButton("Mod List", "Look at installed mods, and control updating", () =>
- {
- Logger.log.Debug("Presenting own flow controller");
- menuFlow.PresentOn(mainFlow);
- });
+ if (ButtonUI.Instance == null)
+ {
+ Logger.log.Debug("Creating Menu");
+ new GameObject("BSIPA Mod List Object").AddComponent().Init();
+ }
}
}
diff --git a/BSIPA-ModList/UI/ButtonUI.cs b/BSIPA-ModList/UI/ButtonUI.cs
new file mode 100644
index 00000000..e44803ce
--- /dev/null
+++ b/BSIPA-ModList/UI/ButtonUI.cs
@@ -0,0 +1,91 @@
+using CustomUI.BeatSaber;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+using UnityEngine.UI;
+
+namespace BSIPA_ModList.UI
+{
+ internal class ButtonUI : MonoBehaviour
+ {
+ private const string ControllerPanel = "MainMenuViewController/SmallButtons";
+ private const string CopyButton = "CreditsButton";
+
+ internal static ButtonUI Instance;
+
+ public void Awake()
+ {
+ DontDestroyOnLoad(gameObject);
+ SceneManager.activeSceneChanged += this.SceneManager_activeSceneChanged;
+ }
+
+ private void SceneManager_activeSceneChanged(Scene from, Scene to)
+ {
+ if (to.name == "EmptyTransition")
+ {
+ if (Instance != null)
+ {
+ Instance.StopAllCoroutines();
+ Destroy(Instance.gameObject);
+ menuFlow = null;
+ }
+ Instance = null;
+ }
+ }
+
+ public void Init()
+ {
+ Instance = this;
+
+ Logger.log.Debug("UI Awake");
+ StartCoroutine(AddModListButton());
+ }
+
+ private static MainFlowCoordinator mainFlow;
+ private static ModListFlowCoordinator menuFlow;
+
+ private static readonly WaitUntil _bottomPanelExists = new WaitUntil(() => GameObject.Find(ControllerPanel) != null);
+ private static RectTransform panel;
+
+ private static HoverHint hintText;
+ private static Button button;
+
+ private static IEnumerator AddModListButton()
+ {
+ Logger.log.Debug("AddModListButton");
+
+ yield return _bottomPanelExists;
+
+ Logger.log.Debug("Adding button to main menu");
+
+ lock (Instance)
+ {
+ if (mainFlow == null)
+ mainFlow = Resources.FindObjectsOfTypeAll().First();
+ if (menuFlow == null)
+ menuFlow = new GameObject("BSIPA Mod List Flow Controller").AddComponent();
+ if (panel == null)
+ panel = GameObject.Find(ControllerPanel).transform as RectTransform;
+
+ if (button == null)
+ {
+ button = BeatSaberUI.CreateUIButton(panel, CopyButton, () =>
+ {
+ Logger.log.Debug("Presenting own flow controller");
+ menuFlow.PresentOn(mainFlow);
+ }, "Mod List");
+ panel.Find(CopyButton).SetAsLastSibling();
+
+ hintText = BeatSaberUI.AddHintText(button.transform as RectTransform, "View and control updates for installed mods");
+ }
+
+ yield break;
+ }
+ }
+ }
+}
diff --git a/BSIPA-ModList/UI/ModListFlowCoordinator.cs b/BSIPA-ModList/UI/ModListFlowCoordinator.cs
index f339bdfd..ab09b76d 100644
--- a/BSIPA-ModList/UI/ModListFlowCoordinator.cs
+++ b/BSIPA-ModList/UI/ModListFlowCoordinator.cs
@@ -25,7 +25,7 @@ namespace BSIPA_ModList.UI
navigationController.didFinishEvent += backButton_DidFinish;
modList = BeatSaberUI.CreateViewController();
- modList.Init(navigationController, PluginManager.AllPlugins, PluginLoader.ignoredPlugins, PluginManager.Plugins);
+ modList.Init(this, PluginManager.AllPlugins, PluginLoader.ignoredPlugins, PluginManager.Plugins);
PushViewControllerToNavigationController(navigationController, modList);
}
@@ -49,10 +49,54 @@ namespace BSIPA_ModList.UI
presentFlow(main, this, finished, immediate, replaceTop);
}
+ public bool HasSelected { get; private set; } = false;
+
+ public void SetSelected(VRUIViewController selected, Action callback = null, bool immediate = false)
+ {
+ if (immediate)
+ {
+ if (HasSelected)
+ PopViewController(immediate: true);
+ PushViewController(selected, callback, true);
+ }
+ else
+ {
+ if (HasSelected)
+ PopViewController(() => PushViewController(selected, callback, immediate), immediate);
+ else
+ PushViewController(selected, callback, immediate);
+ }
+ }
+
+ public void ClearSelected(Action callback = null, bool immediate = false)
+ {
+ if (HasSelected) PopViewController(callback, immediate);
+ }
+
+ public void PushViewController(VRUIViewController controller, Action callback = null, bool immediate = false)
+ {
+ PushViewControllerToNavigationController(navigationController, controller, callback, immediate);
+ }
+
+ public void PopViewController(Action callback = null, bool immediate = false)
+ {
+ PopViewControllerFromNavigationController(navigationController, callback, immediate);
+ }
+
+ private delegate void DismissFlowDel(FlowCoordinator self, FlowCoordinator newF, Action finished, bool immediate);
+ private static DismissFlowDel dismissFlow;
+
private void backButton_DidFinish()
{
+ if (dismissFlow == null)
+ {
+ var ty = typeof(FlowCoordinator);
+ var m = ty.GetMethod("DismissFlowCoordinator", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ dismissFlow = (DismissFlowDel)Delegate.CreateDelegate(typeof(DismissFlowDel), m);
+ }
+
MainFlowCoordinator mainFlow = Resources.FindObjectsOfTypeAll().First();
- mainFlow.InvokeMethod("DismissFlowCoordinator", this, null, false);
+ dismissFlow(mainFlow, this, null, false);
}
}
}
diff --git a/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs b/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs
index 60cde929..2479627c 100644
--- a/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs
+++ b/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs
@@ -4,11 +4,28 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using UnityEngine;
+using VRUI;
namespace BSIPA_ModList.UI
{
- internal class ModInfoViewController : CustomViewController
+ internal class ModInfoViewController : VRUIViewController
{
+ private Sprite Icon;
+ private string Name;
+ private string Version;
+ private string Author;
+ private string Description;
+ private bool CanUpdate;
+ public void Init(Sprite icon, string name, string version, string author, string description, bool canUpdate)
+ {
+ Icon = icon;
+ Name = name;
+ Version = version;
+ Author = author;
+ Description = description;
+ CanUpdate = canUpdate;
+ }
}
}
diff --git a/BSIPA-ModList/UI/ViewControllers/ModListController.cs b/BSIPA-ModList/UI/ViewControllers/ModListController.cs
index f80a887a..801851bf 100644
--- a/BSIPA-ModList/UI/ViewControllers/ModListController.cs
+++ b/BSIPA-ModList/UI/ViewControllers/ModListController.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using System.Collections.Generic;
using CustomUI.BeatSaber;
using CustomUI.Utilities;
@@ -7,6 +8,7 @@ using IPA.Loader;
using IPA.Old;
using UnityEngine;
using VRUI;
+using IPA.Loader.Features;
namespace BSIPA_ModList.UI
{
@@ -31,11 +33,13 @@ namespace BSIPA_ModList.UI
}
internal PluginLoader.PluginInfo Plugin;
+ private ModListController list;
- public BSIPAModCell(PluginLoader.PluginInfo plugin)
+ public BSIPAModCell(ModListController list, PluginLoader.PluginInfo plugin)
: base($"{plugin.Metadata.Name} v{plugin.Metadata.Version}", plugin.Metadata.Manifest.Author, null)
{
Plugin = plugin;
+ this.list = list;
if (plugin.Metadata.Manifest.IconPath != null)
icon = UIUtilities.LoadSpriteRaw(UIUtilities.GetResource(plugin.Metadata.Assembly, plugin.Metadata.Manifest.IconPath));
@@ -45,20 +49,33 @@ namespace BSIPA_ModList.UI
Logger.log.Debug($"BSIPAModCell {plugin.Metadata.Name} {plugin.Metadata.Version}");
}
+ private ModInfoViewController infoView;
+
public void OnSelect(ModListController cntrl)
{
Logger.log.Debug($"Selected BSIPAModCell {Plugin.Metadata.Name} {Plugin.Metadata.Version}");
+
+ if (infoView == null)
+ {
+ infoView = BeatSaberUI.CreateViewController();
+ infoView.Init(icon, Plugin.Metadata.Name, Plugin.Metadata.Version.ToString(), Plugin.Metadata.Manifest.Author,
+ Plugin.Metadata.Manifest.Description, Plugin.Metadata.Features.FirstOrDefault(f => f is NoUpdateFeature) == null);
+ }
+
+ list.flow.SetSelected(infoView);
}
}
private class BSIPAIgnoredModCell : CustomCellInfo, IClickableCell
{
internal PluginLoader.PluginMetadata Plugin;
+ private ModListController list;
- public BSIPAIgnoredModCell(PluginLoader.PluginMetadata plugin)
+ public BSIPAIgnoredModCell(ModListController list, PluginLoader.PluginMetadata plugin)
: base($"{plugin.Name} v{plugin.Version}", $"{plugin.Manifest.Author} - Not loaded", BSIPAModCell.DefaultIcon)
{
Plugin = plugin;
+ this.list = list;
Logger.log.Debug($"BSIPAIgnoredModCell {plugin.Name} {plugin.Version}");
}
@@ -66,6 +83,7 @@ namespace BSIPA_ModList.UI
public void OnSelect(ModListController cntrl)
{
Logger.log.Debug($"Selected BSIPAIgnoredModCell {Plugin.Name} {Plugin.Version}");
+
}
}
@@ -84,11 +102,13 @@ namespace BSIPA_ModList.UI
}
internal IPlugin Plugin;
+ private ModListController list;
- public IPAModCell(IPlugin plugin)
+ public IPAModCell(ModListController list, IPlugin plugin)
: base($"{plugin.Name} {plugin.Version}", "Legacy", DefaultIcon)
{
Plugin = plugin;
+ this.list = list;
Logger.log.Debug($"IPAModCell {plugin.Name} {plugin.Version}");
}
@@ -100,10 +120,10 @@ namespace BSIPA_ModList.UI
}
#pragma warning restore
- private BackButtonNavigationController navigation;
+ private ModListFlowCoordinator flow;
#pragma warning disable CS0618
- public void Init(BackButtonNavigationController navigation, IEnumerable bsipaPlugins, IEnumerable ignoredPlugins, IEnumerable ipaPlugins)
+ public void Init(ModListFlowCoordinator flow, IEnumerable bsipaPlugins, IEnumerable ignoredPlugins, IEnumerable ipaPlugins)
{
Logger.log.Debug("List Controller Init");
@@ -111,16 +131,16 @@ namespace BSIPA_ModList.UI
DidSelectRowEvent = DidSelectRow;
includePageButtons = true;
- this.navigation = navigation;
+ this.flow = flow;
reuseIdentifier = "BSIPAModListTableCell";
foreach (var plugin in bsipaPlugins)
- Data.Add(new BSIPAModCell(plugin));
+ Data.Add(new BSIPAModCell(this, plugin));
foreach (var plugin in ignoredPlugins)
- Data.Add(new BSIPAIgnoredModCell(plugin));
+ Data.Add(new BSIPAIgnoredModCell(this, plugin));
foreach (var plugin in ipaPlugins)
- Data.Add(new IPAModCell(plugin));
+ Data.Add(new IPAModCell(this, plugin));
}
#pragma warning restore
diff --git a/Refs/BeatSaberCustomUI.dll b/Refs/BeatSaberCustomUI.dll
index 8f810ea4..297e4173 100644
Binary files a/Refs/BeatSaberCustomUI.dll and b/Refs/BeatSaberCustomUI.dll differ
diff --git a/Refs/UnityEngine.dll b/Refs/UnityEngine.dll
new file mode 100644
index 00000000..605ef4d4
Binary files /dev/null and b/Refs/UnityEngine.dll differ
diff --git a/Refs/UnityEngine.xml b/Refs/UnityEngine.xml
new file mode 100644
index 00000000..a4658120
--- /dev/null
+++ b/Refs/UnityEngine.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ UnityEngine
+
+
+
diff --git a/Refs/refs.txt b/Refs/refs.txt
index 3818beda..9554dac9 100644
--- a/Refs/refs.txt
+++ b/Refs/refs.txt
@@ -3,6 +3,8 @@
""Managed/
"""Assembly-CSharp.dll
"""UnityEngine.
+""""dll
+""""xml
""""UnityWebRequestModule.
"""""dll
"""""xml