/// <summary> /// Attempts to find a scope cursor's lines at the the specified position. /// Cursors at the end of the cursor list have the highest priority. /// </summary> /// <param name="searchPosition">The position to search at.</param> /// <param name="selectableOnly"> /// A value indicating whether to restrict the search to selectable cursor lines. /// </param> /// <returns>A scope cursor selection at the position or <c>null</c>.</returns> public ScopeCursorSelection FindScopeCursorLines(PointD searchPosition, bool selectableOnly) { var extents = _currentScopeGraphicsRangeExtents; var userRange = extents != null ? CreateScopeGraphicsRange(extents, _xMinimumGraticuleUnits, _yMinimumGraticuleUnits, _userOriginOffset) : null; if (userRange == null) { return(null); } return(Cursors .Select(cursor => { var deviceCursorPosition = userRange.Matrix.TransformPoint(cursor.Position.CairoPoint); // Select each axis we are nearby and which a visible line exists for. return new ScopeCursorSelection(cursor, // X axis ((cursor.Lines & ScopeCursorLines.X) != ScopeCursorLines.None && ((cursor.SelectableLines & ScopeCursorLines.X) != ScopeCursorLines.None || !selectableOnly) && Math.Abs(searchPosition.X - deviceCursorPosition.X) < _maxSnapDistance ? ScopeCursorLines.X : ScopeCursorLines.None) | // Y axis ((cursor.Lines & ScopeCursorLines.Y) != ScopeCursorLines.None && ((cursor.SelectableLines & ScopeCursorLines.Y) != ScopeCursorLines.None || !selectableOnly) && Math.Abs(searchPosition.Y - deviceCursorPosition.Y) < _maxSnapDistance ? ScopeCursorLines.Y : ScopeCursorLines.None)); }) .LastOrDefault(cursorSelection => cursorSelection.SelectedLines != ScopeCursorLines.None)); }