Browse Source

support single scroll snap on pointer wheel

pull/9961/head
Emmanuel Hansen 4 years ago
parent
commit
93f6d31966
  1. 80
      src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

80
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@ -607,6 +607,30 @@ namespace Avalonia.Controls.Presenters
if (Extent.Height > Viewport.Height)
{
double height = isLogical ? scrollable!.ScrollSize.Height : 50;
if(VerticalSnapPointsType == SnapPointsType.MandatorySingle && Content is IScrollSnapPointsInfo)
{
if(_areVerticalSnapPointsRegular)
{
height = _verticalSnapPoint;
}
else
{
double yOffset = Offset.Y;
switch (VerticalSnapPointsAlignment)
{
case SnapPointsAlignment.Center:
yOffset += Viewport.Height / 2;
break;
case SnapPointsAlignment.Far:
yOffset += Viewport.Height;
break;
}
var snapPoint = FindNearestSnapPoint(_verticalSnapPoints, yOffset, out var lowerSnapPoint);
height = snapPoint - lowerSnapPoint;
}
}
y += -delta.Y * height;
y = Math.Max(y, 0);
y = Math.Min(y, Extent.Height - Viewport.Height);
@ -615,6 +639,30 @@ namespace Avalonia.Controls.Presenters
if (Extent.Width > Viewport.Width)
{
double width = isLogical ? scrollable!.ScrollSize.Width : 50;
if (HorizontalSnapPointsType == SnapPointsType.MandatorySingle && Content is IScrollSnapPointsInfo)
{
if (_areHorizontalSnapPointsRegular)
{
width = _horizontalSnapPoint;
}
else
{
double xOffset = Offset.X;
switch (VerticalSnapPointsAlignment)
{
case SnapPointsAlignment.Center:
xOffset += Viewport.Width / 2;
break;
case SnapPointsAlignment.Far:
xOffset += Viewport.Width;
break;
}
var snapPoint = FindNearestSnapPoint(_horizontalSnapPoints, xOffset, out var lowerSnapPoint);
width = snapPoint - lowerSnapPoint;
}
}
x += -delta.X * width;
x = Math.Max(x, 0);
x = Math.Min(x, Extent.Width - Viewport.Width);
@ -903,19 +951,6 @@ namespace Avalonia.Controls.Presenters
}
double FindNearestSnapPoint(IReadOnlyList<double> snapPoints, double value, out double lowerSnapPoint)
{
var point = snapPoints.BinarySearch(value, Comparer<double>.Default);
if (point < 0)
{
point = ~point;
}
lowerSnapPoint = snapPoints[Math.Max(0, point - 1)];
return snapPoints[Math.Min(point, snapPoints.Count - 1)];
}
Vector GetAlignedDiff()
{
var vector = offset;
@ -945,5 +980,24 @@ namespace Avalonia.Controls.Presenters
return offset;
}
private static double FindNearestSnapPoint(IReadOnlyList<double> snapPoints, double value, out double lowerSnapPoint)
{
var point = snapPoints.BinarySearch(value, Comparer<double>.Default);
if (point < 0)
{
point = ~point;
lowerSnapPoint = snapPoints[Math.Max(0, point - 1)];
}
else
{
lowerSnapPoint = snapPoints[point];
point += 1;
}
return snapPoints[Math.Min(point, snapPoints.Count - 1)];
}
}
}

Loading…
Cancel
Save