From 30bec7ce8b774086a591be1bc7cc14d45ded38e9 Mon Sep 17 00:00:00 2001 From: DDAkebono Date: Sat, 28 May 2022 23:06:07 -0500 Subject: [PATCH 1/2] Added notification alignment anchor selection, added notification alpha control. Added colour parameter to EnqueueNotification. --- Notification/NotificationController.cs | 4 + Notification/NotificationObject.cs | 4 +- Notification/NotificationSystem.cs | 115 ++++++++++++++++++++++++- ReMod.Core.csproj | 3 + 4 files changed, 124 insertions(+), 2 deletions(-) diff --git a/Notification/NotificationController.cs b/Notification/NotificationController.cs index be63513..547261d 100644 --- a/Notification/NotificationController.cs +++ b/Notification/NotificationController.cs @@ -19,6 +19,7 @@ public class NotificationController : MonoBehaviour //Objects private Animator _notificationAnimator; private Image _iconImage; + private Image _backgroundImage; private TextMeshProUGUI _titleText; private TextMeshProUGUI _descriptionText; @@ -68,6 +69,7 @@ public static void RegisterSafe() private void Start() { _notificationAnimator = gameObject.GetComponent(); + _backgroundImage = gameObject.transform.Find("Content/Background").GetComponent(); _iconImage = gameObject.transform.Find("Content/Icon").gameObject.GetComponent(); _titleText = gameObject.transform.Find("Content/Title").gameObject.GetComponent(); _descriptionText = gameObject.transform.Find("Content/Description").gameObject.GetComponent(); @@ -96,6 +98,8 @@ private void Update() _descriptionText.text = _currentNotification.Description; _iconImage.sprite = _currentNotification.Icon == null ? defaultSprite : _currentNotification.Icon; _iconImage.enabled = true; + _currentNotification.BackgroundColor.a = NotificationSystem.NotificationAlpha.Value; + _backgroundImage.color = _currentNotification.BackgroundColor; OpenNotification(); } diff --git a/Notification/NotificationObject.cs b/Notification/NotificationObject.cs index b21efd8..8303188 100644 --- a/Notification/NotificationObject.cs +++ b/Notification/NotificationObject.cs @@ -8,13 +8,15 @@ public class NotificationObject public string Description; public Sprite Icon; public float DisplayLength; + public Color BackgroundColor; - public NotificationObject(string title, string description, Sprite icon, float displayLength) + public NotificationObject(string title, string description, Sprite icon, float displayLength, Color backgroundColor) { Title = title; Description = description; Icon = icon; DisplayLength = displayLength; + BackgroundColor = backgroundColor; } } } \ No newline at end of file diff --git a/Notification/NotificationSystem.cs b/Notification/NotificationSystem.cs index f786fca..e927d00 100644 --- a/Notification/NotificationSystem.cs +++ b/Notification/NotificationSystem.cs @@ -1,8 +1,11 @@ using System; +using System.Collections.Generic; using System.IO; using System.Reflection; +using MelonLoader; using UnhollowerRuntimeLib; using UnityEngine; +using Logger = VRC.Core.Logger; using Object = UnityEngine.Object; namespace ReMod.Core.Notification @@ -10,6 +13,9 @@ namespace ReMod.Core.Notification public class NotificationSystem { public static Sprite DefaultIcon; + public static Color DefaultColour = new Color(0.1764f, 0.2549f, .3333f, 1f); + public static MelonPreferences_Entry NotificationAlpha; + public static MelonPreferences_Entry NotificationAlignment; public static bool UseVRChatNotificationSystem; //AssetBundle Parts @@ -18,6 +24,7 @@ public class NotificationSystem private static GameObject _hudContent; private static GameObject _notificationGO; + private static RectTransform _notificationRect; private static NotificationController _controllerInstance; public static void SetupNotifications() @@ -36,12 +43,24 @@ public static void SetupNotifications() NotificationController.RegisterSafe(); + MelonPreferences.CreateCategory("ReModCore", "ReMod.Core"); + NotificationAlpha = MelonPreferences.CreateEntry("ReModCore", "NotificationAlpha", .7f, "Notification Alpha", "Controls transparency of the notification system."); + NotificationAlignment = MelonPreferences.CreateEntry("ReModCore", "NotificationAlignment", "centerMiddle", "Notification Alignment"); + + NotificationAlignment.OnValueChanged += UpdateNotificationAlignment; + + //Create UIX settings enum + RegSettingsEnum("ReModCore", "NotificationAlignment", new[] {("centerMiddle", "Middle Centered"), ("topCenter", "Top Centered"), ("topLeft", "Top Left"), ("topRight", "Top Right"), ("bottomCenter", "Bottom Centered"), ("bottomLeft", "Bottom Left"), ("bottomRight", "Bottom Right")}); + if (_notificationPrefab == null) throw new Exception("NotificationSystem failed to load, prefab missing!"); //Instantiate prefab and let NotificationController setup! _notificationGO = Object.Instantiate(_notificationPrefab, _hudContent.transform); _controllerInstance = _notificationGO.AddComponent(); + //Get the RectTransform for us to set the alignment + _notificationRect = _notificationGO.GetComponent(); + UpdateNotificationAlignment(null, null); _controllerInstance.defaultSprite = DefaultIcon; } @@ -55,7 +74,20 @@ public static void SetupNotifications() /// Optional icon sprite, defaults to Megaphone public static void EnqueueNotification(string title, string description, float displayLength = 5f, Sprite icon = null) { - var notif = new NotificationObject(title, description, icon, displayLength); + EnqueueNotification(title, description, DefaultColour, displayLength, icon); + } + + /// + /// Enqueue a new notification + /// + /// Title shown in the top of the notification + /// Main description, scales based on size + /// Background colour of the notification + /// How long in seconds you want it shown + /// Optional icon sprite, defaults to Megaphone + public static void EnqueueNotification(string title, string description, Color backgroundColour, float displayLength = 5f, Sprite icon = null) + { + var notif = new NotificationObject(title, description, icon, displayLength, backgroundColour); if(_controllerInstance == null) SetupNotifications(); @@ -71,6 +103,50 @@ public static void ClearNotification() _controllerInstance.ClearNotifications(); } + private static void UpdateNotificationAlignment(string sender, string args) + { + if (_notificationRect == null) return; + + switch (NotificationAlignment.Value) + { + case "centerMiddle": + _notificationRect.anchorMin = new Vector2(0.5f, 0.5f); + _notificationRect.anchorMax = new Vector2(0.5f, 0.5f); + _notificationRect.pivot = new Vector2(0.5f, 0.5f); + break; + case "topCenter": + _notificationRect.anchorMin = new Vector2(0.5f, 1f); + _notificationRect.anchorMax = new Vector2(0.5f, 1f); + _notificationRect.pivot = new Vector2(0.5f, 1f); + break; + case "topLeft": + _notificationRect.anchorMin = new Vector2(0f, 1f); + _notificationRect.anchorMax = new Vector2(0f, 1f); + _notificationRect.pivot = new Vector2(0f, 1f); + break; + case "topRight": + _notificationRect.anchorMin = new Vector2(1f, 1f); + _notificationRect.anchorMax = new Vector2(1f, 1f); + _notificationRect.pivot = new Vector2(1f, 1f); + break; + case "bottomCenter": + _notificationRect.anchorMin = new Vector2(0.5f, 0f); + _notificationRect.anchorMax = new Vector2(0.5f, 0f); + _notificationRect.pivot = new Vector2(0.5f, 0f); + break; + case "bottomLeft": + _notificationRect.anchorMin = new Vector2(0f, 0f); + _notificationRect.anchorMax = new Vector2(0f, 0f); + _notificationRect.pivot = new Vector2(0f, 0f); + break; + case "bottomRight": + _notificationRect.anchorMin = new Vector2(1f, 0f); + _notificationRect.anchorMax = new Vector2(1f, 0f); + _notificationRect.pivot = new Vector2(1f, 0f); + break; + } + } + private static void LoadAssets() { using (var assetStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ReMod.Core.Notification.notification")) @@ -96,5 +172,42 @@ private static void LoadAssets() _notificationPrefab.hideFlags |= HideFlags.DontUnloadUnusedAsset; } } + + #region UIXAdapter + + private static bool? _uixAvailable; + private static MethodInfo _regSettingEnum; + private static bool _methodsGetRan; + + public static bool IsUIXAvailable() + { + _uixAvailable ??= MelonHandler.IsModAlreadyLoaded("UI Expansion Kit"); + return _uixAvailable.Value; + } + + public static bool GetUIXMethods() + { + if (_methodsGetRan) return true; + + Type expandedMenu = Type.GetType("UIExpansionKit.API.ExpansionKitApi, UIExpansionKit"); + + if (expandedMenu == null) return false; + + _regSettingEnum = expandedMenu.GetMethod("RegisterSettingAsStringEnum", BindingFlags.Public | BindingFlags.Static); + + return true; + } + + public static bool RegSettingsEnum(string settingsCat, string settingsName, IList<(string value, string desc)> values) + { + if (!IsUIXAvailable()) return false; + if (!GetUIXMethods()) return false; + + _regSettingEnum.Invoke(null, new object[] { settingsCat, settingsName, values }); + + return true; + } + + #endregion } } \ No newline at end of file diff --git a/ReMod.Core.csproj b/ReMod.Core.csproj index 50e333c..ee6e21c 100644 --- a/ReMod.Core.csproj +++ b/ReMod.Core.csproj @@ -95,6 +95,9 @@ $(MlPath)\Managed\UnityEngine.UI.dll False + + $(MlPath)\Managed\UnityEngine.UIModule.dll + $(MlPath)\Managed\VRC.UI.Core.dll False From 3ca5b5a0c2daa119ec6c5e834dacb23f9b324cf9 Mon Sep 17 00:00:00 2001 From: DDAkebono Date: Sat, 28 May 2022 23:07:52 -0500 Subject: [PATCH 2/2] Made UIXAdapter sets _methodsGetRan to true after getting methods, oops. --- Notification/NotificationSystem.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Notification/NotificationSystem.cs b/Notification/NotificationSystem.cs index e927d00..c0b626d 100644 --- a/Notification/NotificationSystem.cs +++ b/Notification/NotificationSystem.cs @@ -178,14 +178,14 @@ private static void LoadAssets() private static bool? _uixAvailable; private static MethodInfo _regSettingEnum; private static bool _methodsGetRan; - - public static bool IsUIXAvailable() + + private static bool IsUIXAvailable() { _uixAvailable ??= MelonHandler.IsModAlreadyLoaded("UI Expansion Kit"); return _uixAvailable.Value; } - - public static bool GetUIXMethods() + + private static bool GetUIXMethods() { if (_methodsGetRan) return true; @@ -194,11 +194,13 @@ public static bool GetUIXMethods() if (expandedMenu == null) return false; _regSettingEnum = expandedMenu.GetMethod("RegisterSettingAsStringEnum", BindingFlags.Public | BindingFlags.Static); + + _methodsGetRan = true; return true; } - - public static bool RegSettingsEnum(string settingsCat, string settingsName, IList<(string value, string desc)> values) + + private static bool RegSettingsEnum(string settingsCat, string settingsName, IList<(string value, string desc)> values) { if (!IsUIXAvailable()) return false; if (!GetUIXMethods()) return false;