Skip to content

Commit 5b9c46b

Browse files
authored
Merge pull request #190 from lellid/PrecisePositioning2
Allow vertical scroll positioning with pixel accuracy
2 parents b1f625d + b8d1c28 commit 5b9c46b

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

ICSharpCode.AvalonEdit/TextEditor.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,8 +1116,21 @@ public void ScrollToLine(int line)
11161116
/// </summary>
11171117
public void ScrollTo(int line, int column)
11181118
{
1119-
const double MinimumScrollPercentage = 0.3;
1119+
const double MinimumScrollFraction = 0.3;
1120+
ScrollTo(line, column, VisualYPosition.LineMiddle, null != scrollViewer ? scrollViewer.ViewportHeight / 2 : 0.0, MinimumScrollFraction);
1121+
}
11201122

1123+
/// <summary>
1124+
/// Scrolls to the specified line/column.
1125+
/// This method requires that the TextEditor was already assigned a size (WPF layout must have run prior).
1126+
/// </summary>
1127+
/// <param name="line">Line to scroll to.</param>
1128+
/// <param name="column">Column to scroll to (important if wrapping is 'on', and for the horizontal scroll position).</param>
1129+
/// <param name="yPositionMode">The mode how to reference the Y position of the line.</param>
1130+
/// <param name="referencedVerticalViewPortOffset">Offset from the top of the viewport to where the referenced line/column should be positioned.</param>
1131+
/// <param name="minimumScrollFraction">The minimum vertical and/or horizontal scroll offset, expressed as fraction of the height or width of the viewport window, respectively.</param>
1132+
public void ScrollTo(int line, int column, VisualYPosition yPositionMode, double referencedVerticalViewPortOffset, double minimumScrollFraction)
1133+
{
11211134
TextView textView = textArea.TextView;
11221135
TextDocument document = textView.Document;
11231136
if (scrollViewer != null && document != null) {
@@ -1132,7 +1145,8 @@ public void ScrollTo(int line, int column)
11321145
// to the correct position.
11331146
// This avoids that the user has to repeat the ScrollTo() call several times when there are very long lines.
11341147
VisualLine vl = textView.GetOrConstructVisualLine(document.GetLineByNumber(line));
1135-
double remainingHeight = scrollViewer.ViewportHeight / 2;
1148+
double remainingHeight = referencedVerticalViewPortOffset;
1149+
11361150
while (remainingHeight > 0) {
11371151
DocumentLine prevLine = vl.FirstDocumentLine.PreviousLine;
11381152
if (prevLine == null)
@@ -1141,16 +1155,16 @@ public void ScrollTo(int line, int column)
11411155
remainingHeight -= vl.Height;
11421156
}
11431157
}
1144-
1145-
Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, Math.Max(1, column)), VisualYPosition.LineMiddle);
1146-
double verticalPos = p.Y - scrollViewer.ViewportHeight / 2;
1147-
if (Math.Abs(verticalPos - scrollViewer.VerticalOffset) > MinimumScrollPercentage * scrollViewer.ViewportHeight) {
1158+
1159+
Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, Math.Max(1, column)), yPositionMode);
1160+
double verticalPos = p.Y - referencedVerticalViewPortOffset;
1161+
if (Math.Abs(verticalPos - scrollViewer.VerticalOffset) > minimumScrollFraction * scrollViewer.ViewportHeight) {
11481162
scrollViewer.ScrollToVerticalOffset(Math.Max(0, verticalPos));
11491163
}
11501164
if (column > 0) {
11511165
if (p.X > scrollViewer.ViewportWidth - Caret.MinimumDistanceToViewBorder * 2) {
11521166
double horizontalPos = Math.Max(0, p.X - scrollViewer.ViewportWidth / 2);
1153-
if (Math.Abs(horizontalPos - scrollViewer.HorizontalOffset) > MinimumScrollPercentage * scrollViewer.ViewportWidth) {
1167+
if (Math.Abs(horizontalPos - scrollViewer.HorizontalOffset) > minimumScrollFraction * scrollViewer.ViewportWidth) {
11541168
scrollViewer.ScrollToHorizontalOffset(horizontalPos);
11551169
}
11561170
} else {

0 commit comments

Comments
 (0)