public void setChildParentData(RenderObject child, SliverConstraints constraints, SliverGeometry geometry) { var childParentData = (SliverPhysicalParentData)child.parentData; switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) { case AxisDirection.up: childParentData.paintOffset = new Offset(0.0f, -(geometry.scrollExtent - (geometry.paintExtent + constraints.scrollOffset))); break; case AxisDirection.right: childParentData.paintOffset = new Offset(-constraints.scrollOffset, 0.0f); break; case AxisDirection.down: childParentData.paintOffset = new Offset(0.0f, -constraints.scrollOffset); break; case AxisDirection.left: childParentData.paintOffset = new Offset(-(geometry.scrollExtent - (geometry.paintExtent + constraints.scrollOffset)), 0.0f); break; } }
public static bool _getRightWayUp(SliverConstraints constraints) { D.assert(constraints != null); bool rightWayUp = true; switch (constraints.axisDirection) { case AxisDirection.up: case AxisDirection.left: rightWayUp = false; break; case AxisDirection.down: case AxisDirection.right: rightWayUp = true; break; } switch (constraints.growthDirection) { case GrowthDirection.forward: break; case GrowthDirection.reverse: rightWayUp = !rightWayUp; break; } return(rightWayUp); }
protected override void performLayout() { SliverConstraints constraints = this.constraints; float extent = constraints.remainingPaintExtent - Mathf.Min(constraints.overlap, 0.0f); if (child != null) { child.layout(constraints.asBoxConstraints( minExtent: extent, maxExtent: extent )); } float paintedChildSize = calculatePaintOffset(constraints, from: 0.0f, to: extent); D.assert(paintedChildSize.isFinite()); D.assert(paintedChildSize >= 0.0); geometry = new SliverGeometry( scrollExtent: constraints.viewportMainAxisExtent, paintExtent: paintedChildSize, maxPaintExtent: paintedChildSize, hasVisualOverflow: extent > constraints.remainingPaintExtent || constraints.scrollOffset > 0.0 ); if (child != null) { setChildParentData(child, constraints, geometry); } }
public float calculateCacheOffset(SliverConstraints constraints, float from, float to) { D.assert(from <= to); float a = constraints.scrollOffset + constraints.cacheOrigin; float b = constraints.scrollOffset + constraints.remainingCacheExtent; return((to.clamp(a, b) - from.clamp(a, b)).clamp(0.0f, constraints.remainingCacheExtent)); }
public double calculateCacheOffset(SliverConstraints constraints, double from, double to) { D.assert(from <= to); double a = constraints.scrollOffset + constraints.cacheOrigin; double b = constraints.scrollOffset + constraints.remainingCacheExtent; return((to.clamp(a, b) - from.clamp(a, b)).clamp(0.0, constraints.remainingCacheExtent)); }
protected virtual double estimateMaxScrollOffset(SliverConstraints constraints, int firstIndex = 0, int lastIndex = 0, double leadingScrollOffset = 0.0, double trailingScrollOffset = 0.0 ) { return(this.childManager.estimateMaxScrollOffset( constraints, firstIndex: firstIndex, lastIndex: lastIndex, leadingScrollOffset: leadingScrollOffset, trailingScrollOffset: trailingScrollOffset )); }
protected virtual float estimateMaxScrollOffset( SliverConstraints constraints, int firstIndex = 0, int lastIndex = 0, float leadingScrollOffset = 0.0f, float trailingScrollOffset = 0.0f ) { return(childManager.estimateMaxScrollOffset( constraints, firstIndex: firstIndex, lastIndex: lastIndex, leadingScrollOffset: leadingScrollOffset, trailingScrollOffset: trailingScrollOffset )); }
protected override void performLayout() { SliverConstraints constraints = this.constraints; float extent = constraints.viewportMainAxisExtent - constraints.precedingScrollExtent; if (child != null) { float childExtent = 0f; switch (constraints.axis) { case Axis.horizontal: childExtent = child.getMaxIntrinsicWidth(constraints.crossAxisExtent); break; case Axis.vertical: childExtent = child.getMaxIntrinsicHeight(constraints.crossAxisExtent); break; } extent = Mathf.Max(extent, childExtent); child.layout(constraints.asBoxConstraints( minExtent: extent, maxExtent: extent )); } D.assert(extent.isFinite(), () => "The calculated extent for the child of SliverFillRemaining is not finite. " + "This can happen if the child is a scrollable, in which case, the " + "hasScrollBody property of SliverFillRemaining should not be set to " + "false." ); float paintedChildSize = calculatePaintOffset(constraints, from: 0.0f, to: extent); D.assert(paintedChildSize.isFinite()); D.assert(paintedChildSize >= 0.0); geometry = new SliverGeometry( scrollExtent: extent, paintExtent: paintedChildSize, maxPaintExtent: paintedChildSize, hasVisualOverflow: extent > constraints.remainingPaintExtent || constraints.scrollOffset > 0.0 ); if (child != null) { setChildParentData(child, constraints, geometry); } }
protected override float estimateMaxScrollOffset(SliverConstraints constraints, int firstIndex = 0, int lastIndex = 0, float leadingScrollOffset = 0.0f, float trailingScrollOffset = 0.0f ) { float padding = this._padding; return(this.childManager.estimateMaxScrollOffset( constraints, firstIndex: firstIndex, lastIndex: lastIndex, leadingScrollOffset: leadingScrollOffset - padding, trailingScrollOffset: trailingScrollOffset - padding ) + padding + padding); }
protected override double estimateMaxScrollOffset(SliverConstraints constraints, int firstIndex = 0, int lastIndex = 0, double leadingScrollOffset = 0.0, double trailingScrollOffset = 0.0 ) { double padding = this._padding; return(this.childManager.estimateMaxScrollOffset( constraints, firstIndex: firstIndex, lastIndex: lastIndex, leadingScrollOffset: leadingScrollOffset - padding, trailingScrollOffset: trailingScrollOffset - padding ) + padding + padding); }
protected override void performLayout() { if (child == null) { geometry = SliverGeometry.zero; return; } SliverConstraints constraints = this.constraints; child.layout(constraints.asBoxConstraints(), parentUsesSize: true); float childExtent = 0.0f; switch (constraints.axis) { case Axis.horizontal: childExtent = child.size.width; break; case Axis.vertical: childExtent = child.size.height; break; } float paintedChildSize = calculatePaintOffset(constraints, from: 0.0f, to: childExtent); float cacheExtent = calculateCacheOffset(constraints, from: 0.0f, to: childExtent); D.assert(paintedChildSize.isFinite()); D.assert(paintedChildSize >= 0.0f); geometry = new SliverGeometry( scrollExtent: childExtent, paintExtent: paintedChildSize, cacheExtent: cacheExtent, maxPaintExtent: childExtent, hitTestExtent: paintedChildSize, hasVisualOverflow: childExtent > constraints.remainingPaintExtent || constraints.scrollOffset > 0.0f ); setChildParentData(child, constraints, geometry); }
protected override void performLayout() { SliverConstraints constraints = this.constraints; float? maxExtent = this.maxExtent; if (((constraints.scrollOffset < _lastActualScrollOffset) || (_effectiveScrollOffset < maxExtent))) { float delta = _lastActualScrollOffset - constraints.scrollOffset; bool allowFloatingExpansion = constraints.userScrollDirection == ScrollDirection.forward; if (allowFloatingExpansion) { if (_effectiveScrollOffset > maxExtent) { _effectiveScrollOffset = maxExtent ?? 0.0f; } } else { if (delta > 0.0f) { delta = 0.0f; } } _effectiveScrollOffset = (_effectiveScrollOffset - delta).clamp(0.0f, constraints.scrollOffset); } else { _effectiveScrollOffset = constraints.scrollOffset; } bool overlapsContent = _effectiveScrollOffset < constraints.scrollOffset; layoutChild( _effectiveScrollOffset, maxExtent ?? 0.0f, overlapsContent: overlapsContent ); _childPosition = updateGeometry(); _lastActualScrollOffset = constraints.scrollOffset; }
protected override void performLayout() { SliverConstraints constraints = this.constraints; float? maxExtent = this.maxExtent; bool overlapsContent = constraints.overlap > 0.0f; layoutChild(constraints.scrollOffset, maxExtent ?? 0.0f, overlapsContent: overlapsContent); float effectiveRemainingPaintExtent = Mathf.Max(0, constraints.remainingPaintExtent - constraints.overlap); float?layoutExtent = (maxExtent - constraints.scrollOffset)?.clamp(0.0f, effectiveRemainingPaintExtent); float stretchOffset = stretchConfiguration != null? constraints.overlap.abs() : 0.0f; geometry = new SliverGeometry( scrollExtent: maxExtent ?? 0.0f, paintOrigin: constraints.overlap, paintExtent: Mathf.Min(childExtent, effectiveRemainingPaintExtent), layoutExtent: layoutExtent, maxPaintExtent: (maxExtent ?? 0.0f) + stretchOffset, maxScrollObstructionExtent: minExtent ?? 0.0f, cacheExtent: layoutExtent > 0.0f ? -constraints.cacheOrigin + layoutExtent : layoutExtent, hasVisualOverflow: true ); }
protected override void performLayout() { SliverConstraints constraints = this.constraints; childManager.didStartLayout(); childManager.setDidUnderflow(false); float itemExtent = this.itemExtent; float scrollOffset = constraints.scrollOffset + constraints.cacheOrigin; D.assert(scrollOffset >= 0.0); float remainingExtent = constraints.remainingCacheExtent; D.assert(remainingExtent >= 0.0); float targetEndScrollOffset = scrollOffset + remainingExtent; BoxConstraints childConstraints = constraints.asBoxConstraints( minExtent: itemExtent, maxExtent: itemExtent ); int firstIndex = getMinChildIndexForScrollOffset(scrollOffset, itemExtent); int?targetLastIndex = targetEndScrollOffset.isFinite() ? getMaxChildIndexForScrollOffset(targetEndScrollOffset, itemExtent) : (int?)null; if (firstChild != null) { int leadingGarbage = _calculateLeadingGarbage(firstIndex); int trailingGarbage = targetLastIndex == null ? 0: _calculateTrailingGarbage(targetLastIndex.Value); collectGarbage(leadingGarbage, trailingGarbage); } else { collectGarbage(0, 0); } if (firstChild == null) { if (!addInitialChild(index: firstIndex, layoutOffset: indexToLayoutOffset(itemExtent, firstIndex))) { float max; if (childManager.childCount != null) { max = computeMaxScrollOffset(constraints, itemExtent); } else if (firstIndex <= 0) { max = 0.0f; } else { // We will have to find it manually. int possibleFirstIndex = firstIndex - 1; while ( possibleFirstIndex > 0 && !addInitialChild( index: possibleFirstIndex, layoutOffset: indexToLayoutOffset(itemExtent, possibleFirstIndex) ) ) { possibleFirstIndex -= 1; } max = possibleFirstIndex * itemExtent; } geometry = new SliverGeometry( scrollExtent: max, maxPaintExtent: max ); childManager.didFinishLayout(); return; } } RenderBox trailingChildWithLayout = null; for (int index = indexOf(firstChild) - 1; index >= firstIndex; --index) { RenderBox child = insertAndLayoutLeadingChild(childConstraints); if (child == null) { geometry = new SliverGeometry(scrollOffsetCorrection: index * itemExtent); return; } var childParentData = (SliverMultiBoxAdaptorParentData)child.parentData; childParentData.layoutOffset = indexToLayoutOffset(itemExtent, index); D.assert(childParentData.index == index); trailingChildWithLayout = trailingChildWithLayout ?? child; } if (trailingChildWithLayout == null) { firstChild.layout(childConstraints); var childParentData = (SliverMultiBoxAdaptorParentData)firstChild.parentData; childParentData.layoutOffset = indexToLayoutOffset(itemExtent, firstIndex); trailingChildWithLayout = firstChild; } float estimatedMaxScrollOffset = float.PositiveInfinity; for (int index = indexOf(trailingChildWithLayout) + 1; targetLastIndex == null || index <= targetLastIndex; ++index) { RenderBox child = childAfter(trailingChildWithLayout); if (child == null || indexOf(child) != index) { child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout); if (child == null) { estimatedMaxScrollOffset = index * itemExtent; break; } } else { child.layout(childConstraints); } trailingChildWithLayout = child; var childParentData = (SliverMultiBoxAdaptorParentData)child.parentData; D.assert(childParentData.index == index); childParentData.layoutOffset = indexToLayoutOffset(itemExtent, childParentData.index); } int lastIndex = indexOf(lastChild); float leadingScrollOffset = indexToLayoutOffset(itemExtent, firstIndex); float trailingScrollOffset = indexToLayoutOffset(itemExtent, lastIndex + 1); D.assert(firstIndex == 0 || childScrollOffset(firstChild) - scrollOffset <= foundation_.precisionErrorTolerance); D.assert(debugAssertChildListIsNonEmptyAndContiguous()); D.assert(indexOf(firstChild) == firstIndex); D.assert(targetLastIndex == null || lastIndex <= targetLastIndex); estimatedMaxScrollOffset = Mathf.Min( estimatedMaxScrollOffset, estimateMaxScrollOffset( constraints, firstIndex: firstIndex, lastIndex: lastIndex, leadingScrollOffset: leadingScrollOffset, trailingScrollOffset: trailingScrollOffset ) ); float paintExtent = calculatePaintOffset( constraints, from: leadingScrollOffset, to: trailingScrollOffset ); float cacheExtent = calculateCacheOffset( constraints, from: leadingScrollOffset, to: trailingScrollOffset ); float targetEndScrollOffsetForPaint = constraints.scrollOffset + constraints.remainingPaintExtent; int?targetLastIndexForPaint = targetEndScrollOffsetForPaint.isFinite() ? getMaxChildIndexForScrollOffset(targetEndScrollOffsetForPaint, itemExtent) : (int?)null; geometry = new SliverGeometry( scrollExtent: estimatedMaxScrollOffset, paintExtent: paintExtent, cacheExtent: cacheExtent, maxPaintExtent: estimatedMaxScrollOffset, hasVisualOverflow: (targetLastIndexForPaint != null && lastIndex >= targetLastIndexForPaint) || constraints.scrollOffset > 0.0 ); if (estimatedMaxScrollOffset == trailingScrollOffset) { childManager.setDidUnderflow(true); } childManager.didFinishLayout(); }
protected float computeMaxScrollOffset(SliverConstraints constraints, float itemExtent) { return(childManager.childCount.Value * itemExtent); }
protected override void performLayout() { SliverConstraints constraints = this.constraints; D.assert(resolvedPadding != null); float?beforePadding = this.beforePadding; float?afterPadding = this.afterPadding; float?mainAxisPadding = this.mainAxisPadding; float?crossAxisPadding = this.crossAxisPadding; if (child == null) { geometry = new SliverGeometry( scrollExtent: mainAxisPadding ?? 0.0f, paintExtent: Mathf.Min(mainAxisPadding ?? 0.0f, constraints.remainingPaintExtent), maxPaintExtent: mainAxisPadding ?? 0.0f ); return; } child.layout( constraints.copyWith( scrollOffset: Mathf.Max(0.0f, constraints.scrollOffset - beforePadding ?? 0.0f), cacheOrigin: Mathf.Min(0.0f, constraints.cacheOrigin + beforePadding ?? 0.0f), overlap: 0.0f, remainingPaintExtent: constraints.remainingPaintExtent - calculatePaintOffset(constraints, from: 0.0f, to: beforePadding ?? 0.0f), remainingCacheExtent: constraints.remainingCacheExtent - calculateCacheOffset(constraints, from: 0.0f, to: beforePadding ?? 0.0f), crossAxisExtent: Mathf.Max(0.0f, constraints.crossAxisExtent - crossAxisPadding ?? 0.0f), precedingScrollExtent: beforePadding ?? 0.0f + constraints.precedingScrollExtent ), parentUsesSize: true ); SliverGeometry childLayoutGeometry = child.geometry; if (childLayoutGeometry.scrollOffsetCorrection != null) { geometry = new SliverGeometry( scrollOffsetCorrection: childLayoutGeometry.scrollOffsetCorrection ); return; } float beforePaddingPaintExtent = calculatePaintOffset( constraints, from: 0.0f, to: beforePadding ?? 0.0f ); float afterPaddingPaintExtent = calculatePaintOffset( constraints, from: beforePadding ?? 0.0f + childLayoutGeometry.scrollExtent, to: mainAxisPadding ?? 0.0f + childLayoutGeometry.scrollExtent ); float mainAxisPaddingPaintExtent = beforePaddingPaintExtent + afterPaddingPaintExtent; float beforePaddingCacheExtent = calculateCacheOffset( constraints, from: 0.0f, to: beforePadding ?? 0.0f ); float afterPaddingCacheExtent = calculateCacheOffset( constraints, from: beforePadding ?? 0.0f + childLayoutGeometry.scrollExtent, to: mainAxisPadding ?? 0.0f + childLayoutGeometry.scrollExtent ); float mainAxisPaddingCacheExtent = afterPaddingCacheExtent + beforePaddingCacheExtent; float paintExtent = Mathf.Min( beforePaddingPaintExtent + Mathf.Max(childLayoutGeometry.paintExtent, childLayoutGeometry.layoutExtent + afterPaddingPaintExtent), constraints.remainingPaintExtent ); geometry = new SliverGeometry( scrollExtent: (mainAxisPadding ?? 0.0f) + childLayoutGeometry.scrollExtent, paintExtent: paintExtent, layoutExtent: Mathf.Min(mainAxisPaddingPaintExtent + childLayoutGeometry.layoutExtent, paintExtent), cacheExtent: Mathf.Min(mainAxisPaddingCacheExtent + childLayoutGeometry.cacheExtent, constraints.remainingCacheExtent), maxPaintExtent: (mainAxisPadding ?? 0.0f) + childLayoutGeometry.maxPaintExtent, hitTestExtent: Mathf.Max( mainAxisPaddingPaintExtent + childLayoutGeometry.paintExtent, beforePaddingPaintExtent + childLayoutGeometry.hitTestExtent ), hasVisualOverflow: childLayoutGeometry.hasVisualOverflow ); SliverPhysicalParentData childParentData = child.parentData as SliverPhysicalParentData; switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) { case AxisDirection.up: childParentData.paintOffset = new Offset(resolvedPadding.left, calculatePaintOffset(constraints, from: resolvedPadding.bottom + childLayoutGeometry.scrollExtent, to: resolvedPadding.bottom + childLayoutGeometry.scrollExtent + resolvedPadding.top)); break; case AxisDirection.right: childParentData.paintOffset = new Offset(calculatePaintOffset(constraints, from: 0.0f, to: resolvedPadding.left), resolvedPadding.top); break; case AxisDirection.down: childParentData.paintOffset = new Offset(resolvedPadding.left, calculatePaintOffset(constraints, from: 0.0f, to: resolvedPadding.top)); break; case AxisDirection.left: childParentData.paintOffset = new Offset(calculatePaintOffset(constraints, from: resolvedPadding.right + childLayoutGeometry.scrollExtent, to: resolvedPadding.right + childLayoutGeometry.scrollExtent + resolvedPadding.left), resolvedPadding.top); break; } D.assert(childParentData.paintOffset != null); D.assert(beforePadding == this.beforePadding); D.assert(afterPadding == this.afterPadding); D.assert(mainAxisPadding == this.mainAxisPadding); D.assert(crossAxisPadding == this.crossAxisPadding); }
protected double computeMaxScrollOffset(SliverConstraints constraints, double itemExtent) { return(this.childManager.childCount.Value * itemExtent); }