mirror of https://github.com/icsharpcode/ILSpy.git
11 changed files with 356 additions and 64 deletions
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Media; |
||||
using System.Windows.Media.Animation; |
||||
using System.Windows.Threading; |
||||
using ICSharpCode.AvalonEdit.Editing; |
||||
|
||||
namespace ICSharpCode.ILSpy |
||||
{ |
||||
/// <summary>
|
||||
/// Animated rectangle around the caret.
|
||||
/// </summary>
|
||||
sealed class CaretHighlightAdorner : Adorner |
||||
{ |
||||
Pen pen; |
||||
RectangleGeometry geometry; |
||||
|
||||
public CaretHighlightAdorner(TextArea textArea) |
||||
: base(textArea.TextView) |
||||
{ |
||||
Rect min = textArea.Caret.CalculateCaretRectangle(); |
||||
min.Offset(-textArea.TextView.ScrollOffset); |
||||
|
||||
Rect max = min; |
||||
double size = Math.Max(min.Width, min.Height) * 0.25; |
||||
max.Inflate(size, size); |
||||
|
||||
pen = new Pen(TextBlock.GetForeground(textArea.TextView).Clone(), 1); |
||||
|
||||
geometry = new RectangleGeometry(min, 2, 2); |
||||
geometry.BeginAnimation(RectangleGeometry.RectProperty, new RectAnimation(min, max, new Duration(TimeSpan.FromMilliseconds(300))) { AutoReverse = true }); |
||||
pen.Brush.BeginAnimation(Brush.OpacityProperty, new DoubleAnimation(1, 0, new Duration(TimeSpan.FromMilliseconds(200))) { BeginTime = TimeSpan.FromMilliseconds(450) }); |
||||
} |
||||
|
||||
public static void DisplayCaretHighlightAnimation(TextArea textArea) |
||||
{ |
||||
AdornerLayer layer = AdornerLayer.GetAdornerLayer(textArea.TextView); |
||||
CaretHighlightAdorner adorner = new CaretHighlightAdorner(textArea); |
||||
layer.Add(adorner); |
||||
|
||||
DispatcherTimer timer = new DispatcherTimer(); |
||||
timer.Interval = TimeSpan.FromSeconds(1); |
||||
timer.Tick += delegate { |
||||
timer.Stop(); |
||||
layer.Remove(adorner); |
||||
}; |
||||
timer.Start(); |
||||
} |
||||
|
||||
protected override void OnRender(DrawingContext drawingContext) |
||||
{ |
||||
drawingContext.DrawGeometry(null, pen, geometry); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Windows.Input; |
||||
using ICSharpCode.AvalonEdit.Document; |
||||
using ICSharpCode.AvalonEdit.Rendering; |
||||
|
||||
namespace ICSharpCode.ILSpy |
||||
{ |
||||
sealed class ReferenceElementGenerator : VisualLineElementGenerator |
||||
{ |
||||
MainWindow parentWindow; |
||||
public TextSegmentCollection<ReferenceSegment> References { get; set; } |
||||
|
||||
public ReferenceElementGenerator(MainWindow parentWindow) |
||||
{ |
||||
if (parentWindow == null) |
||||
throw new ArgumentNullException("parentWindow"); |
||||
this.parentWindow = parentWindow; |
||||
} |
||||
|
||||
public override int GetFirstInterestedOffset(int startOffset) |
||||
{ |
||||
if (this.References == null) |
||||
return -1; |
||||
var segment = this.References.FindFirstSegmentWithStartAfter(startOffset); |
||||
return segment != null ? segment.StartOffset : -1; |
||||
} |
||||
|
||||
public override VisualLineElement ConstructElement(int offset) |
||||
{ |
||||
if (this.References == null) |
||||
return null; |
||||
foreach (var segment in this.References.FindSegmentsContaining(offset)) { |
||||
if (offset < segment.EndOffset) { |
||||
return new VisualLineReferenceText(CurrentContext.VisualLine, segment.EndOffset - offset, this, segment); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
internal void JumpToReference(ReferenceSegment referenceSegment) |
||||
{ |
||||
parentWindow.JumpToReference(referenceSegment); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// VisualLineElement that represents a piece of text and is a clickable link.
|
||||
/// </summary>
|
||||
sealed class VisualLineReferenceText : VisualLineText |
||||
{ |
||||
ReferenceElementGenerator parent; |
||||
ReferenceSegment referenceSegment; |
||||
|
||||
/// <summary>
|
||||
/// Creates a visual line text element with the specified length.
|
||||
/// It uses the <see cref="ITextRunConstructionContext.VisualLine"/> and its
|
||||
/// <see cref="VisualLineElement.RelativeTextOffset"/> to find the actual text string.
|
||||
/// </summary>
|
||||
public VisualLineReferenceText(VisualLine parentVisualLine, int length, ReferenceElementGenerator parent, ReferenceSegment referenceSegment) : base(parentVisualLine, length) |
||||
{ |
||||
this.parent = parent; |
||||
this.referenceSegment = referenceSegment; |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnQueryCursor(QueryCursorEventArgs e) |
||||
{ |
||||
e.Handled = true; |
||||
e.Cursor = Cursors.Hand; |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e) |
||||
{ |
||||
if (e.ChangedButton == MouseButton.Left && !e.Handled) { |
||||
parent.JumpToReference(referenceSegment); |
||||
e.Handled = true; |
||||
} |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
protected override VisualLineText CreateInstance(int length) |
||||
{ |
||||
return new VisualLineReferenceText(ParentVisualLine, length, parent, referenceSegment); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue