Expose "MinimumDistanceToViewBorder"
This is request from the message board on the CodeProject article:
Hey,
could you please make the "MinimumDistanceToViewBorder" in Caret.cs to a property or so. Reason:
- If I move the caret with the mouse the SelectionMouseHandler calls BringCaretToView(5.0). This is OK.
- If I just go into the last visible line and enter a text BringCaretToView(MinimumDistanceToViewBorder) is called. In my opinion MinimumDistanceToViewBorder = 30 is far to large. The whole text just jumps to the top and the user looses the context. I could not find a way ro reduce MinimumDistanceToViewBorder to 5.0. Even with reflection there was no success, because it is a constant.
What purpose does MinimumDistanceToViewBorder even serve? I think we need to distinguish between the vertical and horizontal cases here. Vertically, the border
- ensures the text doesn't look cut off
- allows seeing some context when moving through the document using up/down arrows.
The first point only requires that the line containing the cursor is fully visible (plus maybe 1 or 2 pixels border, but that would run the risk of seeing the bottom pixel of the previous line's descenders). Note that the caret rectangle may be smaller than the line (LineTop vs. TextTop) - we should use the full line boundaries. This is what most text editors seem to do.
The second point requires a larger border, but that should be a configurable feature (disabled by default, because it doesn't make sense for small text fields). It should probably also only trigger when moving with the up/down arrow keys, not when typing text, to avoid the jump back after using the mouse selection feature.
Horizontally, the MinimumDistanceToViewBorder:
- ensures the caret looks like a line, not like a part of the border around the editor.
- gives some context by showing the next character after the caret.
For the first point, a distance of 1 pixel is sufficient. Other editors seem to allow the caret to get quite close to the border, but then scroll by more than just a single character, so that some context becomes visible. By scrolling in larger increments, these editors also avoid scrolling once per character (which AvalonEdit currently does not do). Not sure what we should do here -- no one has complained about the horizontal behavior yet, so I guess that can stay the way it is for now.
Note that the 'selecting text outside the editor boundaries causes the editor to scroll' feature is a side effect of ensuring the caret is visible. Because the mouse offset is currently clamped to the range (0,textView.ActualHeight), decreasing the border so that the next line is not visible may break this feature. If we fix it by clamping less aggressively, we'll need to implement the TODO in TextView.GetVisualLineFromVisualTop().
(note: don't forget to change the clamping in both SelectionMouseHandler and LineNumberMargin)