List <SnapToGridResult> GetClosestGridLines(Rect sourceRect, Orientation orientation) { SnapReference startReference = orientation == Orientation.Horizontal ? SnapReference.LeftEdge : SnapReference.TopEdge; SnapReference centerReference = orientation == Orientation.Horizontal ? SnapReference.HorizontalCenter : SnapReference.VerticalCenter; SnapReference endReference = orientation == Orientation.Horizontal ? SnapReference.RightEdge : SnapReference.BottomEdge; List <SnapToGridResult> results = new List <SnapToGridResult>(3); SnapToGridResult result = GetClosestGridLine(sourceRect, startReference, startReference, endReference); if (result != null) { results.Add(result); } result = GetClosestGridLine(sourceRect, centerReference, startReference, endReference); if (result != null) { results.Add(result); } result = GetClosestGridLine(sourceRect, endReference, startReference, endReference); if (result != null) { results.Add(result); } // Look for the minimum if (results.Count > 0) { results.Sort((a, b) => a.Distance.CompareTo(b.Distance)); float minDistance = results[0].Distance; results.RemoveAll(r => Math.Abs(r.Distance - minDistance) > 0.01f); } return(results); }
SnapToGridResult GetClosestGridLine(Rect sourceRect, SnapReference sourceRef, SnapReference startReference, SnapReference endReference) { float sourcePos = GetPositionWithBorder(sourceRect, sourceRef); float offsetStart = sourcePos - GetClosestGridLine(sourceRect, startReference); float offsetEnd = sourcePos - GetClosestGridLine(sourceRect, endReference); float minOffset = offsetStart; SnapReference minSnappableReference = startReference; if (Math.Abs(minOffset) > Math.Abs(offsetEnd)) { minOffset = offsetEnd; minSnappableReference = endReference; } SnapToGridResult minResult = new SnapToGridResult() { SnappableReference = minSnappableReference, Offset = minOffset }; return(minResult.Distance <= SnapDistance * 1 / m_CurrentScale ? minResult : null); }
static void ApplySnapToGridResult(ref Vector2 snappingOffset, Rect sourceRect, ref Rect r1, SnapToGridResult result) { if (result.SnappableReference <= SnapReference.RightEdge) { r1.x = sourceRect.x - result.Offset; snappingOffset.x = snappingOffset.x < float.MaxValue ? snappingOffset.x + result.Offset : result.Offset; } else { r1.y = sourceRect.y - result.Offset; snappingOffset.y = snappingOffset.y < float.MaxValue ? snappingOffset.y + result.Offset : result.Offset; } }