/// <summary> /// Gets the distance to the left border of the text area of the specified visual column. /// The visual column must belong to the specified text line. /// </summary> public double GetTextLineVisualXPosition(TextLine textLine, int visualColumn) { if (textLine == null) throw new ArgumentNullException("textLine"); double xPos = textLine.GetDistanceFromCharacterHit( new CharacterHit(Math.Min(visualColumn, VisualLengthWithEndOfLineMarker), 0)); if (visualColumn > VisualLengthWithEndOfLineMarker) { xPos += (visualColumn - VisualLengthWithEndOfLineMarker) * textView.WideSpaceWidth; } return xPos; }
private void FindSelectedArea(int idx, int txtLen, int txtOffset, double x, TextLine line, ref double start, ref double end) { int first = Math.Max(txtOffset, this.SelectionStart - idx); int last = Math.Min(txtLen - 1 + txtOffset, this.SelectionEnd - idx); if (last >= first) { start = Math.Min(start, line.GetDistanceFromCharacterHit(new CharacterHit(first, 0)) + x); end = Math.Max(end, line.GetDistanceFromCharacterHit(new CharacterHit(last, 1)) + x); } }
static void MoveCaretUpDown(TextArea textArea, CaretMovementType direction, VisualLine visualLine, TextLine textLine, int caretVisualColumn) { // moving up/down happens using the desired visual X position double xPos = textArea.Caret.DesiredXPos; if (double.IsNaN(xPos)) xPos = textLine.GetDistanceFromCharacterHit(new CharacterHit(caretVisualColumn, 0)); // now find the TextLine+VisualLine where the caret will end up in VisualLine targetVisualLine = visualLine; TextLine targetLine; int textLineIndex = visualLine.TextLines.IndexOf(textLine); switch (direction) { case CaretMovementType.LineUp: { // Move up: move to the previous TextLine in the same visual line // or move to the last TextLine of the previous visual line int prevLineNumber = visualLine.FirstDocumentLine.LineNumber - 1; if (textLineIndex > 0) { targetLine = visualLine.TextLines[textLineIndex - 1]; } else if (prevLineNumber >= 1) { DocumentLine prevLine = textArea.Document.GetLineByNumber(prevLineNumber); targetVisualLine = textArea.TextView.GetOrConstructVisualLine(prevLine); targetLine = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1]; } else { targetLine = null; } break; } case CaretMovementType.LineDown: { // Move down: move to the next TextLine in the same visual line // or move to the first TextLine of the next visual line int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1; if (textLineIndex < visualLine.TextLines.Count - 1) { targetLine = visualLine.TextLines[textLineIndex + 1]; } else if (nextLineNumber <= textArea.Document.LineCount) { DocumentLine nextLine = textArea.Document.GetLineByNumber(nextLineNumber); targetVisualLine = textArea.TextView.GetOrConstructVisualLine(nextLine); targetLine = targetVisualLine.TextLines[0]; } else { targetLine = null; } break; } case CaretMovementType.PageUp: case CaretMovementType.PageDown: { // Page up/down: find the target line using its visual position double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle); if (direction == CaretMovementType.PageUp) yPos -= textArea.TextView.RenderSize.Height; else yPos += textArea.TextView.RenderSize.Height; DocumentLine newLine = textArea.TextView.GetDocumentLineByVisualTop(yPos); targetVisualLine = textArea.TextView.GetOrConstructVisualLine(newLine); targetLine = targetVisualLine.GetTextLineByVisualYPosition(yPos); break; } default: throw new NotSupportedException(direction.ToString()); } if (targetLine != null) { CharacterHit ch = targetLine.GetCharacterHitFromDistance(xPos); SetCaretPosition(textArea, targetVisualLine, targetLine, ch, false); textArea.Caret.DesiredXPos = xPos; } }
private List<textView.TextBounds> GetTextBoundsOnLine(TextLine textLine, Double horizontalOffset, Int32 startIndex, Int32 endIndex) { var list = new List<textView.TextBounds>(); if (startIndex == endIndex) { Double distanceFromCharacterHit = textLine.GetDistanceFromCharacterHit(new CharacterHit(startIndex, 0)); list.Add(new textView.TextBounds((distanceFromCharacterHit + horizontalOffset) + this.HorizontalOffset, this.VerticalOffset, 0, this.Height)); return list; } foreach (textFormatting.TextBounds bounds in textLine.GetTextBounds(startIndex, endIndex - startIndex)) { list.Add(new textView.TextBounds(bounds.Rectangle.Left + horizontalOffset, bounds.Rectangle.Top + this.VerticalOffset, bounds.Rectangle.Width, this.Height)); } return list; }