int GetOffsetFromMousePositionFirstTextLineOnly(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(line.TextLines.First(), pos.X, textArea.Selection.EnableVirtualSpace); return(line.GetRelativeOffset(visualColumn) + line.FirstDocumentLine.Offset); } return(-1); }
static void MoveCaretLeft(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode) { int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace); if (pos >= 0) { SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset); } else { // move to end of previous line DocumentLine previousDocumentLine = visualLine.FirstDocumentLine.PreviousLine; if (previousDocumentLine != null) { VisualLine previousLine = textArea.TextView.GetOrConstructVisualLine(previousDocumentLine); pos = previousLine.GetNextCaretPosition(previousLine.VisualLength + 1, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace); if (pos < 0) { throw ThrowUtil.NoValidCaretPosition(); } SetCaretPosition(textArea, pos, previousLine.GetRelativeOffset(pos) + previousLine.FirstDocumentLine.Offset); } else { // at start of document Debug.Assert(visualLine.FirstDocumentLine.Offset == 0); SetCaretPosition(textArea, 0, 0); } } }
static void MoveCaretRight(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode) { int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace); if (pos >= 0) { SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset); } else { // move to start of next line DocumentLine nextDocumentLine = visualLine.LastDocumentLine.NextLine; if (nextDocumentLine != null) { VisualLine nextLine = textArea.TextView.GetOrConstructVisualLine(nextDocumentLine); pos = nextLine.GetNextCaretPosition(-1, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace); if (pos < 0) { throw ThrowUtil.NoValidCaretPosition(); } SetCaretPosition(textArea, pos, nextLine.GetRelativeOffset(pos) + nextLine.FirstDocumentLine.Offset); } else { // at end of document Debug.Assert(visualLine.LastDocumentLine.Offset + visualLine.LastDocumentLine.TotalLength == textArea.Document.TextLength); SetCaretPosition(textArea, -1, textArea.Document.TextLength); } } }
static void MoveCaretToEndOfLine(TextArea textArea, VisualLine visualLine, TextLine textLine) { int newVC = visualLine.GetTextLineVisualStartColumn(textLine) + textLine.Length - textLine.TrailingWhitespaceLength; int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC); SetCaretPosition(textArea, newVC, offset, isAtEndOfLine: true); }
static void MoveCaretToEndOfLine(TextArea textArea, VisualLine visualLine) { int newVC = visualLine.VisualLength; int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC); SetCaretPosition(textArea, newVC, offset); }
int GetOffsetFromMousePosition(Point positionRelativeToTextView, out int visualColumn, out bool isAtEndOfLine) { 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 - 0.01; } VisualLine line = textView.GetVisualLineFromVisualTop(pos.Y); if (line != null) { var textLine = line.GetTextLineByVisualYPosition(pos.Y); visualColumn = line.GetVisualColumn(textLine, pos.X, textArea.Selection.EnableVirtualSpace); isAtEndOfLine = (visualColumn >= line.GetTextLineVisualStartColumn(textLine) + textLine.Length); return(line.GetRelativeOffset(visualColumn) + line.FirstDocumentLine.Offset); } isAtEndOfLine = false; return(-1); }
void CalculateSegments() { DocumentLine nextLine = document.GetLineByNumber(Math.Min(startLine, endLine)); do { VisualLine vl = textArea.TextView.GetOrConstructVisualLine(nextLine); int startVC = vl.GetVisualColumn(new Point(startXPos, 0), true); int endVC = vl.GetVisualColumn(new Point(endXPos, 0), true); int baseOffset = vl.FirstDocumentLine.Offset; int startOffset = baseOffset + vl.GetRelativeOffset(startVC); int endOffset = baseOffset + vl.GetRelativeOffset(endVC); segments.Add(new SelectionSegment(startOffset, startVC, endOffset, endVC)); nextLine = vl.LastDocumentLine.NextLine; } while (nextLine != null && nextLine.LineNumber <= Math.Max(startLine, endLine)); }
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, textArea.Selection.EnableVirtualSpace); int wordStartVC = line.GetNextCaretPosition(visualColumn + 1, LogicalDirection.Backward, CaretPositioningMode.WordStartOrSymbol, textArea.Selection.EnableVirtualSpace); if (wordStartVC == -1) { wordStartVC = 0; } int wordEndVC = line.GetNextCaretPosition(wordStartVC, LogicalDirection.Forward, CaretPositioningMode.WordBorderOrSymbol, textArea.Selection.EnableVirtualSpace); 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); } }
static void SetCaretPosition(TextArea textArea, VisualLine targetVisualLine, TextLine targetLine, CharacterHit ch, bool allowWrapToNextLine) { int newVisualColumn = ch.FirstCharacterIndex + ch.TrailingLength; int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine); if (!allowWrapToNextLine && newVisualColumn >= targetLineStartCol + targetLine.Length) { newVisualColumn = targetLineStartCol + targetLine.Length - 1; } int newOffset = targetVisualLine.GetRelativeOffset(newVisualColumn) + targetVisualLine.FirstDocumentLine.Offset; SetCaretPosition(textArea, newVisualColumn, newOffset); }
private void OnTextEditorMouseHover(object sender, MouseEventArgs eventArgs) { // Find offset under mouse cursor. var mousePos = eventArgs.GetPosition(_textEditor.TextArea.TextView); double verticalOffset = _textEditor.VerticalOffset; VisualLine visualLine = _textEditor.TextArea.TextView.GetVisualLineFromVisualTop(mousePos.Y + verticalOffset); if (visualLine == null) { return; } double horizontalOffset = _textEditor.HorizontalOffset; int visualColumn = visualLine.GetVisualColumn(mousePos + new Vector(horizontalOffset, verticalOffset)); int relativeOffset = visualLine.GetRelativeOffset(visualColumn); int offset = visualLine.FirstDocumentLine.Offset + relativeOffset; // Get word at mouse cursor. var text = TextUtilities.GetIdentifierAt(_textEditor.Document, offset); // Get region at mouse cursor. ShaderRegion region = _parser.IdentifyRegion(_textEditor.Document, offset); NamedObjectCollection <NamedCompletionData>[] lookupTables = GetToolTipLookupTables(region); if (lookupTables != null) { // Look up symbol in lookup tables. NamedCompletionData info = null; foreach (NamedObjectCollection <NamedCompletionData> lookupTable in lookupTables) { if (lookupTable.TryGet <NamedCompletionData>(text, out info)) { break; } } // Show tooltip if lookup was successful and description for the symbol is available. if (info != null && !string.IsNullOrEmpty(info.Description as string)) { // TODO: Use s better tooltip style. _toolTip = new ToolTip { Content = info.Description, Placement = PlacementMode.Mouse, IsOpen = true, }; } } }
static void SetCaretPosition(TextArea textArea, VisualLine targetVisualLine, TextLine targetLine, int newVisualColumn, bool allowWrapToNextLine) { int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine); if (!allowWrapToNextLine && newVisualColumn >= targetLineStartCol + targetLine.Length) { if (newVisualColumn <= targetVisualLine.VisualLength) { newVisualColumn = targetLineStartCol + targetLine.Length - 1; } } int newOffset = targetVisualLine.GetRelativeOffset(newVisualColumn) + targetVisualLine.FirstDocumentLine.Offset; SetCaretPosition(textArea, newVisualColumn, newOffset); }
static void MoveCaretToStartOfLine(TextArea textArea, VisualLine visualLine) { int newVC = visualLine.GetNextCaretPosition(-1, LogicalDirection.Forward, CaretPositioningMode.WordStart); if (newVC < 0) { throw ThrowUtil.NoValidCaretPosition(); } // when the caret is already at the start of the text, jump to start before whitespace if (newVC == textArea.Caret.VisualColumn) { newVC = 0; } int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC); SetCaretPosition(textArea, newVC, offset); }
/// <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.Location); int firstDocumentLineOffset = visualLine.FirstDocumentLine.Offset; position.VisualColumn = visualLine.ValidateVisualColumn(position, textArea.Selection.EnableVirtualSpace); // search possible caret positions int newVisualColumnForwards = visualLine.GetNextCaretPosition(position.VisualColumn - 1, LogicalDirection.Forward, CaretPositioningMode.Normal, textArea.Selection.EnableVirtualSpace); // If position.VisualColumn was valid, we're done with validation. if (newVisualColumnForwards != position.VisualColumn) { // also search backwards so that we can pick the better match int newVisualColumnBackwards = visualLine.GetNextCaretPosition(position.VisualColumn + 1, LogicalDirection.Backward, CaretPositioningMode.Normal, textArea.Selection.EnableVirtualSpace); if (newVisualColumnForwards < 0 && newVisualColumnBackwards < 0) { throw ThrowUtil.NoValidCaretPosition(); } // determine offsets for new visual column positions int newOffsetForwards; if (newVisualColumnForwards >= 0) { newOffsetForwards = visualLine.GetRelativeOffset(newVisualColumnForwards) + firstDocumentLineOffset; } else { newOffsetForwards = -1; } int newOffsetBackwards; if (newVisualColumnBackwards >= 0) { newOffsetBackwards = visualLine.GetRelativeOffset(newVisualColumnBackwards) + firstDocumentLineOffset; } else { newOffsetBackwards = -1; } int newVisualColumn, newOffset; // if there's only one valid position, use it if (newVisualColumnForwards < 0) { newVisualColumn = newVisualColumnBackwards; newOffset = newOffsetBackwards; } else if (newVisualColumnBackwards < 0) { newVisualColumn = newVisualColumnForwards; newOffset = newOffsetForwards; } else { // two valid positions: find the better match if (Math.Abs(newOffsetBackwards - caretOffset) < Math.Abs(newOffsetForwards - caretOffset)) { // backwards is better newVisualColumn = newVisualColumnBackwards; newOffset = newOffsetBackwards; } else { // forwards is better newVisualColumn = newVisualColumnForwards; newOffset = newOffsetForwards; } } this.Position = new TextViewPosition(textView.Document.GetLocation(newOffset), newVisualColumn); } isInVirtualSpace = (position.VisualColumn > visualLine.VisualLength); }