void AddLineElements(NormalizedSnapshotSpanCollection spans)
        {
            if (spans.Count == 0)
            {
                return;
            }
            var list    = new List <StructureVisualizerData>();
            var updated = new HashSet <StructureVisualizerData>(StructureVisualizerDataComparer.Instance);

            foreach (var span in spans)
            {
                list.Clear();
                structureVisualizerServiceDataProvider.GetData(GetLineExtent(span), list);

                foreach (var info in list)
                {
                    if (updated.Contains(info))
                    {
                        continue;
                    }
                    updated.Add(info);

                    var lineElement = FindLineElement(info);
                    if (lineElement != null)
                    {
                        layer.RemoveAdornment(lineElement);
                        Debug.Assert(!lineElements.Contains(lineElement));
                    }
                    if (lineElement == null)
                    {
                        lineElement = new LineElement(info);
                    }

                    var lines = wpfTextView.TextViewLines.GetTextViewLinesIntersectingSpan(lineElement.Span);
                    if (lines.Count == 0)
                    {
                        continue;
                    }

                    int lineStartIndex = 0;
                    int lineEndIndex   = lines.Count - 1;

                    // Don't add a vertical line to the line containing the start or end block
                    if (LineContainsSpan(info.Top, lines[lineStartIndex]))
                    {
                        lineStartIndex++;
                    }
                    if (LineContainsSpan(info.Bottom, lines[lineEndIndex]))
                    {
                        lineEndIndex--;
                    }

                    if (lineStartIndex > lineEndIndex)
                    {
                        continue;
                    }

                    double top    = lines[lineStartIndex].Top;
                    double bottom = lines[lineEndIndex].Bottom;
                    if (bottom - top < 0.5)
                    {
                        continue;
                    }
                    double x   = GetLineXPosition(info);
                    var    pen = GetPen(info.BlockKind);
                    lineElement.Update(x, bottom, top, pen);

                    bool added = layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, lineElement.Span, null, lineElement, onRemovedDelegate);
                    if (added)
                    {
                        lineElements.Add(lineElement);
                    }
                }
            }
        }
Example #2
0
        IEnumerable <LineElementData> GetLineElementData(NormalizedSnapshotSpanCollection spans)
        {
            if (spans.Count == 0)
            {
                yield break;
            }
            var snapshot = spans[0].Snapshot;
            ITextSnapshotLine snapshotLine = null;
            SnapshotSpan      lineExtent;
            var prevLineExtent = default(SnapshotSpan);
            var list           = new List <StructureVisualizerData>();

            StructureVisualizerData[] listArray = null;
            List <ITextViewLine>      linesList = null;

            foreach (var span in spans)
            {
                var lines = GetTextViewLinesIntersectingSpan(span, ref linesList);
                foreach (var line in lines)
                {
                    if (snapshotLine != null)
                    {
                        if (line.Start >= snapshotLine.Start && line.EndIncludingLineBreak <= snapshotLine.EndIncludingLineBreak)
                        {
                            // Nothing
                        }
                        else if (line.Start == snapshotLine.EndIncludingLineBreak)
                        {
                            snapshotLine = snapshotLine.Snapshot.GetLineFromLineNumber(snapshotLine.LineNumber + 1);
                        }
                        else
                        {
                            snapshotLine = line.Start.GetContainingLine();
                        }
                        lineExtent = snapshotLine.Extent;
                    }
                    else if (line.IsFirstTextViewLineForSnapshotLine && line.IsLastTextViewLineForSnapshotLine)
                    {
                        lineExtent = line.Extent;
                    }
                    else
                    {
                        snapshotLine = line.Start.GetContainingLine();
                        lineExtent   = snapshotLine.Extent;
                    }

                    if (prevLineExtent != lineExtent)
                    {
                        list.Clear();
                        structureVisualizerServiceDataProvider.GetData(lineExtent, list);
                        listArray = list.Count == 0 ? Array.Empty <StructureVisualizerData>() : list.ToArray();
                    }

                    if (listArray.Length != 0)
                    {
                        var last = listArray[listArray.Length - 1];
                        // Don't add a vertical line to the line containing the start block
                        if (!(last.Top.Start >= lineExtent.Start && last.Top.End <= lineExtent.End))
                        {
                            var ary = listArray;
                            if (last.Bottom.Start >= lineExtent.Start && last.Bottom.End <= lineExtent.End)
                            {
                                ary = new StructureVisualizerData[listArray.Length - 1];
                                for (int i = 0; i < ary.Length; i++)
                                {
                                    ary[i] = listArray[i];
                                }
                            }
                            yield return(new LineElementData(line, ary));
                        }
                    }

                    prevLineExtent = lineExtent;
                }
            }
        }