Browse Source

Adjust thumb drag position on track size change.

Fixes `ScrollViewer` jumping around when the scroll extent changes while dragging the scrollbar thumb.
pull/11252/head
Steven Kirk 3 years ago
parent
commit
69922b6917
  1. 6
      src/Avalonia.Controls/Primitives/Thumb.cs
  2. 20
      src/Avalonia.Controls/Primitives/Track.cs

6
src/Avalonia.Controls/Primitives/Thumb.cs

@ -46,6 +46,12 @@ namespace Avalonia.Controls.Primitives
remove { RemoveHandler(DragCompletedEvent, value); }
}
internal void AdjustDrag(Vector v)
{
if (_lastPoint.HasValue)
_lastPoint = _lastPoint.Value + v;
}
protected override AutomationPeer OnCreateAutomationPeer() => new ThumbAutomationPeer(this);
protected virtual void OnDragStarted(VectorEventArgs e)

20
src/Avalonia.Controls/Primitives/Track.cs

@ -45,6 +45,8 @@ namespace Avalonia.Controls.Primitives
public static readonly StyledProperty<bool> IgnoreThumbDragProperty =
AvaloniaProperty.Register<Track, bool>(nameof(IgnoreThumbDrag));
private Vector _lastDrag;
static Track()
{
ThumbProperty.Changed.AddClassHandler<Track>((x, e) => x.ThumbChanged(e));
@ -245,7 +247,10 @@ namespace Avalonia.Controls.Primitives
if (Thumb != null)
{
Thumb.Arrange(new Rect(offset, pieceSize));
var bounds = new Rect(offset, pieceSize);
var adjust = CalculateThumbAdjustment(Thumb, bounds);
Thumb.Arrange(bounds);
Thumb.AdjustDrag(adjust);
}
ThumbCenterOffset = offset.Y + (thumbLength * 0.5);
@ -277,15 +282,25 @@ namespace Avalonia.Controls.Primitives
if (Thumb != null)
{
Thumb.Arrange(new Rect(offset, pieceSize));
var bounds = new Rect(offset, pieceSize);
var adjust = CalculateThumbAdjustment(Thumb, bounds);
Thumb.Arrange(bounds);
Thumb.AdjustDrag(adjust);
}
ThumbCenterOffset = offset.X + (thumbLength * 0.5);
}
_lastDrag = default;
return arrangeSize;
}
private Vector CalculateThumbAdjustment(Thumb thumb, Rect newThumbBounds)
{
var thumbDelta = newThumbBounds.Position - thumb.Bounds.Position;
return _lastDrag - thumbDelta;
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
@ -444,6 +459,7 @@ namespace Avalonia.Controls.Primitives
Value + ValueFromDistance(e.Vector.X, e.Vector.Y),
Minimum,
Maximum));
_lastDrag = e.Vector;
}
private void ShowChildren(bool visible)

Loading…
Cancel
Save