SimpleSegment GetTextLineSegment(MouseEventArgs e) { var pos = e.GetPosition(TextView); pos.X = 0; pos.Y += TextView.VerticalOffset; VisualLine vl = TextView.GetVisualLineFromVisualTop(pos.Y); if (vl == null) { return(SimpleSegment.Invalid); } TextLine tl = vl.GetTextLineByVisualYPosition(pos.Y); int visualStartColumn = vl.GetTextLineVisualStartColumn(tl); int visualEndColumn = visualStartColumn + tl.Length; int relStart = vl.FirstDocumentLine.Offset; int startOffset = vl.GetRelativeOffset(visualStartColumn) + relStart; int endOffset = vl.GetRelativeOffset(visualEndColumn) + relStart; if (endOffset == vl.LastDocumentLine.Offset + vl.LastDocumentLine.Length) { endOffset += vl.LastDocumentLine.DelimiterLength; } return(new SimpleSegment(startOffset, endOffset - startOffset)); }
/// <inheritdoc/> protected override void OnMouseDown(MouseButtonEventArgs e) { int lineNumber = 0; Point pos = e.GetPosition(TextView); pos.X = 0; pos.Y += TextView.VerticalOffset; VisualLine vl = TextView.GetVisualLineFromVisualTop(pos.Y); if (vl != null) { TextLine tl = vl.GetTextLineByVisualYPosition(pos.Y); int visualStartColumn = vl.GetTextLineVisualStartColumn(tl); int relStart = vl.FirstDocumentLine.Offset; int startOffset = vl.GetRelativeOffset(visualStartColumn) + relStart; lineNumber = TextView.Document.GetLineByOffset(startOffset).LineNumber; } List <int> breakpoints = Breakpoints; if (breakpoints != null && lineNumber > 0) { if (breakpoints.Contains(lineNumber)) { breakpoints.Remove(lineNumber); } else { breakpoints.Add(lineNumber); } InvalidateVisual(); } base.OnMouseDown(e); }
protected override void OnRender(DrawingContext drawingContext) { if (TextView != null && TextView.VisualLinesValid && m_Settings.AssemblyEditorSettings.ShowClockCycles) { if (m_Analyzer.InterPretedAssemblyRows != null) { var interpretedz80Instructions = m_Analyzer.InterPretedAssemblyRows .Where(ar => ar.Instruction.Type == Z80.Kernel.Z80Assembler.InstructionType.ProcessorInstruction) .Select(ar => ar); m_TextColor = new SolidColorBrush(m_Settings.AssemblyEditorSettings.ClockCycleColor.Color); foreach (AssemblyRow assemblyRow in interpretedz80Instructions) { VisualLine line = TextView.VisualLines.FirstOrDefault(vl => vl.FirstDocumentLine.LineNumber == assemblyRow.RowNumber); if (line != null) { FormattedText text = new FormattedText($"[{assemblyRow.ClockCycles}]", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("") , m_EmSize, m_TextColor); double y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineTop); double x = line.GetTextLineVisualXPosition(line.TextLines[0], line.GetTextLineVisualStartColumn(line.TextLines[0])); drawingContext.DrawText(text, new Point(x, y - TextView.VerticalOffset)); } } } } }
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); }
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); }
static TextViewPosition GetEndOfLineCaretPosition(VisualLine visualLine, TextLine textLine) { int newVC = visualLine.GetTextLineVisualStartColumn(textLine) + textLine.Length; TextViewPosition pos = visualLine.GetTextViewPosition(newVC); pos.IsAtEndOfLine = true; return(pos); }
private static TextViewPosition GetEndOfLineCaretPosition(VisualLine visualLine, TextLine textLine) { var newVisualCol = visualLine.GetTextLineVisualStartColumn(textLine) + textLine.Length - textLine.TrailingWhitespaceLength; var pos = visualLine.GetTextViewPosition(newVisualCol); pos.IsAtEndOfLine = true; return(pos); }
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); }
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 TextViewPosition GetStartOfLineCaretPosition(int oldVC, VisualLine visualLine, TextLine textLine, bool enableVirtualSpace) { int newVC = visualLine.GetTextLineVisualStartColumn(textLine); if (newVC == 0) { newVC = visualLine.GetNextCaretPosition(newVC - 1, LogicalDirection.Forward, CaretPositioningMode.WordStart, enableVirtualSpace); } if (newVC < 0) { throw ThrowUtil.NoValidCaretPosition(); } // when the caret is already at the start of the text, jump to start before whitespace if (newVC == oldVC) { newVC = 0; } return(visualLine.GetTextViewPosition(newVC)); }
static void MoveCaretToStartOfLine(TextArea textArea, VisualLine visualLine, TextLine textLine) { int newVC = visualLine.GetTextLineVisualStartColumn(textLine); if (newVC == 0) { newVC = visualLine.GetNextCaretPosition(newVC - 1, LogicalDirection.Forward, CaretPositioningMode.WordStart, textArea.Selection.EnableVirtualSpace); } 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); }
static TextViewPosition GetUpDownCaretPosition(TextView textView, TextViewPosition caretPosition, CaretMovementType direction, VisualLine visualLine, TextLine textLine, bool enableVirtualSpace, ref double xPos) { // moving up/down happens using the desired visual X position if (double.IsNaN(xPos)) { xPos = visualLine.GetTextLineVisualXPosition(textLine, caretPosition.VisualColumn); } // 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 = textView.Document.GetLineByNumber(prevLineNumber); targetVisualLine = 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 <= textView.Document.LineCount) { DocumentLine nextLine = textView.Document.GetLineByNumber(nextLineNumber); targetVisualLine = 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 -= textView.RenderSize.Height; } else { yPos += textView.RenderSize.Height; } DocumentLine newLine = textView.GetDocumentLineByVisualTop(yPos); targetVisualLine = textView.GetOrConstructVisualLine(newLine); targetLine = targetVisualLine.GetTextLineByVisualYPosition(yPos); break; } default: throw new NotSupportedException(direction.ToString()); } if (targetLine != null) { double yPos = targetVisualLine.GetTextLineVisualYPosition(targetLine, VisualYPosition.LineMiddle); int newVisualColumn = targetVisualLine.GetVisualColumn(new Point(xPos, yPos), enableVirtualSpace); // prevent wrapping to the next line; TODO: could 'IsAtEnd' help here? int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine); if (newVisualColumn >= targetLineStartCol + targetLine.Length) { if (newVisualColumn <= targetVisualLine.VisualLength) { newVisualColumn = targetLineStartCol + targetLine.Length - 1; } } return(targetVisualLine.GetTextViewPosition(newVisualColumn)); } else { return(caretPosition); } }