BTextView: Prevent scrolling if text rect is inside view rect

No horizontal (or vertical) scrolling allowed if the text rect is
inside the view rect in x (or y).

This fixes issues with right-aligned text views getting scrolled
within bounds becoming left-aligned text views. Prevent scrolling
so that this cannot happen unless text is outside the view.

You can still get DeskCalc to be in a scrolled over no-longer-
right-aligned state by scrolling and resizing repeatedly, but
it's better than before and it is at least fixable. This is most
likely a bug in DeskCalc.

This also fixes issues not being able to scroll all the way right
after scrolling left dragging with the mouse.

Do not set any limits in _PerformAutoScroll(), all limits are set
by the code that does the keyboard handling. Set x and y and call
_ScrollBy();

Update limits set in _ScrollBy() to accommodate both keyboard
and mouse (taking from mouse and using on keyboard as well).
This unifies keyboard and mouse scroll limits in x and y.

Change-Id: I0dd24ce03f9b95651bcee4e190564b77f0343863
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7161
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: John Scipione <jscipione@gmail.com>
This commit is contained in:
John Scipione 2023-12-01 18:53:49 -05:00 committed by Adrien Destugues
parent 0e673505eb
commit e26329ce22

View File

@ -5004,15 +5004,9 @@ BTextView::_PerformAutoScrolling()
else if (fWhere.x < bounds.left)
scrollBy.x = fWhere.x - bounds.left; // negative value
// prevent from scrolling out of view
if (scrollBy.x != 0.0) {
float rightMax = fTextRect.right + fLayoutData->rightInset;
if (bounds.right + scrollBy.x > rightMax)
scrollBy.x = rightMax - bounds.right;
float leftMin = fTextRect.left - fLayoutData->leftInset;
if (bounds.left + scrollBy.x < leftMin)
scrollBy.x = leftMin - bounds.left;
}
// prevent horizontal scrolling if text rect is inside view rect
if (fTextRect.left > bounds.left && fTextRect.right < bounds.right)
scrollBy.x = 0;
if (CountLines() > 1) {
// scroll in Y only if multiple lines!
@ -5020,20 +5014,14 @@ BTextView::_PerformAutoScrolling()
scrollBy.y = fWhere.y - bounds.bottom;
else if (fWhere.y < bounds.top)
scrollBy.y = fWhere.y - bounds.top; // negative value
// prevent from scrolling out of view
if (scrollBy.y != 0.0) {
float bottomMax = fTextRect.bottom + fLayoutData->bottomInset;
if (bounds.bottom + scrollBy.y > bottomMax)
scrollBy.y = bottomMax - bounds.bottom;
float topMin = fTextRect.top - fLayoutData->topInset;
if (bounds.top + scrollBy.y < topMin)
scrollBy.y = topMin - bounds.top;
}
}
// prevent vertical scrolling if text rect is inside view rect
if (fTextRect.top > bounds.top && fTextRect.bottom < bounds.bottom)
scrollBy.y = 0;
if (scrollBy != B_ORIGIN)
ScrollBy(scrollBy.x, scrollBy.y);
_ScrollBy(scrollBy.x, scrollBy.y);
}
@ -5094,15 +5082,22 @@ BTextView::_ScrollTo(float x, float y)
long viewWidth = bounds.IntegerWidth();
long viewHeight = bounds.IntegerHeight();
if (x > fTextRect.right - viewWidth)
x = fTextRect.right - viewWidth;
if (x < 0.0)
x = 0.0;
float minWidth = fTextRect.left - fLayoutData->leftInset;
float maxWidth = fTextRect.right + fLayoutData->rightInset - viewWidth;
float minHeight = fTextRect.top - fLayoutData->topInset;
float maxHeight = fTextRect.bottom + fLayoutData->bottomInset - viewHeight;
if (y > fTextRect.bottom + fLayoutData->bottomInset - viewHeight)
y = fTextRect.bottom + fLayoutData->bottomInset - viewHeight;
if (y < 0.0)
y = 0.0;
// set horizontal scroll limits
if (x > maxWidth)
x = maxWidth;
if (x < minWidth)
x = minWidth;
// set vertical scroll limits
if (y > maxHeight)
y = maxHeight;
if (y < minHeight)
y = minHeight;
ScrollTo(x, y);
}