From a806d4bd4734c04014f5fe9d3d0e7e92ca802588 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Tue, 24 Nov 2020 18:01:34 +0800 Subject: [PATCH 01/13] Add keyboard navigation to slider --- src/Avalonia.Controls/Slider.cs | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/Avalonia.Controls/Slider.cs b/src/Avalonia.Controls/Slider.cs index fe4b24099f..7690f474f3 100644 --- a/src/Avalonia.Controls/Slider.cs +++ b/src/Avalonia.Controls/Slider.cs @@ -188,6 +188,80 @@ namespace Avalonia.Controls _pointerMovedDispose = this.AddDisposableHandler(PointerMovedEvent, TrackMoved, RoutingStrategies.Tunnel); } + private void TrackOnKeyDown(object sender, KeyEventArgs e) + { + if (e.KeyModifiers != KeyModifiers.None) return; + + switch (e.Key) + { + case Key.Left: + MoveToNextTick(-SmallChange); + break; + + case Key.Right: + MoveToNextTick(SmallChange); + break; + + case Key.PageUp: + MoveToNextTick(-LargeChange); + break; + + case Key.PageDown: + MoveToNextTick(LargeChange); + break; + + case Key.Home: + Value = Minimum; + break; + + case Key.End: + Value = Maximum; + break; + } + } + + private void MoveToNextTick(double direction) + { + if (direction == 0.0) return; + + var value = Value; + + // Find the next value by snapping + var next = SnapToTick(Math.Max(Minimum, Math.Min(Maximum, value + direction))); + + var greaterThan = direction > 0; //search for the next tick greater than value? + + // If the snapping brought us back to value, find the next tick point + if (Math.Abs(next - value) < Tolerance + && !(greaterThan && Math.Abs(value - Maximum) < Tolerance) // Stop if searching up if already at Max + && !(!greaterThan && Math.Abs(value - Minimum) < Tolerance)) // Stop if searching down if already at Min + { + var ticks = Ticks; + + // If ticks collection is available, use it. + // Note that ticks may be unsorted. + if (ticks != null && ticks.Count > 0) + { + foreach (var tick in ticks) + { + // Find the smallest tick greater than value or the largest tick less than value + if (greaterThan && MathUtilities.GreaterThan(tick, value) && + (MathUtilities.LessThan(tick, next) || Math.Abs(next - value) < Tolerance) + || !greaterThan && MathUtilities.LessThan(tick, value) && + (MathUtilities.GreaterThan(tick, next) || Math.Abs(next - value) < Tolerance)) + { + next = tick; + } + } + } + else if (MathUtilities.GreaterThan(TickFrequency, 0.0)) + { + // Find the current tick we are at + var tickNumber = Math.Round((value - Minimum) / TickFrequency); + + _pointerMovedDispose = this.AddDisposableHandler(PointerMovedEvent, TrackMoved, RoutingStrategies.Tunnel); + } + private void TrackMoved(object sender, PointerEventArgs e) { if (_isDragging) From 52c14f65b6562dc99eec0831a5bd4b647c65ebe2 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Tue, 24 Nov 2020 18:04:04 +0800 Subject: [PATCH 02/13] Add keyboard navigation to slider --- src/Avalonia.Controls/Slider.cs | 36 ++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/Avalonia.Controls/Slider.cs b/src/Avalonia.Controls/Slider.cs index 7690f474f3..c55a391928 100644 --- a/src/Avalonia.Controls/Slider.cs +++ b/src/Avalonia.Controls/Slider.cs @@ -11,7 +11,6 @@ using Avalonia.Utilities; namespace Avalonia.Controls { - /// /// Enum which describes how to position the ticks in a . /// @@ -84,6 +83,8 @@ namespace Avalonia.Controls private IDisposable _increaseButtonSubscription; private IDisposable _increaseButtonReleaseDispose; private IDisposable _pointerMovedDispose; + + private const double Tolerance = 0.0001; /// /// Initializes static members of the class. @@ -95,7 +96,7 @@ namespace Avalonia.Controls Thumb.DragStartedEvent.AddClassHandler((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble); Thumb.DragCompletedEvent.AddClassHandler((x, e) => x.OnThumbDragCompleted(e), RoutingStrategies.Bubble); - + ValueProperty.OverrideMetadata(new DirectPropertyMetadata(enableDataValidation: true)); } @@ -157,7 +158,7 @@ namespace Avalonia.Controls protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); - + _decreaseButtonPressDispose?.Dispose(); _decreaseButtonReleaseDispose?.Dispose(); _increaseButtonSubscription?.Dispose(); @@ -168,9 +169,11 @@ namespace Avalonia.Controls _track = e.NameScope.Find("PART_Track"); _increaseButton = e.NameScope.Find