diff --git a/Patches/HideoutSearchPatches.cs b/Patches/HideoutSearchPatches.cs index aba3494..c05bdf9 100644 --- a/Patches/HideoutSearchPatches.cs +++ b/Patches/HideoutSearchPatches.cs @@ -6,8 +6,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using UnityEngine; -using UnityEngine.EventSystems; using UnityEngine.UI; namespace UIFixes @@ -18,6 +16,8 @@ namespace UIFixes private static float LastAbsoluteDownScrollPosition = -1f; + private static void ClearLastScrollPosition() => LastAbsoluteDownScrollPosition = -1f; + public static void Enable() { new LazyLoadPatch().Enable(); @@ -65,7 +65,7 @@ namespace UIFixes { // Last one, try to set it exactly scrollRect.verticalNormalizedPosition = 1f - (LastAbsoluteDownScrollPosition / (scrollRect.content.rect.height - scrollRect.viewport.rect.height)); - LastAbsoluteDownScrollPosition = -1f; + ClearLastScrollPosition(); } } } @@ -87,6 +87,9 @@ namespace UIFixes { ____searchInputField.text = lastSearch; } + + ScrollPatches.KeyScroller scroller = __instance.GetComponentInParent(); + scroller?.OnKeyScroll.AddListener(ClearLastScrollPosition); } [PatchPostfix] @@ -159,9 +162,14 @@ namespace UIFixes ScrollRect scrollRect = __instance.GetComponentInParent(); if (scrollRect != null) { - // Need to save the absolute DOWN position, because that's the direction the scrollbox will grow. - // Subtract the viewport height from content heigh because that's the actual RANGE of the scroll position - LastAbsoluteDownScrollPosition = (1f - scrollRect.verticalNormalizedPosition) * (scrollRect.content.rect.height - scrollRect.viewport.rect.height); + if (Settings.RestoreAsyncScrollPositions.Value) + { + // Need to save the absolute DOWN position, because that's the direction the scrollbox will grow. + // Subtract the viewport height from content heigh because that's the actual RANGE of the scroll position + LastAbsoluteDownScrollPosition = (1f - scrollRect.verticalNormalizedPosition) * (scrollRect.content.rect.height - scrollRect.viewport.rect.height); + } + + scrollRect.GetComponent()?.OnKeyScroll.RemoveListener(ClearLastScrollPosition); } // Reset the default behavior @@ -183,7 +191,7 @@ namespace UIFixes public static void Postfix() { LastSearches.Clear(); - LastAbsoluteDownScrollPosition = -1f; + ClearLastScrollPosition(); } } @@ -197,7 +205,7 @@ namespace UIFixes [PatchPostfix] public static void Postfix() { - LastAbsoluteDownScrollPosition = -1f; + ClearLastScrollPosition(); } } } diff --git a/Patches/ScrollPatches.cs b/Patches/ScrollPatches.cs index 6cd94ea..b6cb12d 100644 --- a/Patches/ScrollPatches.cs +++ b/Patches/ScrollPatches.cs @@ -1,4 +1,5 @@ using Aki.Reflection.Patching; +using EFT.Hideout; using EFT.UI; using EFT.UI.Chat; using EFT.UI.Ragfair; @@ -8,6 +9,7 @@ using System; using System.Collections.Generic; using System.Reflection; using UnityEngine; +using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; @@ -22,9 +24,10 @@ namespace UIFixes new EnhanceFleaScrollingPatch().Enable(); new EnhanceMailScrollingPatch().Enable(); new MouseScrollingSpeedPatch().Enable(); + new EnhanceHideoutScrollingPatch().Enable(); } - private static void HandleInput(ScrollRect scrollRect) + private static bool HandleInput(ScrollRect scrollRect) { if (scrollRect != null) { @@ -33,10 +36,12 @@ namespace UIFixes if (Input.GetKeyDown(KeyCode.Home)) { scrollRect.verticalNormalizedPosition = 1f; + return true; } if (Input.GetKeyDown(KeyCode.End)) { scrollRect.verticalNormalizedPosition = 0f; + return true; } } @@ -51,6 +56,7 @@ namespace UIFixes scrollRect.verticalNormalizedPosition = Math.Min(1f, scrollRect.verticalNormalizedPosition + pageSize); + return true; } if (Input.GetKeyDown(KeyCode.PageDown)) @@ -62,13 +68,16 @@ namespace UIFixes scrollRect.verticalNormalizedPosition = Math.Max(0f, scrollRect.verticalNormalizedPosition - pageSize); + return true; } } } + + return false; } // LightScrollers don't expose heights that I can see, so just fudge it with fake OnScroll events - private static void HandleInput(LightScroller lightScroller) + private static bool HandleInput(LightScroller lightScroller) { if (lightScroller != null) { @@ -77,10 +86,12 @@ namespace UIFixes if (Input.GetKeyDown(KeyCode.Home)) { lightScroller.SetScrollPosition(0f); + return true; } if (Input.GetKeyDown(KeyCode.End)) { lightScroller.SetScrollPosition(1f); + return true; } } @@ -93,6 +104,7 @@ namespace UIFixes scrollDelta = new Vector2(0f, 25f) }; lightScroller.OnScroll(eventData); + return true; } if (Input.GetKeyDown(KeyCode.PageDown)) { @@ -101,9 +113,12 @@ namespace UIFixes scrollDelta = new Vector2(0f, -25f) }; lightScroller.OnScroll(eventData); + return true; } } } + + return false; } private static IEnumerable RemovePageUpDownHandling(IEnumerable instructions) @@ -131,6 +146,27 @@ namespace UIFixes } } + public class KeyScroller : MonoBehaviour + { + private ScrollRect scrollRect; + + public UnityEvent OnKeyScroll; + + public void Awake() + { + scrollRect = GetComponent(); + OnKeyScroll = new(); + } + + public void Update() + { + if (HandleInput(scrollRect)) + { + OnKeyScroll.Invoke(); + } + } + } + public class EnhanceStashScrollingPatch : ModulePatch { protected override MethodBase GetTargetMethod() @@ -207,6 +243,26 @@ namespace UIFixes } } + public class EnhanceHideoutScrollingPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(AreaScreenSubstrate), nameof(AreaScreenSubstrate.Awake)); + } + + [PatchPostfix] + public static void Postfix(AreaScreenSubstrate __instance) + { + ScrollRect scrollRect = __instance.transform.Find("Content/CurrentLevel/CurrentContainer/Scrollview")?.GetComponent(); + if (scrollRect == null) + { + return; + } + + scrollRect.GetOrAddComponent(); + } + } + public class EnhanceMailScrollingPatch : ModulePatch { protected override MethodBase GetTargetMethod() diff --git a/Settings.cs b/Settings.cs index b172bc0..abe8aab 100644 --- a/Settings.cs +++ b/Settings.cs @@ -36,6 +36,7 @@ namespace UIFixes public static ConfigEntry AutofillQuestTurnIns { get; set; } public static ConfigEntry AutoSwitchTrading { get; set; } public static ConfigEntry ClickOutOfDialogs { get; set; } // Advanced + public static ConfigEntry RestoreAsyncScrollPositions { get; set; } // Advanced // Input public static ConfigEntry UseHomeEnd { get; set; } @@ -143,6 +144,15 @@ namespace UIFixes null, new ConfigurationManagerAttributes { IsAdvanced = true }))); + configEntries.Add(RestoreAsyncScrollPositions = config.Bind( + GeneralSection, + "Restore Async Scroll Positions", + true, + new ConfigDescription( + "In scroll views that load content dynamically, scroll down as the content loads to restore old scroll position", + null, + new ConfigurationManagerAttributes { IsAdvanced = true }))); + // Input configEntries.Add(UseHomeEnd = config.Bind( InputSection,