diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/ITextMarker.cs b/Debugger/ILSpy.Debugger/AvalonEdit/ITextMarker.cs
deleted file mode 100644
index f690f6748..000000000
--- a/Debugger/ILSpy.Debugger/AvalonEdit/ITextMarker.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.Collections.Generic;
-using System.Windows.Media;
-
-using ICSharpCode.ILSpy.Debugger.Bookmarks;
-
-namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
-{
- ///
- /// Represents a text marker.
- ///
- public interface ITextMarker
- {
- ///
- /// Gets the start offset of the marked text region.
- ///
- int StartOffset { get; }
-
- ///
- /// Gets the end offset of the marked text region.
- ///
- int EndOffset { get; }
-
- ///
- /// Gets the length of the marked region.
- ///
- int Length { get; }
-
- ///
- /// Deletes the text marker.
- ///
- void Delete();
-
- ///
- /// Gets whether the text marker was deleted.
- ///
- bool IsDeleted { get; }
-
- ///
- /// Event that occurs when the text marker is deleted.
- ///
- event EventHandler Deleted;
-
- ///
- /// Gets/Sets the background color.
- ///
- Color? BackgroundColor { get; set; }
-
- ///
- /// Gets/Sets the foreground color.
- ///
- Color? ForegroundColor { get; set; }
-
- ///
- /// Gets/Sets the type of the marker. Use TextMarkerType.None for normal markers.
- ///
- TextMarkerType MarkerType { get; set; }
-
- ///
- /// Gets/Sets the color of the marker.
- ///
- Color MarkerColor { get; set; }
-
- ///
- /// Gets/Sets an object with additional data for this text marker.
- ///
- object Tag { get; set; }
-
- ///
- /// Gets/Sets an object that will be displayed as tooltip in the text editor.
- ///
- object ToolTip { get; set; }
-
- ///
- /// Gets or sets if the marker is visible or not.
- ///
- Predicate IsVisible { get; set; }
-
- ///
- /// Gets or sets the bookmark.
- ///
- IBookmark Bookmark { get; set; }
- }
-
- public enum TextMarkerType
- {
- ///
- /// Use no marker
- ///
- None,
- ///
- /// Use squiggly underline marker
- ///
- SquigglyUnderline
- }
-
- public interface ITextMarkerService
- {
- ///
- /// Creates a new text marker. The text marker will be invisible at first,
- /// you need to set one of the Color properties to make it visible.
- ///
- ITextMarker Create(int startOffset, int length);
-
- ///
- /// Gets the list of text markers.
- ///
- IEnumerable TextMarkers { get; }
-
- ///
- /// Removes the specified text marker.
- ///
- void Remove(ITextMarker marker);
-
- ///
- /// Removes all text markers that match the condition.
- ///
- void RemoveAll(Predicate predicate);
- }
-}
diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/IToolTip.cs b/Debugger/ILSpy.Debugger/AvalonEdit/IToolTip.cs
deleted file mode 100644
index bfbddea3c..000000000
--- a/Debugger/ILSpy.Debugger/AvalonEdit/IToolTip.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.Windows;
-
-namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
-{
- ///
- /// Content of text editor tooltip (used as ),
- /// specifying whether it should be displayed in a WPF Popup.
- ///
- internal interface ITooltip
- {
- ///
- /// If true, this ITooltip will be displayed in a WPF Popup.
- /// Otherwise it will be displayed in a WPF Tooltip.
- /// WPF Popups are (unlike WPF Tooltips) focusable.
- ///
- bool ShowAsPopup { get; }
-
- ///
- /// Closes this tooltip.
- ///
- /// True if close request is raised
- /// because of mouse click on some SharpDevelop GUI element.
- /// True if Close succeeded (that is, can close). False otherwise.
- bool Close(bool mouseClick);
-
- ///
- /// Occurs when this tooltip decides to close.
- ///
- event RoutedEventHandler Closed;
- }
-}
diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs b/Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs
deleted file mode 100644
index 9f60a8202..000000000
--- a/Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.Diagnostics;
-using System.Linq;
-using System.Windows;
-using System.Windows.Input;
-using System.Windows.Media;
-
-using ICSharpCode.AvalonEdit.Editing;
-using ICSharpCode.AvalonEdit.Rendering;
-using ICSharpCode.AvalonEdit.Utils;
-using ICSharpCode.Decompiler;
-using ICSharpCode.ILSpy.Debugger.Bookmarks;
-using ICSharpCode.ILSpy.Debugger.Services;
-using ICSharpCode.NRefactory.CSharp;
-using Mono.Cecil;
-
-namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
-{
- [Export("IconMargin"), PartCreationPolicy(CreationPolicy.Shared)]
- public class IconBarMargin : AbstractMargin, IDisposable
- {
- public IconBarMargin()
- {
- BookmarkManager.Added += delegate { InvalidateVisual(); };
- BookmarkManager.Removed += delegate { InvalidateVisual(); };
- }
-
- public virtual void Dispose()
- {
- this.TextView = null; // detach from TextView (will also detach from manager)
- }
-
- ///
- protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
- {
- // accept clicks even when clicking on the background
- return new PointHitTestResult(this, hitTestParameters.HitPoint);
- }
-
- ///
- protected override Size MeasureOverride(Size availableSize)
- {
- return new Size(18, 0);
- }
-
- protected override void OnRender(DrawingContext drawingContext)
- {
- Size renderSize = this.RenderSize;
- drawingContext.DrawRectangle(SystemColors.ControlBrush, null,
- new Rect(0, 0, renderSize.Width, renderSize.Height));
- drawingContext.DrawLine(new Pen(SystemColors.ControlDarkBrush, 1),
- new Point(renderSize.Width - 0.5, 0),
- new Point(renderSize.Width - 0.5, renderSize.Height));
-
- TextView textView = this.TextView;
- if (textView != null && textView.VisualLinesValid) {
- // create a dictionary line number => first bookmark
- Dictionary bookmarkDict = new Dictionary();
- foreach (var bm in BookmarkManager.Bookmarks) {
- if (DebugData.DecompiledMemberReferences == null || DebugData.DecompiledMemberReferences.Count == 0 ||
- !DebugData.DecompiledMemberReferences.ContainsKey(bm.MemberReference.MetadataToken.ToInt32()))
- continue;
-
- int line = bm.LineNumber;
- BookmarkBase existingBookmark;
- if (!bookmarkDict.TryGetValue(line, out existingBookmark) || bm.ZOrder > existingBookmark.ZOrder)
- bookmarkDict[line] = bm;
- }
- Size pixelSize = PixelSnapHelpers.GetPixelSize(this);
- foreach (VisualLine line in textView.VisualLines) {
- int lineNumber = line.FirstDocumentLine.LineNumber;
- BookmarkBase bm;
- if (bookmarkDict.TryGetValue(lineNumber, out bm)) {
- Rect rect = new Rect(0, PixelSnapHelpers.Round(line.VisualTop - textView.VerticalOffset, pixelSize.Height), 16, 16);
- if (dragDropBookmark == bm && dragStarted)
- drawingContext.PushOpacity(0.5);
- drawingContext.DrawImage(bm.Image, rect);
- if (dragDropBookmark == bm && dragStarted)
- drawingContext.Pop();
- }
- }
- if (dragDropBookmark != null && dragStarted) {
- Rect rect = new Rect(0, PixelSnapHelpers.Round(dragDropCurrentPoint - 8, pixelSize.Height), 16, 16);
- drawingContext.DrawImage(dragDropBookmark.Image, rect);
- }
- }
- }
-
- IBookmark dragDropBookmark; // bookmark being dragged (!=null if drag'n'drop is active)
- double dragDropStartPoint;
- double dragDropCurrentPoint;
- bool dragStarted; // whether drag'n'drop operation has started (mouse was moved minimum distance)
-
- protected override void OnMouseDown(MouseButtonEventArgs e)
- {
- base.OnMouseDown(e);
- int line = GetLineFromMousePosition(e);
- if (!e.Handled && line > 0) {
- IBookmark bm = GetBookmarkFromLine(line);
- if (bm != null) {
- bm.MouseDown(e);
- if (!e.Handled) {
- if (e.ChangedButton == MouseButton.Left && bm.CanDragDrop && CaptureMouse()) {
- StartDragDrop(bm, e);
- e.Handled = true;
- }
- }
- }
- }
- // don't allow selecting text through the IconBarMargin
- if (e.ChangedButton == MouseButton.Left)
- e.Handled = true;
- }
-
- BookmarkBase GetBookmarkFromLine(int line)
- {
- BookmarkBase result = null;
- foreach (BookmarkBase bm in BookmarkManager.Bookmarks) {
- if (bm.LineNumber == line &&
- DebugData.DecompiledMemberReferences != null && DebugData.DecompiledMemberReferences.ContainsKey(bm.MemberReference.MetadataToken.ToInt32())) {
- if (result == null || bm.ZOrder > result.ZOrder)
- result = bm;
- }
- }
- return result;
- }
-
- protected override void OnLostMouseCapture(MouseEventArgs e)
- {
- CancelDragDrop();
- base.OnLostMouseCapture(e);
- }
-
- void StartDragDrop(IBookmark bm, MouseEventArgs e)
- {
- dragDropBookmark = bm;
- dragDropStartPoint = dragDropCurrentPoint = e.GetPosition(this).Y;
- if (TextView != null) {
- TextArea area = TextView.Services.GetService(typeof(TextArea)) as TextArea;
- if (area != null)
- area.PreviewKeyDown += TextArea_PreviewKeyDown;
- }
- }
-
- void CancelDragDrop()
- {
- if (dragDropBookmark != null) {
- dragDropBookmark = null;
- dragStarted = false;
- if (TextView != null) {
- TextArea area = TextView.Services.GetService(typeof(TextArea)) as TextArea;
- if (area != null)
- area.PreviewKeyDown -= TextArea_PreviewKeyDown;
- }
- ReleaseMouseCapture();
- InvalidateVisual();
- }
- }
-
- void TextArea_PreviewKeyDown(object sender, KeyEventArgs e)
- {
- // any key press cancels drag'n'drop
- CancelDragDrop();
- if (e.Key == Key.Escape)
- e.Handled = true;
- }
-
- int GetLineFromMousePosition(MouseEventArgs e)
- {
- TextView textView = this.TextView;
- if (textView == null)
- return 0;
- VisualLine vl = textView.GetVisualLineFromVisualTop(e.GetPosition(textView).Y + textView.ScrollOffset.Y);
- if (vl == null)
- return 0;
- return vl.FirstDocumentLine.LineNumber;
- }
-
- protected override void OnMouseMove(MouseEventArgs e)
- {
- base.OnMouseMove(e);
- if (dragDropBookmark != null) {
- dragDropCurrentPoint = e.GetPosition(this).Y;
- if (Math.Abs(dragDropCurrentPoint - dragDropStartPoint) > SystemParameters.MinimumVerticalDragDistance)
- dragStarted = true;
- InvalidateVisual();
- }
-
- BreakpointBookmark bm = BookmarkManager.Bookmarks.Find(
- b => DebugData.CodeMappings != null && DebugData.CodeMappings.ContainsKey(b.MemberReference.MetadataToken.ToInt32()) &&
- b.LineNumber == GetLineFromMousePosition(e)
- && b is BreakpointBookmark) as BreakpointBookmark;
-
- this.ToolTip = (bm != null) ? bm.Tooltip : null;
- }
-
- protected override void OnMouseUp(MouseButtonEventArgs e)
- {
- base.OnMouseUp(e);
- int line = GetLineFromMousePosition(e);
- if (!e.Handled && dragDropBookmark != null) {
- if (dragStarted) {
- if (line != 0)
- dragDropBookmark.Drop(line);
- e.Handled = true;
- }
- CancelDragDrop();
- }
- if (!e.Handled && line != 0) {
- BookmarkBase bm = GetBookmarkFromLine(line);
- if (bm != null) {
- bm.MouseUp(e);
-
- if (bm.CanToggle) {
- BookmarkManager.RemoveMark(bm);
- InvalidateVisual();
- }
-
- if (e.Handled)
- return;
- }
- if (e.ChangedButton == MouseButton.Left) {
- if (DebugData.CodeMappings != null && DebugData.CodeMappings.Count > 0) {
-
- // check if the codemappings exists for this line
- var storage = DebugData.CodeMappings;
- int token = 0;
- foreach (var key in storage.Keys) {
- var instruction = storage[key].GetInstructionByLineNumber(line, out token);
-
- if (instruction == null) {
- continue;
- }
-
- // no bookmark on the line: create a new breakpoint
- DebuggerService.ToggleBreakpointAt(
- DebugData.DecompiledMemberReferences[key],
- line,
- instruction.ILInstructionOffset,
- DebugData.Language);
- break;
- }
-
- if (token == 0) {
- MessageBox.Show(string.Format("Missing code mappings at line {0}.", line),
- "Code mappings", MessageBoxButton.OK, MessageBoxImage.Information);
- return;
- }
- }
- }
- InvalidateVisual();
- }
- }
-
- public void SyncBookmarks()
- {
- var storage = DebugData.CodeMappings;
- if (storage == null || storage.Count == 0)
- return;
-
- //remove existing bookmarks and create new ones
- List newBookmarks = new List();
- for (int i = BookmarkManager.Bookmarks.Count - 1; i >= 0; --i) {
- var breakpoint = BookmarkManager.Bookmarks[i] as BreakpointBookmark;
- if (breakpoint == null)
- continue;
-
- var key = breakpoint.MemberReference.MetadataToken.ToInt32();
- if (!storage.ContainsKey(key))
- continue;
-
- var member = DebugData.DecompiledMemberReferences[key];
-
- bool isMatch;
- SourceCodeMapping map = storage[key].GetInstructionByTokenAndOffset(
- member.MetadataToken.ToInt32(), breakpoint.ILRange.From, out isMatch);
-
- if (map != null) {
- newBookmarks.Add(new BreakpointBookmark(
- member, new AstLocation(map.SourceCodeLine, 0),
- map.ILInstructionOffset, BreakpointAction.Break, DebugData.Language));
-
- BookmarkManager.RemoveMark(breakpoint);
- }
- }
-
- newBookmarks.ForEach(m => BookmarkManager.AddMark(m));
-
- SyncCurrentLineBookmark();
- }
-
- void SyncCurrentLineBookmark()
- {
- // checks
- if (CurrentLineBookmark.Instance == null)
- return;
-
- var oldMappings = DebugData.OldCodeMappings;
- var newMappings = DebugData.CodeMappings;
-
- if (oldMappings == null || newMappings == null)
- return;
-
- // 1. Save it's data
- int line = CurrentLineBookmark.Instance.LineNumber;
- var markerType = CurrentLineBookmark.Instance.MemberReference;
-
- if (!oldMappings.ContainsKey(markerType.MetadataToken.ToInt32()) || !newMappings.ContainsKey(markerType.MetadataToken.ToInt32()))
- return;
-
- // 2. Remove it
- CurrentLineBookmark.Remove();
-
- // 3. map the marker line
- int token;
- var instruction = oldMappings[markerType.MetadataToken.ToInt32()].GetInstructionByLineNumber(line, out token);
- if (instruction == null)
- return;
-
- MemberReference memberReference;
- int newline;
- if (newMappings[markerType.MetadataToken.ToInt32()].GetInstructionByTokenAndOffset(token, instruction.ILInstructionOffset.From, out memberReference, out newline)) {
- // 4. create breakpoint for new languages
- CurrentLineBookmark.SetPosition(memberReference, newline, 0, newline, 0);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/TextEditorWeakEventManager.cs b/Debugger/ILSpy.Debugger/AvalonEdit/TextEditorWeakEventManager.cs
deleted file mode 100644
index 1ac80f7d5..000000000
--- a/Debugger/ILSpy.Debugger/AvalonEdit/TextEditorWeakEventManager.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Windows;
-using ICSharpCode.AvalonEdit;
-using ICSharpCode.AvalonEdit.Utils;
-
-namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
-{
- public static class TextEditorWeakEventManager
- {
- public sealed class MouseHover : WeakEventManagerBase
- {
- protected override void StopListening(TextEditor source)
- {
- source.MouseHover -= DeliverEvent;
- }
-
- protected override void StartListening(TextEditor source)
- {
- source.MouseHover += DeliverEvent;
- }
- }
-
- public sealed class MouseHoverStopped : WeakEventManagerBase
- {
- protected override void StopListening(TextEditor source)
- {
- source.MouseHoverStopped -= DeliverEvent;
- }
-
- protected override void StartListening(TextEditor source)
- {
- source.MouseHoverStopped += DeliverEvent;
- }
- }
-
- public sealed class MouseDown : WeakEventManagerBase
- {
- protected override void StopListening(TextEditor source)
- {
- source.MouseDown -= DeliverEvent;
- }
-
- protected override void StartListening(TextEditor source)
- {
- source.MouseDown += DeliverEvent;
- }
- }
- }
-}
diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/TextMarkerService.cs b/Debugger/ILSpy.Debugger/AvalonEdit/TextMarkerService.cs
deleted file mode 100644
index 8c6b89525..000000000
--- a/Debugger/ILSpy.Debugger/AvalonEdit/TextMarkerService.cs
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.Linq;
-using System.Windows;
-using System.Windows.Media;
-using System.Windows.Threading;
-
-using ICSharpCode.AvalonEdit;
-using ICSharpCode.AvalonEdit.Document;
-using ICSharpCode.AvalonEdit.Rendering;
-using ICSharpCode.ILSpy.Debugger.Bookmarks;
-
-namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
-{
- ///
- /// Handles the text markers for a code editor.
- ///
- [Export("TextMarkerService"), PartCreationPolicy(CreationPolicy.Shared)]
- public sealed class TextMarkerService : DocumentColorizingTransformer, IBackgroundRenderer, ITextMarkerService
- {
- TextEditor codeEditor;
-
- TextSegmentCollection markers = new TextSegmentCollection();
-
- public TextMarkerService()
- {
- BookmarkManager.Added += new BookmarkEventHandler(BookmarkManager_Added);
- BookmarkManager.Removed += new BookmarkEventHandler(BookmarkManager_Removed);
- }
-
- public TextEditor CodeEditor {
- get { return codeEditor; }
- set { codeEditor = value; }
- }
-
- void BookmarkManager_Removed(object sender, BookmarkEventArgs e)
- {
- if (e.Bookmark is BreakpointBookmark) {
- var bm = (MarkerBookmark)e.Bookmark;
- Remove(bm.Marker);
- }
-
- if (e.Bookmark is CurrentLineBookmark) {
- RemoveAll(m => m.Bookmark is CurrentLineBookmark);
- }
- }
-
- void BookmarkManager_Added(object sender, BookmarkEventArgs e)
- {
- if (e.Bookmark is MarkerBookmark) {
- var bm = (MarkerBookmark)e.Bookmark;
- // add bookmark for the current type
- if (bm.LineNumber < codeEditor.Document.LineCount) {
- DocumentLine line = codeEditor.Document.GetLineByNumber(bm.LineNumber);
- bm.CreateMarker(this, line.Offset, line.Length);
- }
- }
- }
-
- #region ITextMarkerService
- public ITextMarker Create(int startOffset, int length)
- {
- int textLength = codeEditor.TextArea.TextView.Document.TextLength;
- if (startOffset < 0 || startOffset > textLength)
- throw new ArgumentOutOfRangeException("startOffset", startOffset, "Value must be between 0 and " + textLength);
- if (length < 0 || startOffset + length > textLength)
- throw new ArgumentOutOfRangeException("length", length, "length must not be negative and startOffset+length must not be after the end of the document");
-
- TextMarker m = new TextMarker(this, startOffset, length);
- markers.Add(m);
- // no need to mark segment for redraw: the text marker is invisible until a property is set
- return m;
- }
-
- public IEnumerable GetMarkersAtOffset(int offset)
- {
- return markers.FindSegmentsContaining(offset);
- }
-
- public IEnumerable TextMarkers {
- get { return markers; }
- }
-
- public void RemoveAll(Predicate predicate)
- {
- if (predicate == null)
- throw new ArgumentNullException("predicate");
- foreach (TextMarker m in markers.ToArray()) {
- if (predicate(m))
- Remove(m);
- }
- }
-
- public void Remove(ITextMarker marker)
- {
- if (marker == null)
- return;
-
- TextMarker m = marker as TextMarker;
- if (markers.Remove(m)) {
- Redraw(m);
- m.OnDeleted();
- }
- }
-
- ///
- /// Redraws the specified text segment.
- ///
- public void Redraw(ISegment segment)
- {
- codeEditor.TextArea.TextView.Redraw(segment, DispatcherPriority.Normal);
- }
- #endregion
-
- #region DocumentColorizingTransformer
- protected override void ColorizeLine(DocumentLine line)
- {
- if (markers == null)
- return;
- int lineStart = line.Offset;
- int lineEnd = lineStart + line.Length;
- foreach (TextMarker marker in markers.FindOverlappingSegments(lineStart, line.Length).Reverse()) {
- if (!marker.IsVisible(marker.Bookmark))
- continue;
-
- Brush foregroundBrush = null;
- if (marker.ForegroundColor != null) {
- foregroundBrush = new SolidColorBrush(marker.ForegroundColor.Value);
- foregroundBrush.Freeze();
- }
- ChangeLinePart(
- Math.Max(marker.StartOffset, lineStart),
- Math.Min(marker.EndOffset, lineEnd),
- element => {
- if (foregroundBrush != null) {
- element.TextRunProperties.SetForegroundBrush(foregroundBrush);
- }
- }
- );
- }
- }
- #endregion
-
- #region IBackgroundRenderer
- public KnownLayer Layer {
- get {
- // draw behind selection
- return KnownLayer.Selection;
- }
- }
-
- public void Draw(TextView textView, DrawingContext drawingContext)
- {
- if (textView == null)
- throw new ArgumentNullException("textView");
- if (drawingContext == null)
- throw new ArgumentNullException("drawingContext");
- if (markers == null || !textView.VisualLinesValid)
- return;
- var visualLines = textView.VisualLines;
- if (visualLines.Count == 0)
- return;
- int viewStart = visualLines.First().FirstDocumentLine.Offset;
- int viewEnd = visualLines.Last().LastDocumentLine.Offset + visualLines.Last().LastDocumentLine.Length;
- foreach (TextMarker marker in markers.FindOverlappingSegments(viewStart, viewEnd - viewStart).Reverse()) {
- if (!marker.IsVisible(marker.Bookmark))
- continue;
-
- if (marker.BackgroundColor != null) {
- BackgroundGeometryBuilder geoBuilder = new BackgroundGeometryBuilder();
- geoBuilder.AlignToWholePixels = true;
- geoBuilder.CornerRadius = 3;
- geoBuilder.AddSegment(textView, marker);
- Geometry geometry = geoBuilder.CreateGeometry();
- if (geometry != null) {
- Color color = marker.BackgroundColor.Value;
- SolidColorBrush brush = new SolidColorBrush(color);
- brush.Freeze();
- drawingContext.DrawGeometry(brush, null, geometry);
- }
- }
- if (marker.MarkerType != TextMarkerType.None) {
- foreach (Rect r in BackgroundGeometryBuilder.GetRectsForSegment(textView, marker)) {
- Point startPoint = r.BottomLeft;
- Point endPoint = r.BottomRight;
-
- Pen usedPen = new Pen(new SolidColorBrush(marker.MarkerColor), 1);
- usedPen.Freeze();
- switch (marker.MarkerType) {
- case TextMarkerType.SquigglyUnderline:
- double offset = 2.5;
-
- int count = Math.Max((int)((endPoint.X - startPoint.X) / offset) + 1, 4);
-
- StreamGeometry geometry = new StreamGeometry();
-
- using (StreamGeometryContext ctx = geometry.Open()) {
- ctx.BeginFigure(startPoint, false, false);
- ctx.PolyLineTo(CreatePoints(startPoint, endPoint, offset, count).ToArray(), true, false);
- }
-
- geometry.Freeze();
-
- drawingContext.DrawGeometry(Brushes.Transparent, usedPen, geometry);
- break;
- }
- }
- }
- }
- }
-
- IEnumerable CreatePoints(Point start, Point end, double offset, int count)
- {
- for (int i = 0; i < count; i++)
- yield return new Point(start.X + i * offset, start.Y - ((i + 1) % 2 == 0 ? offset : 0));
- }
- #endregion
- }
-
- sealed class TextMarker : TextSegment, ITextMarker
- {
- readonly TextMarkerService service;
-
- public TextMarker(TextMarkerService service, int startOffset, int length)
- {
- if (service == null)
- throw new ArgumentNullException("service");
- this.service = service;
- this.StartOffset = startOffset;
- this.Length = length;
- this.markerType = TextMarkerType.None;
- }
-
- public event EventHandler Deleted;
-
- public bool IsDeleted {
- get { return !this.IsConnectedToCollection; }
- }
-
- public void Delete()
- {
- service.Remove(this);
- }
-
- internal void OnDeleted()
- {
- if (Deleted != null)
- Deleted(this, EventArgs.Empty);
- }
-
- void Redraw()
- {
- service.Redraw(this);
- }
-
- Color? backgroundColor;
-
- public Color? BackgroundColor {
- get { return backgroundColor; }
- set {
- if (backgroundColor != value) {
- backgroundColor = value;
- Redraw();
- }
- }
- }
-
- Color? foregroundColor;
-
- public Color? ForegroundColor {
- get { return foregroundColor; }
- set {
- if (foregroundColor != value) {
- foregroundColor = value;
- Redraw();
- }
- }
- }
-
- public object Tag { get; set; }
-
- TextMarkerType markerType;
-
- public TextMarkerType MarkerType {
- get { return markerType; }
- set {
- if (markerType != value) {
- markerType = value;
- Redraw();
- }
- }
- }
-
- Color markerColor;
-
- public Color MarkerColor {
- get { return markerColor; }
- set {
- if (markerColor != value) {
- markerColor = value;
- Redraw();
- }
- }
-
- }
- ///
- public object ToolTip { get; set; }
-
- ///
- public Predicate IsVisible { get; set; }
-
- ///
- public IBookmark Bookmark { get; set; }
- }
-}