From a5ec556f0d8516f03f670de2494ed5fff5be76a7 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 6 May 2021 15:52:07 -0400 Subject: [PATCH] feat(scrollviewer): Add ability to configure scrollbar's auto-hide delay, and fully disable auto-hide --- src/Uno.UI/FeatureConfiguration.cs | 8 +++++ .../Controls/ScrollViewer/ScrollViewer.cs | 36 +++++++++++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/Uno.UI/FeatureConfiguration.cs b/src/Uno.UI/FeatureConfiguration.cs index 299c7fdb6d14..cdbd6dc4f91f 100644 --- a/src/Uno.UI/FeatureConfiguration.cs +++ b/src/Uno.UI/FeatureConfiguration.cs @@ -395,6 +395,14 @@ public static class ScrollViewer /// public static ScrollViewerUpdatesMode DefaultUpdatesMode { get; set; } = ScrollViewerUpdatesMode.AsynchronousIdle; + /// + /// Defines the delay after which the scrollbars hide themselves when pointer is not over.
+ /// Default is 4 sec.
+ /// Setting this to will completely disable the auto hide feature. + ///
+ /// This is effective only for managed scrollbars (WASM, macOS and Skia for now) + public static TimeSpan? DefaultAutoHideDelay { get; set; } + #if __ANDROID__ /// /// This value defines an optional delay to be set for native ScrollBar thumbs to disapear. The diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs index f57fae020379..6d4bff1b7c93 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs @@ -907,7 +907,7 @@ protected override void OnApplyTemplate() OnBringIntoViewOnFocusChangeChangedPartial(BringIntoViewOnFocusChange); - ResetScrollIndicator(forced: true); + PrepareScrollIndicator(); } partial void OnApplyTemplatePartial(); @@ -1368,16 +1368,30 @@ public bool ChangeView(double? horizontalOffset, double? verticalOffset, float? return ChangeViewNative(horizontalOffset, verticalOffset, zoomFactor, disableAnimation); } -#region Scroll indicators visual states (Managed scroll bars only) + #region Scroll indicators visual states (Managed scroll bars only) + private static readonly TimeSpan _indicatorResetDelay = FeatureConfiguration.ScrollViewer.DefaultAutoHideDelay ?? TimeSpan.FromSeconds(4); + private static readonly bool _indicatorResetDisabled = _indicatorResetDelay == TimeSpan.MaxValue; private DispatcherQueueTimer? _indicatorResetTimer; private string? _indicatorState; + private void PrepareScrollIndicator() // OnApplyTemplate + { + if (_indicatorResetDisabled) + { + ShowScrollIndicator(PointerDeviceType.Mouse, forced: true); + } + else + { + ResetScrollIndicator(forced: true); + } + } + private static void ShowScrollIndicator(object sender, PointerRoutedEventArgs e) // OnPointerMove => (sender as ScrollViewer)?.ShowScrollIndicator(e.Pointer.PointerDeviceType); - private void ShowScrollIndicator(PointerDeviceType type) + private void ShowScrollIndicator(PointerDeviceType type, bool forced = false) { - if (!ComputedIsVerticalScrollEnabled && !ComputedIsHorizontalScrollEnabled) + if (!forced && !ComputedIsVerticalScrollEnabled && !ComputedIsHorizontalScrollEnabled) { return; } @@ -1393,13 +1407,18 @@ private void ShowScrollIndicator(PointerDeviceType type) _indicatorState = indicatorState; } + if (_indicatorResetDisabled) + { + return; + } + // Automatically hide the scroll indicator after a delay without any interaction if (_indicatorResetTimer == null) { var weakRef = WeakReferencePool.RentSelfWeakReference(this); _indicatorResetTimer = new DispatcherQueueTimer { - Interval = TimeSpan.FromSeconds(4), + Interval = _indicatorResetDelay, IsRepeating = false }; _indicatorResetTimer.Tick += (snd, e) => (weakRef.Target as ScrollViewer)?.ResetScrollIndicator(); @@ -1412,6 +1431,11 @@ private void ShowScrollIndicator(PointerDeviceType type) private void ResetScrollIndicator(bool forced = false) { + if (_indicatorResetDisabled) + { + return; + } + _indicatorResetTimer?.Stop(); if (!forced && ((_horizontalScrollbar?.IsPointerOver ?? false) || (_verticalScrollbar?.IsPointerOver ?? false))) @@ -1447,6 +1471,6 @@ private void ResetScrollIndicator(bool forced = false) VisualStateManager.GoToState(this, VisualStates.ScrollBarsSeparator.Collapsed, true); } } -#endregion + #endregion } }