scrollBy method
Moves the view by delta rows, freezing it away from the live end.
viewport is how many rows the pane can draw, which only the pane knows.
Scrolling back down to the last row re-sticks rather than stopping one
short: a user who scrolls down to the newest line has said they want the
newest line, and leaving them frozen there would silently stop showing
output while looking exactly like a pane that is following it.
Implementation
void scrollBy(int delta, {required int viewport}) {
if (viewport <= 0) return;
final total = lines.length;
final maxTop = total - viewport;
// Nothing is off-screen, so there is nowhere to go and no way to be
// anywhere but live.
if (maxTop <= 0) {
if (_scrollTop != null) {
_scrollTop = null;
notifyListeners();
}
return;
}
final next = (_scrollTop ?? maxTop) + delta;
final clamped = next.clamp(0, maxTop);
// Landing on the last window means the newest line is on screen, which is
// what following the tail means.
final resolved = clamped >= maxTop ? null : clamped;
if (resolved == _scrollTop) return;
_scrollTop = resolved;
notifyListeners();
}