Example #1
0
        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;
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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));
        }
Example #5
0
        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));
        }
Example #6
0
 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
                ));
 }
Example #7
0
 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
                ));
 }
Example #8
0
        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);
            }
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        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;
        }
Example #13
0
        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
                );
        }
Example #14
0
        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();
        }
Example #15
0
 protected float computeMaxScrollOffset(SliverConstraints constraints, float itemExtent)
 {
     return(childManager.childCount.Value * itemExtent);
 }
Example #16
0
        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);
        }
Example #17
0
 protected double computeMaxScrollOffset(SliverConstraints constraints, double itemExtent)
 {
     return(this.childManager.childCount.Value * itemExtent);
 }