From 1bdd80e396875e3baaa86783eb1aa4ba04539089 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 3 Feb 2014 03:02:38 +0100 Subject: [PATCH] Render InsertWithCursor line in the middle of empty lines, but between lines if they are not empty. --- .../Src/Refactoring/InsertionCursorLayer.cs | 24 ++++++++++++------- .../Base/Project/Editor/DocumentUtilities.cs | 14 +++++++++-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs index 0fbebf268b..24c068e7d7 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs @@ -30,6 +30,7 @@ using ICSharpCode.AvalonEdit.Rendering; using ICSharpCode.AvalonEdit.Utils; using ICSharpCode.NRefactory; using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Editor; namespace CSharpBinding.Refactoring { class InsertionCursorLayer : Canvas, IDisposable @@ -67,9 +68,9 @@ namespace CSharpBinding.Refactoring ScrollToInsertionPoint(); } - static readonly Pen markerPen = new Pen(Brushes.Blue, 1); + static readonly Pen markerPen = new Pen(Brushes.Blue, 2); - static readonly Pen tempMarkerPen = new Pen(Brushes.Gray, 1); + static readonly Pen tempMarkerPen = new Pen(Brushes.Gray, 2); protected override void OnRender(DrawingContext drawingContext) { @@ -77,16 +78,22 @@ namespace CSharpBinding.Refactoring if (insertionPointNextToMouse > -1 && insertionPointNextToMouse != CurrentInsertionPoint) DrawLineForInsertionPoint(insertionPointNextToMouse, tempMarkerPen, drawingContext); SetGroupBoxPosition(); - // HACK + // HACK: why OnRender() override? we could just use Line objects instead } - void DrawLineForInsertionPoint(int index, Pen pen, DrawingContext drawingContext) + Point GetLinePosition(int index) { var currentInsertionPoint = insertionPoints[index]; - var pos = editor.TextView.GetVisualPosition(new TextViewPosition(currentInsertionPoint.Location), VisualYPosition.LineTop); + var textViewPosition = new TextViewPosition(currentInsertionPoint.Location); + bool isEmptyLine = DocumentUtilities.IsEmptyLine(editor.Document, textViewPosition.Line); + var pos = editor.TextView.GetVisualPosition(textViewPosition, isEmptyLine ? VisualYPosition.LineMiddle : VisualYPosition.LineTop); + return pos - editor.TextView.ScrollOffset; + } + + void DrawLineForInsertionPoint(int index, Pen pen, DrawingContext drawingContext) + { + var pos = GetLinePosition(index); var endPos = new Point(pos.X + editor.TextView.ActualWidth * 0.6, pos.Y); - pos -= editor.TextView.ScrollOffset; - endPos -= editor.TextView.ScrollOffset; var pixelSize = PixelSnapHelpers.GetPixelSize(this); drawingContext.DrawLine(pen, PixelSnapHelpers.Round(pos, pixelSize), PixelSnapHelpers.Round(endPos, pixelSize)); } @@ -248,8 +255,7 @@ namespace CSharpBinding.Refactoring void SetGroupBoxPosition() { - var location = insertionPoints[CurrentInsertionPoint].Location; - var boxPosition = editor.TextView.GetVisualPosition(new TextViewPosition(location), VisualYPosition.LineMiddle) - editor.TextView.ScrollOffset + new Vector(editor.TextView.ActualWidth * 0.6 - 5, -groupBox.ActualHeight / 2.0); + var boxPosition = GetLinePosition(CurrentInsertionPoint) + new Vector(editor.TextView.ActualWidth * 0.6 - 5, -groupBox.ActualHeight / 2.0); Canvas.SetTop(groupBox, boxPosition.Y); Canvas.SetLeft(groupBox, boxPosition.X); } diff --git a/src/Main/Base/Project/Editor/DocumentUtilities.cs b/src/Main/Base/Project/Editor/DocumentUtilities.cs index a844575bc6..a7017d48c9 100644 --- a/src/Main/Base/Project/Editor/DocumentUtilities.cs +++ b/src/Main/Base/Project/Editor/DocumentUtilities.cs @@ -166,10 +166,20 @@ namespace ICSharpCode.SharpDevelop.Editor return DocumentUtilities.GetWhitespaceAfter(document, document.GetLineByNumber(line).Offset); } + /// + /// Gets whether the specified document line is empty or contains only whitespace. + /// + public static bool IsEmptyLine(IDocument document, int lineNumber) + { + var line = document.GetLineByNumber(lineNumber); + ISegment segment = TextUtilities.GetWhitespaceAfter(document, line.Offset); + return segment.Length == line.Length; + } + /// /// Gets all indentation starting at offset. /// - /// The document. + /// The document. /// The offset where the indentation starts. /// The indentation text. public static string GetWhitespaceAfter(ITextSource textSource, int offset) @@ -181,7 +191,7 @@ namespace ICSharpCode.SharpDevelop.Editor /// /// Gets all indentation before the offset. /// - /// The document. + /// The document. /// The offset where the indentation ends. /// The indentation text. public static string GetWhitespaceBefore(ITextSource textSource, int offset)