int GetOffsetFromMousePosition(Point positionRelativeToTextView, out int visualColumn) { visualColumn = 0; TextView textView = textArea.TextView; Point pos = positionRelativeToTextView; if (pos.Y < 0) { pos.Y = 0; } if (pos.Y > textView.ActualHeight) { pos.Y = textView.ActualHeight; } pos += textView.ScrollOffset; if (pos.Y > textView.DocumentHeight) { pos.Y = textView.DocumentHeight - ExtensionMethods.Epsilon; } VisualLine line = textView.GetVisualLineFromVisualTop(pos.Y); if (line != null) { visualColumn = line.GetVisualColumn(pos); return(line.GetRelativeOffset(visualColumn) + line.FirstDocumentLine.Offset); } return(-1); }
/// <summary> /// Validates the visual column of the caret using the specified visual line. /// The visual line must contain the caret offset. /// </summary> void RevalidateVisualColumn(VisualLine visualLine) { if (visualLine == null) { throw new ArgumentNullException("visualLine"); } // mark column as validated visualColumnValid = true; int caretOffset = textView.Document.GetOffset(position); int firstDocumentLineOffset = visualLine.FirstDocumentLine.Offset; if (position.VisualColumn < 0) { position.VisualColumn = visualLine.GetVisualColumn(caretOffset - firstDocumentLineOffset); } else { int offsetFromVisualColumn = visualLine.GetRelativeOffset(position.VisualColumn); offsetFromVisualColumn += firstDocumentLineOffset; if (offsetFromVisualColumn != caretOffset) { position.VisualColumn = visualLine.GetVisualColumn(caretOffset - firstDocumentLineOffset); } else { if (position.VisualColumn > visualLine.VisualLength) { position.VisualColumn = visualLine.VisualLength; } } } // search possible caret position (first try forwards) int newVisualColumn = visualLine.GetNextCaretPosition(position.VisualColumn - 1, LogicalDirection.Forward, CaretPositioningMode.Normal); if (newVisualColumn < 0) { // then try backwards newVisualColumn = visualLine.GetNextCaretPosition(position.VisualColumn + 1, LogicalDirection.Backward, CaretPositioningMode.Normal); } if (newVisualColumn >= 0 && newVisualColumn != position.VisualColumn) { int newOffset = visualLine.GetRelativeOffset(newVisualColumn) + firstDocumentLineOffset; this.Position = new TextViewPosition(textView.Document.GetLocation(newOffset), newVisualColumn); } }
/// <summary> /// Changes a part of the current document line. /// </summary> /// <param name="startOffset">Start offset of the region to change</param> /// <param name="endOffset">End offset of the region to change</param> /// <param name="action">Action that changes an individual <see cref="VisualLineElement"/>.</param> protected void ChangeLinePart(int startOffset, int endOffset, Action <VisualLineElement> action) { if (startOffset < currentDocumentLineStartOffset || startOffset > currentDocumentLineEndOffset) { throw new ArgumentOutOfRangeException("startOffset", startOffset, "Value must be between " + currentDocumentLineStartOffset + " and " + currentDocumentLineEndOffset); } if (endOffset < startOffset || endOffset > currentDocumentLineEndOffset) { throw new ArgumentOutOfRangeException("endOffset", endOffset, "Value must be between " + startOffset + " and " + currentDocumentLineEndOffset); } VisualLine vl = this.CurrentContext.VisualLine; int visualStart = vl.GetVisualColumn(startOffset - firstLineStart); int visualEnd = vl.GetVisualColumn(endOffset - firstLineStart); if (visualStart < visualEnd) { ChangeVisualElements(visualStart, visualEnd, action); } }
int GetTextLineIndexFromOffset(List <TextLine> textLines, int offset) { int lineNumber = TextView.Document.GetLineByOffset(offset).LineNumber; VisualLine vl = TextView.GetVisualLine(lineNumber); if (vl != null) { int relOffset = offset - vl.FirstDocumentLine.Offset; TextLine line = vl.GetTextLine(vl.GetVisualColumn(relOffset)); return(textLines.IndexOf(line)); } return(-1); }
SimpleSegment GetWordAtMousePosition(MouseEventArgs e) { TextView textView = textArea.TextView; if (textView == null) { return(SimpleSegment.Invalid); } Point pos = e.GetPosition(textView); if (pos.Y < 0) { pos.Y = 0; } if (pos.Y > textView.ActualHeight) { pos.Y = textView.ActualHeight; } pos += textView.ScrollOffset; VisualLine line = textView.GetVisualLineFromVisualTop(pos.Y); if (line != null) { int visualColumn = line.GetVisualColumn(pos); int wordStartVC = line.GetNextCaretPosition(visualColumn + 1, LogicalDirection.Backward, CaretPositioningMode.WordStartOrSymbol); if (wordStartVC == -1) { wordStartVC = 0; } int wordEndVC = line.GetNextCaretPosition(wordStartVC, LogicalDirection.Forward, CaretPositioningMode.WordBorderOrSymbol); if (wordEndVC == -1) { wordEndVC = line.VisualLength; } int relOffset = line.FirstDocumentLine.Offset; int wordStartOffset = line.GetRelativeOffset(wordStartVC) + relOffset; int wordEndOffset = line.GetRelativeOffset(wordEndVC) + relOffset; return(new SimpleSegment(wordStartOffset, wordEndOffset - wordStartOffset)); } else { return(SimpleSegment.Invalid); } }