void CreateAndAddAdornment(ITextViewLine line, SnapshotSpan span, Brush brush, bool extendToRight) { var markerGeometry = _view.TextViewLines.GetMarkerGeometry(span); double left = 0; double width = _view.ViewportWidth + _view.MaxTextRightCoordinate; if (markerGeometry != null) { left = markerGeometry.Bounds.Left; if (!extendToRight) width = markerGeometry.Bounds.Width; } Rect rect = new Rect(left, line.Top, width, line.Height); RectangleGeometry geometry = new RectangleGeometry(rect); GeometryDrawing drawing = new GeometryDrawing(brush, new Pen(), geometry); drawing.Freeze(); DrawingImage drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); Image image = new Image(); image.Source = drawingImage; Canvas.SetLeft(image, geometry.Bounds.Left); Canvas.SetTop(image, geometry.Bounds.Top); _layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null); }
private void CreateVisuals(ITextViewLine line) { IWpfTextViewLineCollection textViewLines = _view.TextViewLines; SnapshotSpan span = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(line.Start, line.End)); if (span.GetText().IsMethodDefinition()) AddAdornmentToMethod(line, textViewLines, span); }
private UIElement GetPositionedCodeTag(ITextViewLine line, IWpfTextViewLineCollection textViewLines, Geometry geometry) { int lineNumber = _view.TextSnapshot.GetLineNumberFromPosition(line.Start.Position) + 1; UIElement codeTagElement = CodeLine.ElementAt(lineNumber, GetFilename); PlaceVisualNextToGeometry(geometry, codeTagElement); return codeTagElement; }
private void CreateVisuals(ITextViewLine line) { IWpfTextViewLineCollection textViewLines = view.TextViewLines; if ( textViewLines == null ) return; // not ready yet. SnapshotSpan span = line.Extent; Rect rc = new Rect( new Point(line.Left, line.Top), new Point(Math.Max(view.ViewportRight - 2, line.Right), line.Bottom) ); if ( NeedsNewImage(rc) ) { Geometry g = new RectangleGeometry(rc, 1.0, 1.0); GeometryDrawing drawing = new GeometryDrawing(fillBrush, borderPen, g); drawing.Freeze(); DrawingImage drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); Image image = new Image(); // work around WPF rounding bug image.UseLayoutRounding = false; image.Source = drawingImage; currentHighlight = image; } //Align the image with the top of the bounds of the text geometry Canvas.SetLeft(currentHighlight, rc.Left); Canvas.SetTop(currentHighlight, rc.Top); layer.AddAdornment( AdornmentPositioningBehavior.TextRelative, span, CUR_LINE_TAG, currentHighlight, null ); }
/// <summary> /// Within the given line add the scarlet box behind the a /// </summary> private void CreateVisuals(ITextViewLine line) { //grab a reference to the lines in the current TextView IWpfTextViewLineCollection textViewLines = _view.TextViewLines; int start = line.Start; int end = line.End; //Loop through each character, and place a box around any a for (int i = start; (i < end); ++i) { if (_view.TextSnapshot[i] == 'a') { SnapshotSpan span = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(i, i + 1)); Geometry g = textViewLines.GetMarkerGeometry(span); if (g != null) { GeometryDrawing drawing = new GeometryDrawing(_brush, _pen, g); drawing.Freeze(); DrawingImage drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); Image image = new Image(); image.Source = drawingImage; //Align the image with the top of the bounds of the text geometry Canvas.SetLeft(image, g.Bounds.Left); Canvas.SetTop(image, g.Bounds.Top); _layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null); } } } }
private void CreateVisuals(ITextViewLine line) { if ( !IsEnabled() ) { return; // not enabled } IWpfTextViewLineCollection textViewLines = view.TextViewLines; if ( textViewLines == null ) return; // not ready yet. SnapshotSpan span = line.Extent; Rect rc = new Rect( new Point(view.ViewportLeft, line.TextTop), new Point(Math.Max(view.ViewportRight - 2, line.TextRight), line.TextBottom) ); lineRect.Width = rc.Width; lineRect.Height = rc.Height; //Align the image with the top of the bounds of the text geometry Canvas.SetLeft(lineRect, rc.Left); Canvas.SetTop(lineRect, rc.Top); layer.AddAdornment( AdornmentPositioningBehavior.TextRelative, span, CUR_LINE_TAG, lineRect, null ); }
/// <summary> /// Store <paramref name="timeStamp"/> and updates the text for the visual. /// </summary> /// <param name="timeStamp">Time of the event.</param> /// <param name="line">The line that this time stamp corresponds to.</param> /// <param name="view">The <see cref="IWpfTextView"/> to whom the <paramref name="line"/> belongs.</param> /// <param name="formatting">Properties for the time stamp text.</param> /// <param name="marginWidth">Used to calculate the horizontal offset for <see cref="OnRender(DrawingContext)"/>.</param> /// <param name="verticalOffset">Used to calculate the vertical offset for <see cref="OnRender(DrawingContext)"/>.</param> /// <param name="showHours">Option to show hours on the time stamp.</param> /// <param name="showMilliseconds">Option to show milliseconds on the time stamp.</param> internal void UpdateVisual(DateTime timeStamp, ITextViewLine line, IWpfTextView view, TextRunProperties formatting, double marginWidth, double verticalOffset, bool showHours, bool showMilliseconds) { this.LineTag = line.IdentityTag; if (timeStamp != this.TimeStamp) { this.TimeStamp = timeStamp; string text = GetFormattedTime(timeStamp, showHours, showMilliseconds); TextFormattingMode textFormattingMode = view.FormattedLineSource.UseDisplayMode ? TextFormattingMode.Display : TextFormattingMode.Ideal; _text = new FormattedText(text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, formatting.Typeface, formatting.FontRenderingEmSize, formatting.ForegroundBrush, InvariantNumberSubstitution, textFormattingMode); _horizontalOffset = Math.Round(marginWidth - _text.Width); this.InvalidateVisual(); // force redraw } double newVerticalOffset = line.TextTop - view.ViewportTop + verticalOffset; if (newVerticalOffset != _verticalOffset) { _verticalOffset = newVerticalOffset; this.InvalidateVisual(); // force redraw } }
public void Draw(ITextViewLine line, Rect lineRect) { if (executionProvider.Running) return; if (line.LineNumber == executionProvider.Location.LineNumber - 1) Draw (lineRect); }
internal void Update( string text, ITextViewLine line, IWpfTextView view, TextRunProperties formatting, double marginWidth, double verticalOffset) { LineTag = line.IdentityTag; if (_text == null || !string.Equals(_text, text, StringComparison.Ordinal)) { _text = text; _formattedText = new FormattedText( _text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, formatting.Typeface, formatting.FontRenderingEmSize, formatting.ForegroundBrush); _horizontalOffset = Math.Round(marginWidth - _formattedText.Width); InvalidateVisual(); } var num = line.TextTop - view.ViewportTop + verticalOffset; // ReSharper disable once CompareOfFloatsByEqualityOperator if (num == _verticalOffset) return; _verticalOffset = num; InvalidateVisual(); }
/// <summary> /// Adds the adornment behind the "TODO"s within the given line /// </summary> /// <param name="line"></param> private void CreateVisuals(ITextViewLine line) { var textViewLines = _wpfTextView.TextViewLines; var text = line.Extent.GetText(); // TODO: Add support for block comments var todoRegex = new Regex(@"\/\/\s*TODO\b", RegexOptions.IgnoreCase); var match = todoRegex.Match(text); while (match.Success) { var matchStart = match.Index; var lineStart = line.Extent.Start.Position; var span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(matchStart + lineStart, matchStart + lineStart + match.Length)); DrawAdornment(textViewLines, span); match = match.NextMatch(); } // TODO: Evaluate the performance of below algo and RegEx /*// Loop through each character for (int charIndex = line.Start; charIndex < line.End; charIndex++) { // Check if the current letter is 'T' and the buffer is large enough so that a "TODO" may exist if (_wpfTextView.TextSnapshot[charIndex] == 'T' && charIndex + 4 < line.End) { // Get a string of 4 characters starting from the 'T' string snapshot = _wpfTextView.TextSnapshot.GetText(charIndex, 4); // Is the string a TODO? if (snapshot.Equals("TODO")) { SnapshotSpan span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(charIndex, charIndex + 4)); DrawAdornment(textViewLines, span); } } }*/ }
public LineTransform GetLineTransform(ITextViewLine line, double yPosition, ViewRelativePosition placement) { var transform = removeExtraTextLineVerticalPixels ? new LineTransform(0, 0, line.DefaultLineTransform.VerticalScale, line.DefaultLineTransform.Right) : line.DefaultLineTransform; foreach (var source in lineTransformSources) transform = LineTransform.Combine(transform, source.GetLineTransform(line, yPosition, placement)); return transform; }
public void Repaint(ITextViewLine line, Rect marginRect) { var breakpoint = GetBreakpoint (line); if (breakpoint != null) Draw (marginRect, breakpointProvider.IsBound (breakpoint), breakpoint.Enabled ); }
MouseLocation(ITextViewLine textViewLine, VirtualSnapshotPoint position, Point point) { if (textViewLine == null) throw new ArgumentNullException(nameof(textViewLine)); TextViewLine = textViewLine; Position = position; Affinity = textViewLine.IsLastTextViewLineForSnapshotLine || position.Position != textViewLine.End ? PositionAffinity.Successor : PositionAffinity.Predecessor; Debug.Assert(position.VirtualSpaces == 0 || Affinity == PositionAffinity.Successor); Point = point; }
public VirtualSnapshotSpan GetSpan(ITextViewLine line) { if (textSelection.TextView.TextSnapshot != textSnapshot) throw new InvalidOperationException(); var start = line.GetInsertionBufferPositionFromXCoordinate(xLeft); var end = line.GetInsertionBufferPositionFromXCoordinate(xRight); if (start <= end) return new VirtualSnapshotSpan(start, end); return new VirtualSnapshotSpan(end, start); }
private void AddAdornmentToMethod(ITextViewLine line, IWpfTextViewLineCollection textViewLines, SnapshotSpan span) { Geometry geometry = textViewLines.GetMarkerGeometry(span); if (geometry != null) { UIElement codeTagElement = GetPositionedCodeTag(line, textViewLines, geometry); _layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, codeTagElement, null); } }
public void Repaint(ITextViewLine line, Rect marginRect) { if (Event.current.type != EventType.repaint) return; var orgColor = GUI.color; GUI.color = _appearance.LineNumberColor; _appearance.LineNumber.Draw(marginRect, (line.LineNumber + 1).ToString(), false, false, false, false); GUI.color = orgColor; }
public void HandleInputEvent(ITextViewLine line, Rect marginRect) { if (Event.current.type != EventType.mouseDown) return; if (!marginRect.Contains(Event.current.mousePosition)) return; SetBreakPoint(line); }
protected override int? GetLineNumber(ITextViewLine viewLine, ref LineNumberState state) { if (!viewLine.IsFirstTextViewLineForSnapshotLine) return null; if (state == null) state = new LineNumberState(); if (state.SnapshotLine == null || state.SnapshotLine.EndIncludingLineBreak != viewLine.Start) state.SnapshotLine = viewLine.Start.GetContainingLine(); else state.SnapshotLine = state.SnapshotLine.Snapshot.GetLineFromLineNumber(state.SnapshotLine.LineNumber + 1); return state.SnapshotLine.LineNumber + 1; }
private void CreateVisuals(ITextViewLine line, IList<VariableDeclaratorSyntax> fields, IList<VariableDeclaratorSyntax> fieldsThatShouldBeReadOnly) { IWpfTextViewLineCollection textViewLines = this.view.TextViewLines; var fieldsOnThisLine = fields.Where(f => f.FullSpan.IntersectsWith(new TextSpan(line.Start.Position, line.Length))); foreach (var field in fieldsOnThisLine) { if (fieldsThatShouldBeReadOnly.Contains(field) && !this.layer.Elements.Any(e => AdornmentTagFor(field).Equals(e.Tag))) { var startIndex = field.FullSpan.Start; SnapshotSpan span = new SnapshotSpan(this.view.TextSnapshot, Span.FromBounds(startIndex, startIndex + field.FullSpan.Length)); var geometry = textViewLines.GetMarkerGeometry(span); if (geometry != null) { var drawing = new GeometryDrawing(this.brush, this.pen, geometry); drawing.Freeze(); var drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); var image = new Image { Source = drawingImage, }; // If you're going to torment your colleagues, torment them good and hard image.BeginAnimation(Image.VisibilityProperty, new ObjectAnimationUsingKeyFrames { Duration = new Duration(TimeSpan.FromSeconds(1)), RepeatBehavior = RepeatBehavior.Forever, KeyFrames = new ObjectKeyFrameCollection { new DiscreteObjectKeyFrame(Visibility.Visible, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.0))), new DiscreteObjectKeyFrame(Visibility.Hidden, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5))), }, }); // Align the image with the top of the bounds of the text geometry Canvas.SetLeft(image, geometry.Bounds.Left); Canvas.SetTop(image, geometry.Bounds.Top); this.layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, AdornmentTagFor(field), image, null); } } else { this.layer.RemoveAdornmentsByTag(AdornmentTagFor(field)); } } }
private void DoAddAdornment(ITextViewLine line, Rect area) { IWpfTextViewLineCollection textViewLines = m_view.TextViewLines; // Align the image with the top of the bounds of the text geometry Canvas.SetLeft(m_adornment, area.Left); Canvas.SetTop(m_adornment, area.Top); m_layer.AddAdornment( AdornmentPositioningBehavior.TextRelative, line.Extent, AdornmentName, m_adornment, null); }
internal static int GetStartPositionAfterLines(this ITextView textView, ITextViewLine line, int currentLineDifference) { var lineNumber = textView.TextBuffer.GetLineNumber(line.Start) + currentLineDifference; if (lineNumber >= textView.TextBuffer.CurrentSnapshot.LineCount) { lineNumber = textView.TextBuffer.CurrentSnapshot.LineCount - 1; } var currentLine = textView.TextSnapshot.GetLineFromLineNumber(lineNumber); return currentLine.Start.Position; }
public LineTransform GetLineTransform(ITextViewLine line, double yPosition, ViewRelativePosition placement) { foreach (IAdornment adornment in this.adornments) { if (line.ContainsBufferPosition(new SnapshotPoint(line.Snapshot, adornment.Span.GetStartPoint(line.Snapshot).Position))) { //if (adornment.Visual.IsMeasureValid) { // adornment.ShouldRedrawAdornmentLayout = false; //} return new LineTransform(adornment.Visual.DesiredSize.Height, 0.0, 1.0); } } return new LineTransform(0, 0, 1); }
protected override int? GetLineNumber(ITextViewLine viewLine, ref LineNumberState state) { if (owner == null) return null; CustomLineNumberState customState; if (state == null) state = customState = new CustomLineNumberState(); else customState = (CustomLineNumberState)state; if (state.SnapshotLine == null || state.SnapshotLine.EndIncludingLineBreak != viewLine.Start) state.SnapshotLine = viewLine.Start.GetContainingLine(); else state.SnapshotLine = state.SnapshotLine.Snapshot.GetLineFromLineNumber(state.SnapshotLine.LineNumber + 1); return owner.GetLineNumber(viewLine, state.SnapshotLine, ref customState.State); }
/// <summary> /// Highlighs the text line /// </summary> /// <param name="textLine">The text line</param> internal void Highlight(ITextViewLine textLine) { if (textLine != null) { this.visualElement.Visibility = Visibility.Visible; // Set the position of the visual element this.visualElement.Height = textLine.Height; this.visualElement.Width = this.View.ViewportWidth; Canvas.SetLeft(this.visualElement, this.View.ViewportLeft); Canvas.SetTop(this.visualElement, textLine.Top + textLine.LineTransform.TopSpace); } else { this.Clear(); } }
LineTransform ILineTransformSource.GetLineTransform(ITextViewLine line, double yPosition, ViewRelativePosition placement) { IEnumerable<ImageAdornment> targetImages = this.manager.Images .Where(imageAdornment => imageAdornment.ApplyRenderTrackingPoint(this.manager.View.TextSnapshot, line)); if (targetImages.Count() > 0) { ImageAdornment imageAdornmentWithMaxHeight = targetImages .OrderByDescending(imageAdornment => imageAdornment.VisualElement.Height) .FirstOrDefault(); return new LineTransform(imageAdornmentWithMaxHeight.VisualElement.Height + ImageAdornmentSpacePadding, 0, 1.0); } return new LineTransform(0, 0, 1.0); }
/// <summary> /// Determine the size of a particular line, based on distance from caret /// </summary> /// <param name="line">The position of the line currently being modified </param> /// <param name="yPosition">Unused data type left over from base.GetLineTransform() </param> /// <param name="placement">Unused data type left over from base.GetLineTransform() </param> /// <returns>LineTransform object containing the desired scale value for the line</returns> public LineTransform GetLineTransform(ITextViewLine line, double yPosition, ViewRelativePosition placement) { //Vertically compress lines that are far from the caret (based on buffer lines, not view lines). int caretLineNumber = _textView.TextSnapshot.GetLineNumberFromPosition(_textView.Caret.Position.BufferPosition); int lineNumber = _textView.TextSnapshot.GetLineNumberFromPosition(line.Start); int delta = Math.Abs(caretLineNumber - lineNumber); double scale; if (delta <= 1) scale = 1.0; else if (delta <= 3) scale = 1.0 - ((delta - 3)) * 0.05; else if (delta <= 8) scale = 0.75 - ((delta - 8)) * 0.025; else scale = 0.5; return new LineTransform(0.0, 0.0, scale); }
/// <summary> /// Within the given line add the scarlet box behind the a /// </summary> private void CreateVisuals(ITextViewLine line) { // Grab a reference to the lines in the current TextView IWpfTextViewLineCollection textViewLines = textView.TextViewLines; int start = line.Start; int end = line.End; List<Geometry> geometries = new List<Geometry>(); var keywordFirstLetters = keywordFormats.Keys .Select(k => k[0]) .Distinct() .ToArray(); // Loop through each character and place a box around any registered keyword for (int i = start; i < end; i++) { if (keywordFirstLetters.Contains(textView.TextSnapshot[i])) // Performance optimisation { foreach (var kvp in keywordFormats) { string keyword = kvp.Key; if (textView.TextSnapshot[i] == keyword[0] && // Performance optimisation i <= end - keyword.Length && textView.TextSnapshot.GetText(i, keyword.Length) == keyword) { SnapshotSpan span = new SnapshotSpan(textView.TextSnapshot, Span.FromBounds(i, i + keyword.Length)); Geometry markerGeometry = textViewLines.GetMarkerGeometry(span); if (markerGeometry != null) { if (!geometries.Any(g => g.FillContainsWithDetail(markerGeometry) > IntersectionDetail.Empty)) { geometries.Add(markerGeometry); AddMarker(span, markerGeometry, kvp.Value); } } } } } } }
private Geometry BuildLineGeometry(SnapshotSpan span, ITextViewLine line) { double left, top, right, bottom; if ( line.ContainsBufferPosition(span.Start) ) { var bounds = line.GetCharacterBounds(span.Start); left = bounds.Left; top = line.TextTop; } else { left = line.Left; top = line.Top; } if ( line.ContainsBufferPosition(span.End) ) { var bounds = line.GetCharacterBounds(span.End); right = bounds.Right; bottom = line.TextBottom + 1; } else { right = Math.Max(line.Right, this.view.ViewportRight - 1); bottom = line.Bottom; } return new RectangleGeometry(new Rect(left, top, right-left, bottom-top)); }
public LineTransform GetLineTransform(ITextViewLine line, double yPosition, ViewRelativePosition placement) { if (!compressEmptyOrWhitespaceLines && !compressNonLetterLines) return new LineTransform(0, 0, 1, 0); if (!line.IsFirstTextViewLineForSnapshotLine && !line.IsLastTextViewLineForSnapshotLine) return new LineTransform(0, 0, 1, 0); switch (GetLineType(line)) { case LineKind.Normal: return new LineTransform(0, 0, 1, 0); case LineKind.EmptyOrWhitespace: if (compressEmptyOrWhitespaceLines) return new LineTransform(0, 0, SCALE, 0); return new LineTransform(0, 0, 1, 0); case LineKind.NoLettersDigits: if (compressNonLetterLines) return new LineTransform(0, 0, SCALE, 0); return new LineTransform(0, 0, 1, 0); default: throw new InvalidOperationException(); } }
LineTransform ILineTransformSource.GetLineTransform(ITextViewLine line, double yPosition, ViewRelativePosition placement) { #pragma warning disable 219 bool imageOnLine = false; // useful for tracing #pragma warning restore 219 int lineNumber = line.Snapshot.GetLineFromPosition(line.Start.Position).LineNumber; LineTransform lineTransform; // Look up Image for current line and increase line height as necessary if (_manager.Images.ContainsKey(lineNumber) && ImageAdornmentManager.Enabled) { double defaultHeight = line.DefaultLineTransform.BottomSpace; MyImage image = _manager.Images[lineNumber]; lineTransform = new LineTransform(0, image.Height + defaultHeight, 1.0); imageOnLine = true; } else { lineTransform = new LineTransform(0, 0, 1.0); } return lineTransform; }
protected abstract TextFormattingRunProperties GetLineNumberTextFormattingRunProperties(ITextViewLine viewLine, LineNumberState state, int lineNumber);
public void MoveCaret(ITextViewLine textLine, double horizontalOffset, bool extendSelection) => EditorOperations.MoveCaret(textLine, horizontalOffset, extendSelection);
/// <summary> /// Scans text line for matching image comment signature, then adds new or updates existing image adornment /// </summary> private void CreateVisuals(ITextViewLine line, int lineNumber) { #pragma warning disable 219 bool imageDetected = false; // useful for tracing #pragma warning restore 219 string lineText = line.Extent.GetText(); string matchedText; int matchIndex = ImageCommentParser.Match(_contentTypeName, lineText, out matchedText); if (matchIndex >= 0) { // Get coordinates of text int start = line.Extent.Start.Position + matchIndex; int end = line.Start + (line.Extent.Length - 1); var span = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(start, end)); Exception xmlParseException; string imageUrl; double scale; Color bgColor = new Color(); ImageCommentParser.TryParse(matchedText, out imageUrl, out scale, ref bgColor, out xmlParseException); if (xmlParseException != null) { if (Images.ContainsKey(lineNumber)) { _layer.RemoveAdornment(Images[lineNumber]); Images.Remove(lineNumber); } _errorTags.Add(new TagSpan <ErrorTag>(span, new ErrorTag("XML parse error", GetErrorMessage(xmlParseException)))); return; } MyImage image; Exception imageLoadingException = null; // Check for and update existing image MyImage existingImage = Images.ContainsKey(lineNumber) ? Images[lineNumber] : null; if (existingImage != null) { image = existingImage; if (existingImage.Url != imageUrl) // URL different, so set new source { existingImage.TrySet(imageUrl, scale, bgColor, out imageLoadingException, () => CreateVisuals(line, lineNumber)); if (image.BgColor != null) { image.BgColor.R = 254; } } } else // No existing image, so create new one { image = new MyImage(_variableExpander); image.TrySet(imageUrl, scale, bgColor, out imageLoadingException, () => CreateVisuals(line, lineNumber)); if (image.BgColor != null) { image.BgColor.R = 254; } Images.Add(lineNumber, image); } // Position image and add as adornment if (imageLoadingException == null) { try { _layer.RemoveAdornment(image); } catch (Exception ex) { // No expected exceptions, so tell user something is wrong. ExceptionHandler.Notify(ex, true); } if ((image.Source as BitmapFrame)?.IsDownloading ?? false) { (image.Source as BitmapFrame).DownloadCompleted += (x, y) => { if (x == image.Source) { ShowDownloadedImage(line, span, bgColor, image); } }; } else { ShowDownloadedImage(line, span, bgColor, image); } } else { if (Images.ContainsKey(lineNumber)) { Images.Remove(lineNumber); } _errorTags.Add(new TagSpan <ErrorTag>(span, new ErrorTag("Trouble loading image", GetErrorMessage(imageLoadingException)))); } imageDetected = true; } else { if (Images.ContainsKey(lineNumber)) { Images.Remove(lineNumber); } } }
public void SelectLine(ITextViewLine viewLine, bool extendSelection) { throw new NotImplementedException(); }
public bool Contains(ITextViewLine item) { return(item.Snapshot == Snapshot); }
public CaretPosition MoveTo(ITextViewLine textLine, double xCoordinate) { throw new NotImplementedException(); }
CaretPosition ITextCaret.MoveTo(ITextViewLine textLine, double xCoordinate, bool captureHorizontalPosition) { Line = textLine.Start; // TODO: xCoordinate - is that just visual or does it have an impact on the column ? return(((ITextCaret)this).Position); }
public LineInfo(ITextViewLine textViewLine, List <IconInfo> icons) { Line = textViewLine ?? throw new ArgumentNullException(nameof(textViewLine)); Icons = icons ?? throw new ArgumentNullException(nameof(icons)); }
private bool LineIntersectsSpan(ITextViewLine line, SnapshotSpan span) { return(line.ContainsBufferPosition(span.Start) || line.ContainsBufferPosition(span.End) || line.Start >= span.Start); }
public int GetIndexOfTextLine(ITextViewLine textLine) { throw new NotImplementedException(); }
void UpdateAdornments_Performance( ITextSnapshot snapshot, ITextViewModel viewModel, ITextViewLine firstVisibleLine, IEnumerable <LineSpan> analysisLines ) { #endif double spaceWidth = firstVisibleLine.VirtualSpaceWidth; if (spaceWidth <= 0.0) { return; } double horizontalOffset = firstVisibleLine.TextLeft; HashSet <LineSpan> unusedLines = new HashSet <LineSpan>(Lines.Keys); CaretHandlerBase caret = CaretHandlerBase.FromName(Theme.CaretHandler, View.Caret.Position.VirtualBufferPosition, Analysis.TabSize); object perfCookie = null; PerformanceLogger.Start(ref perfCookie); #if DEBUG int initialCount = Lines.Count; #endif foreach (LineSpan line in analysisLines.Concat(GetPageWidthLines())) { double top = View.ViewportTop; double bottom = View.ViewportBottom; double left = line.Indent * spaceWidth + horizontalOffset; Line adornment; unusedLines.Remove(line); if (line.Type == LineSpanType.PageWidthMarker) { line.Highlight = Analysis.LongestLine > line.Indent; if (!Lines.TryGetValue(line, out adornment)) { Lines[line] = adornment = CreateGuide(Canvas); } UpdateGuide(line, adornment, left, top, bottom); continue; } if (Lines.TryGetValue(line, out adornment)) { adornment.Visibility = Visibility.Hidden; } caret.AddLine(line, true); if (line.FirstLine >= 0 && line.LastLine < int.MaxValue) { int firstLineNumber = line.FirstLine; int lastLineNumber = line.LastLine; ITextSnapshotLine firstLine, lastLine; try { firstLine = snapshot.GetLineFromLineNumber(firstLineNumber); lastLine = snapshot.GetLineFromLineNumber(lastLineNumber); } catch (Exception ex) { Trace.TraceError("In GetLineFromLineNumber:\n{0}", ex); continue; } if (firstLine.Start > View.TextViewLines.LastVisibleLine.Start || lastLine.Start < View.TextViewLines.FirstVisibleLine.Start) { continue; } while ( !viewModel.IsPointInVisualBuffer(firstLine.Start, PositionAffinity.Successor) && ++firstLineNumber < lastLineNumber ) { try { firstLine = snapshot.GetLineFromLineNumber(firstLineNumber); } catch (Exception ex) { Trace.TraceError("In GetLineFromLineNumber:\n{0}", ex); firstLine = null; break; } } while ( !viewModel.IsPointInVisualBuffer(lastLine.Start, PositionAffinity.Predecessor) && --lastLineNumber > firstLineNumber ) { try { lastLine = snapshot.GetLineFromLineNumber(lastLineNumber); } catch (Exception ex) { Trace.TraceError("In GetLineFromLineNumber:\n{0}", ex); lastLine = null; break; } } if (firstLine == null || lastLine == null || firstLineNumber > lastLineNumber) { continue; } IWpfTextViewLine firstView, lastView; try { firstView = View.GetTextViewLineContainingBufferPosition(firstLine.Start); lastView = View.GetTextViewLineContainingBufferPosition(lastLine.End); } catch (Exception ex) { Trace.TraceError("UpdateAdornments GetTextViewLineContainingBufferPosition failed\n{0}", ex); continue; } string extentText; if (!string.IsNullOrWhiteSpace(extentText = firstView.Extent.GetText()) && line.Indent > extentText.LeadingWhitespace(Analysis.TabSize) ) { continue; } if (firstView.VisibilityState != VisibilityState.Unattached) { top = firstView.Top; } if (lastView.VisibilityState != VisibilityState.Unattached) { bottom = lastView.Bottom; } } if (!Lines.TryGetValue(line, out adornment)) { Lines[line] = adornment = CreateGuide(Canvas); } UpdateGuide(line, adornment, left, top, bottom); } PerformanceLogger.End(perfCookie); #if DEBUG Debug.WriteLine("Added {0} guides", Lines.Count - initialCount); Debug.WriteLine("Removed {0} guides", unusedLines.Count); Debug.WriteLine("{0} guides active", Lines.Count - unusedLines.Count); Debug.WriteLine(""); #endif foreach (LineSpan line in unusedLines) { Line adornment; if (Lines.TryGetValue(line, out adornment)) { Canvas.Children.Remove(adornment); Lines.Remove(line); } } foreach (LineSpan line in caret.GetModified()) { Line adornment; if (Lines.TryGetValue(line, out adornment)) { UpdateGuide(line, adornment); } } }
private void UpdateAdornmentsWorker() { //var analysisLines = Analysis.Lines; //if (Analysis.Snapshot != View.TextSnapshot) { // var task = Analysis.Update(); // if (task != null) { // UpdateAdornments(task); // } // return; //} else if (analysisLines == null) { // UpdateAdornments(Analysis.Reset()); // return; //} if (!GlobalVisible) { Canvas.Visibility = Visibility.Collapsed; return; } Canvas.Visibility = Visibility.Visible; ITextSnapshot snapshot = View.TextSnapshot; ITextViewModel viewModel = View.TextViewModel; if (snapshot == null || viewModel == null) { return; } ITextViewLine firstVisibleLine = View.TextViewLines.FirstOrDefault(line => line.IsFirstTextViewLineForSnapshotLine); if (firstVisibleLine == null) { return; } ITextViewLine lastVisibleLine = View.TextViewLines.LastOrDefault(line => line.IsLastTextViewLineForSnapshotLine); if (lastVisibleLine == null) { return; } IEnumerable <LineSpan> analysisLines = Analysis.GetLines( firstVisibleLine.Start.GetContainingLine().LineNumber, lastVisibleLine.Start.GetContainingLine().LineNumber ); if (!analysisLines.Any()) { return; } #if PERFORMANCE object cookie = null; try { PerformanceLogger.Start(ref cookie); UpdateAdornments_Performance( snapshot, viewModel, firstVisibleLine, analysisLines ); } catch (OperationCanceledException) { PerformanceLogger.Mark("Cancel"); throw; } finally { PerformanceLogger.End(cookie); } }
public bool Remove(ITextViewLine item) { throw new NotImplementedException(); }
public int IndexOf(ITextViewLine item) { throw new NotImplementedException(); }
public void HandleInputEvent(ITextViewLine line, Rect marginRect) { }
public static bool TryGetClosestTextViewLine(this ITextView textView, double yCoordinate, out ITextViewLine closestLine) { if (textView == null) { throw new ArgumentNullException(nameof(textView)); } if (textView.IsClosed || textView.InLayout) { closestLine = null; return(false); } ITextViewLine textLine = null; ITextViewLineCollection textLines = textView.TextViewLines; if (textLines != null && textLines.Count > 0) { textLine = textLines.GetTextViewLineContainingYCoordinate(yCoordinate); if (textLine == null) { if (yCoordinate <= textLines.FirstVisibleLine.Bottom) { textLine = textLines.FirstVisibleLine; } else if (yCoordinate >= textLines.LastVisibleLine.Top) { textLine = textLines.LastVisibleLine; } } closestLine = textLine; return(true); } closestLine = null; return(false); }
public void Add(ITextViewLine item) { throw new NotImplementedException(); }
public void MoveCaret(ITextViewLine textLine, double horizontalOffset, bool extendSelection) { throw new NotImplementedException(); }
public void Insert(int index, ITextViewLine item) { throw new NotImplementedException(); }
void IEditorOperations.SelectLine(ITextViewLine viewLine, bool extendSelection) { throw new NotImplementedException(); }
CaretPosition ITextCaret.MoveTo(ITextViewLine textLine) { Line = textLine.Start; return(((ITextCaret)this).Position); }
public CaretPosition MoveTo(ITextViewLine textLine, double xCoordinate, bool captureHorizontalPosition) { throw new NotImplementedException(); }
/// <summary> /// Scans text line for matching image comment signature, then adds new or updates existing image adornment /// </summary> private void CreateVisuals(ITextViewLine line, int lineNumber) { #pragma warning disable 219 bool imageDetected = false; // useful for tracing #pragma warning restore 219 ThreadHelper.ThrowIfNotOnUIThread(); string lineText = line.Extent.GetText(); string matchedText; int matchIndex = ImageCommentParser.Match(_contentTypeName, lineText, out matchedText); if (matchIndex >= 0) { // Get coordinates of text int start = line.Extent.Start.Position + matchIndex; int end = line.Start + (line.Extent.Length - 1); var span = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(start, end)); Exception xmlParseException; string imageUrl; double scale; Color bgColor = new Color(); ImageCommentParser.TryParse(matchedText, out imageUrl, out scale, ref bgColor, out xmlParseException); if (xmlParseException != null) { if (Images.ContainsKey(lineNumber)) { _layer.RemoveAdornment(Images[lineNumber]); Images.Remove(lineNumber); } _errorTags.Add(new TagSpan <ErrorTag>(span, new ErrorTag("XML parse error", GetErrorMessage(xmlParseException)))); return; } MyImage image; Exception imageLoadingException = null; // Check for and update existing image MyImage existingImage = Images.ContainsKey(lineNumber) ? Images[lineNumber] : null; if (existingImage != null) { image = existingImage; if (existingImage.Url != imageUrl || existingImage.BgColor != bgColor) // URL different, so set new source { existingImage.TrySet(imageUrl, scale, bgColor, out imageLoadingException, () => CreateVisuals(line, lineNumber)); } else if (existingImage.Url == imageUrl && Math.Abs(existingImage.Scale - scale) > 0.0001) // URL same but scale changed { existingImage.Scale = scale; } } else // No existing image, so create new one { image = new MyImage(_variableExpander); image.TrySet(imageUrl, scale, bgColor, out imageLoadingException, () => CreateVisuals(line, lineNumber)); Images.Add(lineNumber, image); } // Position image and add as adornment if (imageLoadingException == null) { Geometry g = _view.TextViewLines.GetMarkerGeometry(span); if (g == null) // Exceptional case when image dimensions are massive (e.g. specifying very large scale factor) { throw new InvalidOperationException("Couldn't get source code line geometry. Is the loaded image massive?"); } double textLeft = g.Bounds.Left; double textBottom = line.TextBottom; Canvas.SetLeft(image, textLeft); Canvas.SetTop(image, textBottom); // Add image to editor view try { _layer.RemoveAdornment(image); _layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, line.Extent, null, image, null); } catch (Exception ex) { // No expected exceptions, so tell user something is wrong. ExceptionHandler.Notify(ex, true); } } else { if (Images.ContainsKey(lineNumber)) { Images.Remove(lineNumber); } _errorTags.Add(new TagSpan <ErrorTag>(span, new ErrorTag("Trouble loading image", GetErrorMessage(imageLoadingException)))); } imageDetected = true; } else { if (Images.ContainsKey(lineNumber)) { Images.Remove(lineNumber); } } }
public CaretPosition MoveTo(ITextViewLine textLine) => MoveTo(textLine, preferredXCoordinate, false, true, true);
private void AddLineResultAdornment(ITextViewLine line, SnapshotSpan span, LineResult[] lineResults) { if (lineResults.Length > 0) { var geometry = Geometry.Parse("F1M9.4141,8L12.4141,11 11.0001,12.414 8.0001,9.414 5.0001,12.414 3.5861,11 6.5861,8 3.5861,5 5.0001,3.586 8.0001,6.586 11.0001,3.586 12.4141,5z"); geometry.Freeze(); var drawing = new GeometryDrawing(lineResults.Any(p => p.IsPrimary) ? _exceptionOriginBrushAndPen.Brush : _exceptionTraceBrushAndPen.Brush, null, geometry); drawing.Freeze(); var drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); var toolTip = new StackPanel() { MaxWidth = 600 }; foreach (var group in lineResults.GroupBy(p => p.ErrorMessage)) { var header = new TextBlock() { Text = string.Join(Environment.NewLine, group.Select(p => p.TestMethod.ShortName).Distinct()), TextWrapping = TextWrapping.Wrap }; var description = new TextBlock() { Text = group.Key, TextWrapping = TextWrapping.Wrap, Opacity = 0.7d, Margin = new Thickness(0, 0, 0, 10) }; toolTip.Children.Add(header); toolTip.Children.Add(description); } toolTip.Children.OfType <TextBlock>().Last().Margin = new Thickness(); var viewBox = new Viewbox() { Width = _textView.LineHeight, Height = _textView.LineHeight, Stretch = Stretch.Uniform }; var button = new ActionButton() { Icon = drawingImage, CommandParameter = lineResults.FirstOrDefault().TestMethod, Command = _selectTestCommand, ToolTip = toolTip, Cursor = Cursors.Hand, Tag = lineResults.Select(p => p.TestMethod).ToArray() }; button.MouseRightButtonDown += (o, e) => e.Handled = true; button.MouseRightButtonUp += OnTestCoverageRightButtonUp; viewBox.Child = button; Canvas.SetLeft(viewBox, _sequenceCoverageLineWidth); Canvas.SetTop(viewBox, line.Top); _adornmentLayer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, viewBox, null); } }
public CaretPosition MoveTo(ITextViewLine textLine, double xCoordinate) => MoveTo(textLine, xCoordinate, true, true, true);
public CaretPosition MoveTo(ITextViewLine textLine, double xCoordinate, bool captureHorizontalPosition) => MoveTo(textLine, xCoordinate, captureHorizontalPosition, true, true);
protected abstract int?GetLineNumber(ITextViewLine viewLine, ref LineNumberState state);
public bool TryGetTextViewLineContainingBufferPosition(SnapshotPoint bufferPosition, out ITextViewLine textViewLine) => _innerTextView.TryGetTextViewLineContainingBufferPosition(bufferPosition, out textViewLine);
public void SelectLine(ITextViewLine viewLine, bool extendSelection) => //TODO: If in a code buffer, don't select the prompt EditorOperations.SelectLine(viewLine, extendSelection);