/// <inheritdoc/> protected override void OnRender(DrawingContext drawingContext) { if (!TextView.VisualLinesValid) { return; } if (TextView.VisualLines.Count == 0 || FoldingManager == null) { return; } Pen grayPen = new Pen(Brushes.Gray, 1); grayPen.Freeze(); Pen blackPen = new Pen(Brushes.Black, 1); blackPen.Freeze(); var allTextLines = TextView.VisualLines.SelectMany(vl => vl.TextLines).ToList(); Pen[] colors = new Pen[allTextLines.Count + 1]; Pen[] endMarker = new Pen[allTextLines.Count]; int viewStartOffset = TextView.VisualLines[0].FirstDocumentLine.Offset; DocumentLine lastVisibleLine = TextView.VisualLines.Last().LastDocumentLine; int viewEndOffset = lastVisibleLine.Offset + lastVisibleLine.Length; var foldings = FoldingManager.GetFoldingsContaining(viewStartOffset); int maxEndOffset = 0; foreach (FoldingSection fs in foldings) { int end = fs.EndOffset; if (end < viewEndOffset && !fs.IsFolded) { int textLineNr = GetTextLineIndexFromOffset(allTextLines, end); if (textLineNr >= 0) { endMarker[textLineNr] = grayPen; } } if (end > maxEndOffset && fs.StartOffset < viewStartOffset) { maxEndOffset = end; } } if (maxEndOffset > 0) { if (maxEndOffset > viewEndOffset) { for (int i = 0; i < colors.Length; i++) { colors[i] = grayPen; } } else { int maxTextLine = GetTextLineIndexFromOffset(allTextLines, maxEndOffset); for (int i = 0; i <= maxTextLine; i++) { colors[i] = grayPen; } } } foreach (FoldingMarginMarker marker in markers) { int end = marker.FoldingSection.EndOffset; int endTextLineNr = GetTextLineIndexFromOffset(allTextLines, end); if (!marker.FoldingSection.IsFolded && endTextLineNr >= 0) { if (marker.IsMouseDirectlyOver) { endMarker[endTextLineNr] = blackPen; } else if (endMarker[endTextLineNr] == null) { endMarker[endTextLineNr] = grayPen; } } int startTextLineNr = GetTextLineIndexFromOffset(allTextLines, marker.FoldingSection.StartOffset); if (startTextLineNr >= 0) { for (int i = startTextLineNr + 1; i < colors.Length && i - 1 != endTextLineNr; i++) { if (marker.IsMouseDirectlyOver) { colors[i] = blackPen; } else if (colors[i] == null) { colors[i] = grayPen; } } } } double markerXPos = Math.Round(RenderSize.Width / 2); double startY = 0; Pen currentPen = colors[0]; int tlNumber = 0; foreach (VisualLine vl in TextView.VisualLines) { foreach (TextLine tl in vl.TextLines) { if (endMarker[tlNumber] != null) { double visualPos = GetVisualPos(vl, tl); drawingContext.DrawLine(endMarker[tlNumber], new Point(markerXPos, visualPos), new Point(RenderSize.Width, visualPos)); } if (colors[tlNumber + 1] != currentPen) { double visualPos = GetVisualPos(vl, tl); if (currentPen != null) { drawingContext.DrawLine(currentPen, new Point(markerXPos, startY), new Point(markerXPos, visualPos)); } currentPen = colors[tlNumber + 1]; startY = visualPos; } tlNumber++; } } if (currentPen != null) { drawingContext.DrawLine(currentPen, new Point(markerXPos, startY), new Point(markerXPos, RenderSize.Height)); } base.OnRender(drawingContext); }
internal FoldingSection(FoldingManager manager, int startOffset, int endOffset) { this.manager = manager; this.StartOffset = startOffset; this.Length = endOffset - startOffset; }