Skip to content

Commit

Permalink
fix(SV): snapping issues
Browse files Browse the repository at this point in the history
- unable to snap to first/last item
- droid: invalid snap point calculation with uno impl
  • Loading branch information
Xiaoy312 committed Nov 11, 2022
1 parent c0bcd4e commit bf4843c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2079,17 +2079,16 @@ private IEnumerable<float> GetSnapPointsInner(SnapPointsAlignment alignment)

private float GetSnapPoint(View view, SnapPointsAlignment alignment)
{
switch (alignment)
var snapPointInPhysical = alignment switch
{
case SnapPointsAlignment.Near:
return ContentOffset + GetChildStartWithMargin(view);
case SnapPointsAlignment.Center:
return ContentOffset + (GetChildStartWithMargin(view) + GetChildEndWithMargin(view)) / 2f;
case SnapPointsAlignment.Far:
return ContentOffset + GetChildEndWithMargin(view);
default:
throw new ArgumentOutOfRangeException(nameof(alignment));
}
SnapPointsAlignment.Near => ContentOffset + GetChildStartWithMargin(view),
SnapPointsAlignment.Center => ContentOffset + (GetChildStartWithMargin(view) + GetChildEndWithMargin(view)) / 2f,
SnapPointsAlignment.Far => ContentOffset + GetChildEndWithMargin(view),

_ => throw new ArgumentOutOfRangeException(nameof(alignment)),
};

return (float)ViewHelper.PhysicalToLogicalPixels(snapPointInPhysical);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,32 +385,22 @@ private IReadOnlyList<float> CopyMotionSnapPoints(
// it doesn't matter so do it for consistency.
snapPoint *= zoomFactor;

var alignedSnapPoint = alignment switch
// Adjust snap point to relative(near/center/far) viewport offset, and then
// clamp it within valid scroll range.
var adjustedOffset = alignment switch
{
SnapPointsAlignment.Near => snapPoint,
SnapPointsAlignment.Center => (float)(snapPoint - viewportDimension / 2),
SnapPointsAlignment.Far => (float)(snapPoint - viewportDimension),
_ => throw new IndexOutOfRangeException("alignment")
};
var clampedOffset = (float)Math.Max(0, Math.Min(adjustedOffset, ScrollableWidth));

var distanceFromFarEdge = (float)(extentDimension - viewportDimension - alignedSnapPoint);

// With certain scale factors and resolutions the snap points sometimes get pushed out of bounds
// by rounding errors, in these cases we need to intervene and return them to the boundary.
if (distanceFromFarEdge < 0 &&
distanceFromFarEdge >= (-1.0 * (ScrollViewerSnapPointLocationTolerance * Math.Max(1.0f, zoomFactor))))
{
alignedSnapPoint = (float)(extentDimension - viewportDimension);
distanceFromFarEdge = 0;
}
if (alignedSnapPoint >= 0 && distanceFromFarEdge >= 0)
if (staticZoomFactor == 1.0f)
{
if (staticZoomFactor == 1.0f)
{
alignedSnapPoint /= zoomFactor;
}
result.Add(alignedSnapPoint);
clampedOffset /= zoomFactor;
}
result.Add(clampedOffset);
}
}
}
Expand Down

0 comments on commit bf4843c

Please sign in to comment.