bool Intersects(SnapshotSpan fullSpan, ITextViewLine line, Rect rect) { var span = fullSpan.Intersection(line.ExtentIncludingLineBreak); if (span == null || span.Value.Length == 0) return false; var start = line.GetExtendedCharacterBounds(span.Value.Start); var end = line.GetExtendedCharacterBounds(span.Value.End - 1); double left = Math.Min(start.Left, end.Left) - wpfTextView.ViewportLeft; double top = Math.Min(start.Top, end.Top) - wpfTextView.ViewportTop; double right = Math.Max(start.Right, end.Right) - wpfTextView.ViewportLeft; double bottom = Math.Max(start.Bottom, end.Bottom) - wpfTextView.ViewportTop; bool b = left <= right && top <= bottom; Debug.Assert(b); if (!b) return false; var r = new Rect(left, top, right - left, bottom - top); return r.IntersectsWith(rect); }
CaretPosition MoveTo(ITextViewLine textLine, double xCoordinate, bool captureHorizontalPosition, bool captureVerticalPosition, bool canAutoIndent) { if (textLine == null) { throw new ArgumentNullException(nameof(textLine)); } bool filterPos = true; // Don't auto indent if it's at column 0 if (canAutoIndent && CanAutoIndent(textLine) && xCoordinate > textLine.TextRight) { var wpfView = textView as IWpfTextView; if (wpfView != null) { int indentation = IndentHelper.GetDesiredIndentation(textView, smartIndentationService, textLine.Start.GetContainingLine()) ?? 0; var textBounds = textLine.GetExtendedCharacterBounds(new VirtualSnapshotPoint(textLine.Start, indentation)); xCoordinate = textBounds.Leading; filterPos = false; } } var bufferPosition = textLine.GetInsertionBufferPositionFromXCoordinate(xCoordinate); Affinity = textLine.IsLastTextViewLineForSnapshotLine || bufferPosition.Position != textLine.End ? PositionAffinity.Successor : PositionAffinity.Predecessor; if (filterPos) { bufferPosition = FilterColumn(bufferPosition); } SetExplicitPosition(bufferPosition); if (captureHorizontalPosition) { preferredXCoordinate = Left; } if (captureVerticalPosition) { SavePreferredYCoordinate(); } return(Position); }
bool Intersects(SnapshotSpan fullSpan, ITextViewLine line, Rect rect) { var span = fullSpan.Intersection(line.ExtentIncludingLineBreak); if (span == null || span.Value.Length == 0) return false; var start = line.GetExtendedCharacterBounds(span.Value.Start); var end = line.GetExtendedCharacterBounds(span.Value.End - 1); double left = Math.Min(start.Left, end.Left) - wpfTextView.ViewportLeft; double top = Math.Min(start.Top, end.Top) - wpfTextView.ViewportTop; double right = Math.Max(start.Right, end.Right) - wpfTextView.ViewportLeft; double bottom = Math.Max(start.Bottom, end.Bottom) - wpfTextView.ViewportTop; bool b = left <= right && top <= bottom; Debug.Assert(b); if (!b) return false; var r = new Rect(left, top, right - left, bottom - top); return r.IntersectsWith(rect); }
CaretPosition MoveTo(ITextViewLine textLine, double xCoordinate, bool captureHorizontalPosition, bool captureVerticalPosition, bool canAutoIndent) { if (textLine == null) throw new ArgumentNullException(nameof(textLine)); bool filterPos = true; // Don't auto indent if it's at column 0 if (canAutoIndent && CanAutoIndent(textLine) && xCoordinate > textLine.TextRight) { var wpfView = textView as IWpfTextView; if (wpfView != null) { int indentation = IndentHelper.GetDesiredIndentation(textView, smartIndentationService, textLine.Start.GetContainingLine()) ?? 0; var textBounds = textLine.GetExtendedCharacterBounds(new VirtualSnapshotPoint(textLine.Start, indentation)); xCoordinate = textBounds.Leading; filterPos = false; } } var bufferPosition = textLine.GetInsertionBufferPositionFromXCoordinate(xCoordinate); Affinity = textLine.IsLastTextViewLineForSnapshotLine || bufferPosition.Position != textLine.End ? PositionAffinity.Successor : PositionAffinity.Predecessor; if (filterPos) bufferPosition = FilterColumn(bufferPosition); SetExplicitPosition(bufferPosition); if (captureHorizontalPosition) preferredXCoordinate = Left; if (captureVerticalPosition) SavePreferredYCoordinate(); return Position; }
/// <summary> /// Get the caret x coordinate for a virtual buffer position. /// </summary> /// <remarks> /// The x coordinate is always on the trailing edge of the previous character, /// *unless* the supplied buffer position is the first character on the line or /// is in virtual space. /// </remarks> internal static double GetXCoordinateFromVirtualBufferPosition(ITextViewLine textLine, VirtualSnapshotPoint bufferPosition) { return((bufferPosition.IsInVirtualSpace || bufferPosition.Position == textLine.Start) ? textLine.GetExtendedCharacterBounds(bufferPosition).Leading : textLine.GetExtendedCharacterBounds(bufferPosition.Position - 1).Trailing); }
private void InternalMoveCaret(VirtualSnapshotPoint bufferPosition, PositionAffinity caretAffinity, ITextViewLine textLine, bool captureHorizontalPosition, bool captureVerticalPosition, bool raiseEvent) { CaretPosition oldPosition = this.Position; _caretAffinity = caretAffinity; _insertionPoint = bufferPosition; _forceVirtualSpace = _insertionPoint.IsInVirtualSpace && !this.IsVirtualSpaceOrBoxSelectionEnabled; _emptySelection = _wpfTextView.Selection.IsEmpty; _isContainedByView = (textLine.VisibilityState != VisibilityState.Unattached); double xCoordinate; double width; if (bufferPosition.IsInVirtualSpace || textLine.End == bufferPosition.Position) { //Never show overwrite caret when at the physical end of a line. this.OverwriteMode = false; } else { //Position is in the interior of the line ... preferred position is based strictly on the bufferPosition. this.OverwriteMode = _wpfTextView.Options.IsOverwriteModeEnabled() && _emptySelection; } // if we're in overwrite mode, draw a rectangle covering the text element, otherwise, just // draw a thin line if (_overwriteMode) { Microsoft.VisualStudio.Text.Formatting.TextBounds bounds = textLine.GetExtendedCharacterBounds(bufferPosition); xCoordinate = bounds.Left; width = bounds.Width; } else { xCoordinate = GetXCoordinateFromVirtualBufferPosition(textLine, bufferPosition); width = 10;//TODO: SystemParameters.CaretWidth; } _bounds = new SKRect((float)xCoordinate, (float)textLine.TextTop, (float)(xCoordinate + width), (float)textLine.TextBottom); CapturePreferredPositions(captureHorizontalPosition, captureVerticalPosition); CaretPosition newPosition = this.Position; if (newPosition != oldPosition) { this.UpdateBlinkTimer(); if (raiseEvent) { if (_selection.IsEmpty) { //Empty selections are logically located at the caret position, so force a selection changed event to be raised //before any of the caret position changed events. _selection.RaiseChangedEvent(emptyBefore: true, emptyAfter: true, moved: true); } // Inform this change to interested parties EventHandler <CaretPositionChangedEventArgs> positionChanged = this.PositionChanged; if (positionChanged != null) { _guardedOperations.RaiseEvent <CaretPositionChangedEventArgs>(this, positionChanged, new CaretPositionChangedEventArgs(_wpfTextView, oldPosition, newPosition)); } } } this.InvalidateVisual(); _updateNeeded = true; }