forked from akaStiX/ProgressiveScrollVS2017
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MarkerRenderer.cs
150 lines (127 loc) · 4.64 KB
/
MarkerRenderer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System;
using System.Collections.Generic;
using System.Windows.Media;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.Text;
using System.Windows;
namespace ProgressiveScroll
{
class MarkerRenderer
{
private ITextView _textView;
private ITagAggregator<IVsVisibleTextMarkerTag> _markerTagAggregator;
private ITagAggregator<IErrorTag> _errorTagAggregator;
private EnvDTE.Debugger _debugger;
private SimpleScrollBar _scrollBar;
private string _filename;
public ColorSet Colors { get; set; }
private static readonly int markerStartOffset = -1; //-3
private static readonly int markerEndOffset = 0; //2
private static int _bookmarkType = 3;
public MarkerRenderer(
ITextView textView,
ITagAggregator<IVsVisibleTextMarkerTag> markerTagAggregator,
ITagAggregator<IErrorTag> errorTagAggregator,
EnvDTE.Debugger debugger,
SimpleScrollBar scrollBar)
{
_textView = textView;
_markerTagAggregator = markerTagAggregator;
_errorTagAggregator = errorTagAggregator;
_debugger = debugger;
_scrollBar = scrollBar;
// ... Pretty convoluted way to get the filename:
ITextDocument doc;
bool success = textView.TextBuffer.Properties.TryGetProperty<ITextDocument>(typeof(ITextDocument), out doc);
if (success)
{
_filename = doc.FilePath;
}
else
{
_filename = "";
}
}
public void Render(DrawingContext drawingContext)
{
NormalizedSnapshotSpanCollection bookmarks = GetBookmarks();
DrawMarkers(drawingContext, bookmarks, Colors.BookmarksBrush, true, 0, 3);
NormalizedSnapshotSpanCollection breakpoints = GetBreakpoints();
DrawMarkers(drawingContext, breakpoints, Colors.BreakpointsBrush, false, 3, 3);
if (Options.ErrorsEnabled)
{
NormalizedSnapshotSpanCollection errors = GetErrors();
DrawMarkers(drawingContext, errors, Colors.ErrorsBrush, true, -3, 3);
}
}
internal NormalizedSnapshotSpanCollection GetBreakpoints()
{
List<SnapshotSpan> unnormalizedBreakpoints = new List<SnapshotSpan>();
foreach (EnvDTE.Breakpoint bp in _debugger.Breakpoints)
{
if (bp.LocationType == EnvDTE.dbgBreakpointLocationType.dbgBreakpointLocationTypeFile &&
bp.File == _filename)
{
try
{
ITextSnapshotLine line = _textView.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(bp.FileLine);
unnormalizedBreakpoints.Add(line.Extent);
}
catch (System.ArgumentOutOfRangeException) {}
}
}
return new NormalizedSnapshotSpanCollection(unnormalizedBreakpoints);
}
internal NormalizedSnapshotSpanCollection GetBookmarks()
{
IEnumerable<IMappingTagSpan<IVsVisibleTextMarkerTag>> tags =
_markerTagAggregator.GetTags(new SnapshotSpan(_textView.TextSnapshot, 0, _textView.TextSnapshot.Length));
List<SnapshotSpan> unnormalizedBookmarks = new List<SnapshotSpan>();
foreach (IMappingTagSpan<IVsVisibleTextMarkerTag> tag in tags)
{
if (tag.Tag.Type == _bookmarkType)
{
unnormalizedBookmarks.AddRange(tag.Span.GetSpans(_textView.TextSnapshot));
}
}
return new NormalizedSnapshotSpanCollection(unnormalizedBookmarks);
}
internal NormalizedSnapshotSpanCollection GetErrors()
{
IEnumerable<IMappingTagSpan<IErrorTag>> tags =
_errorTagAggregator.GetTags(new SnapshotSpan(_textView.TextSnapshot, 0, _textView.TextSnapshot.Length));
List<SnapshotSpan> unnormalizederrors = new List<SnapshotSpan>();
foreach (IMappingTagSpan<IErrorTag> tag in tags)
{
unnormalizederrors.AddRange(tag.Span.GetSpans(_textView.TextSnapshot));
}
return new NormalizedSnapshotSpanCollection(unnormalizederrors);
}
private void DrawMarkers(DrawingContext drawingContext, NormalizedSnapshotSpanCollection markers, Brush brush, bool right, short xOfs, short markerWidth)
{
if (markers.Count > 0)
{
double yTop = Math.Floor(_scrollBar.GetYCoordinateOfBufferPosition(markers[0].Start)) + markerStartOffset;
double yBottom = Math.Ceiling(_scrollBar.GetYCoordinateOfBufferPosition(markers[0].End)) + markerEndOffset;
double x = right ? _scrollBar.Width - markerWidth + xOfs : xOfs;
for (int i = 1; i < markers.Count; ++i)
{
double y = _scrollBar.GetYCoordinateOfBufferPosition(markers[i].Start) + markerStartOffset;
if (yBottom < y)
{
drawingContext.DrawRectangle(
brush, null,
new Rect(x, yTop, markerWidth, yBottom - yTop));
yTop = y;
}
yBottom = Math.Ceiling(_scrollBar.GetYCoordinateOfBufferPosition(markers[i].End)) + markerEndOffset;
}
drawingContext.DrawRectangle(
brush, null,
new Rect(x, yTop, markerWidth, yBottom - yTop));
}
}
}
}