layout method
Implementation
@override
void layout(FConstraints constraints) {
final child = this.child!;
// tight on the non-scrolling axis (fill viewport), unbounded on the scrolling axis
child._doLayout(.new(
minWidth: scrollHorizontal ? 0 : constraints.maxWidth,
maxWidth: scrollHorizontal ? double.infinity : constraints.maxWidth,
minHeight: scrollVertical ? 0 : constraints.maxHeight,
maxHeight: scrollVertical ? double.infinity : constraints.maxHeight,
));
// the scroll view itself always fills exactly the space it was offered (it's the viewport)
size = .vec2(constraints.maxWidth, constraints.maxHeight);
// clamp scroll so you can't scroll past the content
final maxScrollX = (child.size.x - size.x).clamp(0, double.infinity);
final maxScrollY = (child.size.y - size.y).clamp(0, double.infinity);
if (autoScrollX && !_userScrolled) _scrollX = maxScrollX.toDouble();
if (autoScrollY && !_userScrolled) _scrollY = maxScrollY.toDouble();
_userScrolled = false;
// track last content height; only auto-scroll if content size changed
// if (autoScrollX && !_userScrolled && child.size.x != _lastChildWidth) {
// _scrollX = maxScrollX.toDouble();
// }
// if (autoScrollY && !_userScrolled && child.size.y != _lastChildHeight) {
// _scrollY = maxScrollY.toDouble();
// }
// _lastChildWidth = child.size.x;
// _lastChildHeight = child.size.y;
// _userScrolled = false;
_scrollX = _scrollX.clamp(0, maxScrollX).toDouble();
_scrollY = _scrollY.clamp(0, maxScrollY).toDouble();
child.localOffset = .vec2(-_scrollX, -_scrollY);
}