From ff01c46e988456f78a8b77cc06a0d956ecba2a66 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 27 Oct 2010 17:05:25 +0200 Subject: [PATCH] Fixed http://community.sharpdevelop.net/forums/t/12009.aspx (when word-wrapping is enabled and lines are very long, ScrollTo() does not find the correct position). --- .../Rendering/TextView.cs | 7 ++++-- .../ICSharpCode.AvalonEdit/TextEditor.cs | 22 +++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs index ea3e74fe00..ca0cd38af8 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs @@ -547,15 +547,18 @@ namespace ICSharpCode.AvalonEdit.Rendering TextParagraphProperties paragraphProperties = CreateParagraphProperties(globalTextRunProperties); while (heightTree.GetIsCollapsed(documentLine)) { - documentLine = heightTree.GetLineByNumber(documentLine.LineNumber - 1); + documentLine = documentLine.PreviousLine; } l = BuildVisualLine(documentLine, globalTextRunProperties, paragraphProperties, elementGenerators.ToArray(), lineTransformers.ToArray(), lastAvailableSize); - l.VisualTop = heightTree.GetVisualPosition(documentLine); allVisualLines.Add(l); + // update all visual top values (building the line might have changed visual top of other lines due to word wrapping) + foreach (var line in allVisualLines) { + line.VisualTop = heightTree.GetVisualPosition(line.FirstDocumentLine); + } } return l; } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs index c152b358e1..d3c74ca179 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs @@ -7,11 +7,11 @@ using System.IO; using System.Text; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Threading; - using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Highlighting; @@ -1065,7 +1065,25 @@ namespace ICSharpCode.AvalonEdit { const double MinimumScrollPercentage = 0.3; - if (scrollViewer != null) { + TextView textView = textArea.TextView; + TextDocument document = textView.Document; + if (scrollViewer != null && document != null) { + IScrollInfo scrollInfo = textView; + if (!scrollInfo.CanHorizontallyScroll) { + // Word wrap is enabled. Ensure that we have up-to-date info about line height so that we scroll + // to the correct position. + // This avoids that the user has to repeat the ScrollTo() call several times when there are very long lines. + VisualLine vl = textView.GetOrConstructVisualLine(document.GetLineByNumber(line)); + double remainingHeight = scrollViewer.ViewportHeight / 2; + while (remainingHeight > 0) { + DocumentLine prevLine = vl.FirstDocumentLine.PreviousLine; + if (prevLine == null) + break; + vl = textView.GetOrConstructVisualLine(prevLine); + remainingHeight -= vl.Height; + } + } + Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, Math.Max(1, column)), VisualYPosition.LineMiddle); double verticalPos = p.Y - scrollViewer.ViewportHeight / 2; if (Math.Abs(verticalPos - scrollViewer.VerticalOffset) > MinimumScrollPercentage * scrollViewer.ViewportHeight) {