Implementing switch expressions in rendering/ (#143812)

This pull request is part of the effort to solve issue #136139.

The previous [`switch` expressions PR](https://github.com/flutter/flutter/pull/143496) was comprised of many simple changes throughout `flutter/lib/src/`, but due to some more in-depth refactoring in `flutter/lib/src/rendering/`, I decided to submit the changes to this directory as a separate pull request.

There was really just one function that I changed significantly; I'll add a comment for explanation.
This commit is contained in:
Nate 2024-02-26 10:36:21 -07:00 committed by GitHub
parent 469a2338ad
commit 60d28ad913
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 366 additions and 604 deletions

View file

@ -93,32 +93,27 @@ class RenderDecoratedSliver extends RenderProxySliver {
@override
void paint(PaintingContext context, Offset offset) {
if (child != null && child!.geometry!.visible) {
final SliverPhysicalParentData childParentData = child!.parentData! as SliverPhysicalParentData;
final Size childSize;
final Offset scrollOffset;
// In the case where the child sliver has infinite scroll extent, the decoration
// should only extend down to the bottom cache extent.
final double cappedMainAxisExtent = child!.geometry!.scrollExtent.isInfinite
? constraints.scrollOffset + child!.geometry!.cacheExtent + constraints.cacheOrigin
: child!.geometry!.scrollExtent;
switch (constraints.axis) {
case Axis.vertical:
childSize = Size(constraints.crossAxisExtent, cappedMainAxisExtent);
scrollOffset = Offset(0.0, -constraints.scrollOffset);
case Axis.horizontal:
childSize = Size(cappedMainAxisExtent, constraints.crossAxisExtent);
scrollOffset = Offset(-constraints.scrollOffset, 0.0);
}
final Offset childOffset = offset + childParentData.paintOffset;
if (position == DecorationPosition.background) {
_painter!.paint(context.canvas, childOffset + scrollOffset, configuration.copyWith(size: childSize));
}
context.paintChild(child!, childOffset);
if (position == DecorationPosition.foreground) {
_painter!.paint(context.canvas, childOffset + scrollOffset, configuration.copyWith(size: childSize));
}
if (child == null || !child!.geometry!.visible) {
return;
}
// In the case where the child sliver has infinite scroll extent, the decoration
// should only extend down to the bottom cache extent.
final double cappedMainAxisExtent = child!.geometry!.scrollExtent.isInfinite
? constraints.scrollOffset + child!.geometry!.cacheExtent + constraints.cacheOrigin
: child!.geometry!.scrollExtent;
final (Size childSize, Offset scrollOffset) = switch (constraints.axis) {
Axis.horizontal => (Size(cappedMainAxisExtent, constraints.crossAxisExtent), Offset(-constraints.scrollOffset, 0.0)),
Axis.vertical => (Size(constraints.crossAxisExtent, cappedMainAxisExtent), Offset(0.0, -constraints.scrollOffset)),
};
offset += (child!.parentData! as SliverPhysicalParentData).paintOffset;
void paintDecoration() => _painter!.paint(context.canvas, offset + scrollOffset, configuration.copyWith(size: childSize));
switch (position) {
case DecorationPosition.background:
paintDecoration();
context.paintChild(child!, offset);
case DecorationPosition.foreground:
context.paintChild(child!, offset);
paintDecoration();
}
}
}

View file

@ -67,14 +67,11 @@ class TextSelectionPoint {
@override
String toString() {
switch (direction) {
case TextDirection.ltr:
return '$point-ltr';
case TextDirection.rtl:
return '$point-rtl';
case null:
return '$point';
}
return switch (direction) {
TextDirection.ltr => '$point-ltr',
TextDirection.rtl => '$point-rtl',
null => '$point',
};
}
@override
@ -1686,32 +1683,26 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
Axis get _viewportAxis => _isMultiline ? Axis.vertical : Axis.horizontal;
Offset get _paintOffset {
switch (_viewportAxis) {
case Axis.horizontal:
return Offset(-offset.pixels, 0.0);
case Axis.vertical:
return Offset(0.0, -offset.pixels);
}
return switch (_viewportAxis) {
Axis.horizontal => Offset(-offset.pixels, 0.0),
Axis.vertical => Offset(0.0, -offset.pixels),
};
}
double get _viewportExtent {
assert(hasSize);
switch (_viewportAxis) {
case Axis.horizontal:
return size.width;
case Axis.vertical:
return size.height;
}
return switch (_viewportAxis) {
Axis.horizontal => size.width,
Axis.vertical => size.height,
};
}
double _getMaxScrollExtent(Size contentSize) {
assert(hasSize);
switch (_viewportAxis) {
case Axis.horizontal:
return math.max(0.0, contentSize.width - size.width);
case Axis.vertical:
return math.max(0.0, contentSize.height - size.height);
}
return switch (_viewportAxis) {
Axis.horizontal => math.max(0.0, contentSize.width - size.width),
Axis.vertical => math.max(0.0, contentSize.height - size.height),
};
}
// We need to check the paint offset here because during animation, the start of

View file

@ -223,23 +223,17 @@ bool? _startIsTopLeft(Axis direction, TextDirection? textDirection, VerticalDire
// If the relevant value of textDirection or verticalDirection is null, this returns null too.
switch (direction) {
case Axis.horizontal:
switch (textDirection) {
case TextDirection.ltr:
return true;
case TextDirection.rtl:
return false;
case null:
return null;
}
return switch (textDirection) {
TextDirection.ltr => true,
TextDirection.rtl => false,
null => null,
};
case Axis.vertical:
switch (verticalDirection) {
case VerticalDirection.down:
return true;
case VerticalDirection.up:
return false;
case null:
return null;
}
return switch (verticalDirection) {
VerticalDirection.down => true,
VerticalDirection.up => false,
null => null,
};
}
}
@ -656,21 +650,17 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}
double _getCrossSize(Size size) {
switch (_direction) {
case Axis.horizontal:
return size.height;
case Axis.vertical:
return size.width;
}
return switch (_direction) {
Axis.horizontal => size.height,
Axis.vertical => size.width,
};
}
double _getMainSize(Size size) {
switch (_direction) {
case Axis.horizontal:
return size.width;
case Axis.vertical:
return size.height;
}
return switch (_direction) {
Axis.horizontal => size.width,
Axis.vertical => size.height,
};
}
@override
@ -700,12 +690,10 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
constraints: constraints,
);
switch (_direction) {
case Axis.horizontal:
return constraints.constrain(Size(sizes.mainSize, sizes.crossSize));
case Axis.vertical:
return constraints.constrain(Size(sizes.crossSize, sizes.mainSize));
}
return constraints.constrain(switch (_direction) {
Axis.horizontal => Size(sizes.mainSize, sizes.crossSize),
Axis.vertical => Size(sizes.crossSize, sizes.mainSize),
});
}
FlutterError? _debugCheckConstraints({required BoxConstraints constraints, required bool reportParentConstraints}) {
@ -797,13 +785,20 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
// Determine used flex factor, size inflexible items, calculate free space.
int totalFlex = 0;
final double maxMainSize = _direction == Axis.horizontal ? constraints.maxWidth : constraints.maxHeight;
final bool canFlex = maxMainSize < double.infinity;
final double maxMainSize = _getMainSize(constraints.biggest);
final bool canFlex = maxMainSize.isFinite;
double crossSize = 0.0;
double allocatedSize = 0.0; // Sum of the sizes of the non-flexible children.
RenderBox? child = firstChild;
RenderBox? lastFlexChild;
final bool stretched = switch (crossAxisAlignment) {
CrossAxisAlignment.start => false,
CrossAxisAlignment.center => false,
CrossAxisAlignment.end => false,
CrossAxisAlignment.baseline => false,
CrossAxisAlignment.stretch => true,
};
while (child != null) {
final FlexParentData childParentData = child.parentData! as FlexParentData;
final int flex = _getFlex(child);
@ -811,22 +806,12 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
totalFlex += flex;
lastFlexChild = child;
} else {
final BoxConstraints innerConstraints;
if (crossAxisAlignment == CrossAxisAlignment.stretch) {
switch (_direction) {
case Axis.horizontal:
innerConstraints = BoxConstraints.tightFor(height: constraints.maxHeight);
case Axis.vertical:
innerConstraints = BoxConstraints.tightFor(width: constraints.maxWidth);
}
} else {
switch (_direction) {
case Axis.horizontal:
innerConstraints = BoxConstraints(maxHeight: constraints.maxHeight);
case Axis.vertical:
innerConstraints = BoxConstraints(maxWidth: constraints.maxWidth);
}
}
final BoxConstraints innerConstraints = switch ((stretched, _direction)) {
(true, Axis.horizontal) => BoxConstraints.tightFor(height: constraints.maxHeight),
(true, Axis.vertical) => BoxConstraints.tightFor(width: constraints.maxWidth),
(false, Axis.horizontal) => BoxConstraints(maxHeight: constraints.maxHeight),
(false, Axis.vertical) => BoxConstraints(maxWidth: constraints.maxWidth),
};
final Size childSize = layoutChild(child, innerConstraints);
allocatedSize += _getMainSize(childSize);
crossSize = math.max(crossSize, _getCrossSize(childSize));
@ -844,49 +829,21 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
while (child != null) {
final int flex = _getFlex(child);
if (flex > 0) {
final double maxChildExtent = canFlex ? (child == lastFlexChild ? (freeSpace - allocatedFlexSpace) : spacePerFlex * flex) : double.infinity;
late final double minChildExtent;
switch (_getFit(child)) {
case FlexFit.tight:
assert(maxChildExtent < double.infinity);
minChildExtent = maxChildExtent;
case FlexFit.loose:
minChildExtent = 0.0;
}
final BoxConstraints innerConstraints;
if (crossAxisAlignment == CrossAxisAlignment.stretch) {
switch (_direction) {
case Axis.horizontal:
innerConstraints = BoxConstraints(
minWidth: minChildExtent,
maxWidth: maxChildExtent,
minHeight: constraints.maxHeight,
maxHeight: constraints.maxHeight,
);
case Axis.vertical:
innerConstraints = BoxConstraints(
minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth,
minHeight: minChildExtent,
maxHeight: maxChildExtent,
);
}
} else {
switch (_direction) {
case Axis.horizontal:
innerConstraints = BoxConstraints(
minWidth: minChildExtent,
maxWidth: maxChildExtent,
maxHeight: constraints.maxHeight,
);
case Axis.vertical:
innerConstraints = BoxConstraints(
maxWidth: constraints.maxWidth,
minHeight: minChildExtent,
maxHeight: maxChildExtent,
);
}
}
final double maxChildExtent = switch (canFlex) {
true when child == lastFlexChild => freeSpace - allocatedFlexSpace,
true => spacePerFlex * flex,
false => double.infinity,
};
final double minChildExtent = switch (_getFit(child)) {
FlexFit.tight => maxChildExtent,
FlexFit.loose => 0.0,
};
assert(minChildExtent.isFinite);
final double minCrossSize = stretched ? _getCrossSize(constraints.biggest) : 0.0;
final BoxConstraints innerConstraints = switch (_direction) {
Axis.horizontal => constraints.copyWith(minHeight: minCrossSize, minWidth: minChildExtent, maxWidth: maxChildExtent),
Axis.vertical => constraints.copyWith(minWidth: minCrossSize, minHeight: minChildExtent, maxHeight: maxChildExtent),
};
final Size childSize = layoutChild(child, innerConstraints);
final double childMainSize = _getMainSize(childSize);
assert(childMainSize <= maxChildExtent);
@ -899,7 +856,10 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}
}
final double idealSize = canFlex && mainAxisSize == MainAxisSize.max ? maxMainSize : allocatedSize;
final double idealSize = switch (mainAxisSize) {
MainAxisSize.max when canFlex => maxMainSize,
MainAxisSize.max || MainAxisSize.min => allocatedSize,
};
return _LayoutSizes(
mainSize: idealSize,
crossSize: crossSize,
@ -974,34 +934,28 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
final double actualSizeDelta = actualSize - allocatedSize;
_overflow = math.max(0.0, -actualSizeDelta);
final double remainingSpace = math.max(0.0, actualSizeDelta);
late final double leadingSpace;
late final double betweenSpace;
final double betweenSpace = switch (_mainAxisAlignment) {
MainAxisAlignment.start || MainAxisAlignment.end || MainAxisAlignment.center => 0.0,
MainAxisAlignment.spaceBetween when childCount > 1 => remainingSpace / (childCount - 1),
MainAxisAlignment.spaceAround when childCount > 0 => remainingSpace / childCount,
MainAxisAlignment.spaceEvenly when childCount > 0 => remainingSpace / (childCount + 1),
MainAxisAlignment.spaceBetween || MainAxisAlignment.spaceAround || MainAxisAlignment.spaceEvenly => 0.0,
};
final double leadingSpace = switch (_mainAxisAlignment) {
MainAxisAlignment.start => 0.0,
MainAxisAlignment.end => remainingSpace,
MainAxisAlignment.center => remainingSpace / 2.0,
MainAxisAlignment.spaceBetween => 0.0,
MainAxisAlignment.spaceAround => betweenSpace / 2.0,
MainAxisAlignment.spaceEvenly => betweenSpace,
};
// flipMainAxis is used to decide whether to lay out
// left-to-right/top-to-bottom (false), or right-to-left/bottom-to-top
// (true). The _startIsTopLeft will return null if there's only one child
// and the relevant direction is null, in which case we arbitrarily decide
// to flip, but that doesn't have any detectable effect.
final bool flipMainAxis = !(_startIsTopLeft(direction, textDirection, verticalDirection) ?? true);
switch (_mainAxisAlignment) {
case MainAxisAlignment.start:
leadingSpace = 0.0;
betweenSpace = 0.0;
case MainAxisAlignment.end:
leadingSpace = remainingSpace;
betweenSpace = 0.0;
case MainAxisAlignment.center:
leadingSpace = remainingSpace / 2.0;
betweenSpace = 0.0;
case MainAxisAlignment.spaceBetween:
leadingSpace = 0.0;
betweenSpace = childCount > 1 ? remainingSpace / (childCount - 1) : 0.0;
case MainAxisAlignment.spaceAround:
betweenSpace = childCount > 0 ? remainingSpace / childCount : 0.0;
leadingSpace = betweenSpace / 2.0;
case MainAxisAlignment.spaceEvenly:
betweenSpace = childCount > 0 ? remainingSpace / (childCount + 1) : 0.0;
leadingSpace = betweenSpace;
}
// Position elements
double childMainPosition = flipMainAxis ? actualSize - leadingSpace : leadingSpace;
@ -1036,12 +990,10 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
if (flipMainAxis) {
childMainPosition -= _getMainSize(child.size);
}
switch (_direction) {
case Axis.horizontal:
childParentData.offset = Offset(childMainPosition, childCrossPosition);
case Axis.vertical:
childParentData.offset = Offset(childCrossPosition, childMainPosition);
}
childParentData.offset = switch (_direction) {
Axis.horizontal => Offset(childMainPosition, childCrossPosition),
Axis.vertical => Offset(childCrossPosition, childMainPosition),
};
if (flipMainAxis) {
childMainPosition -= betweenSpace;
} else {
@ -1104,13 +1056,10 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
// Simulate a child rect that overflows by the right amount. This child
// rect is never used for drawing, just for determining the overflow
// location and amount.
final Rect overflowChildRect;
switch (_direction) {
case Axis.horizontal:
overflowChildRect = Rect.fromLTWH(0.0, 0.0, size.width + _overflow, 0.0);
case Axis.vertical:
overflowChildRect = Rect.fromLTWH(0.0, 0.0, 0.0, size.height + _overflow);
}
final Rect overflowChildRect = switch (_direction) {
Axis.horizontal => Rect.fromLTWH(0.0, 0.0, size.width + _overflow, 0.0),
Axis.vertical => Rect.fromLTWH(0.0, 0.0, 0.0, size.height + _overflow),
};
paintOverflowIndicator(context, offset, Offset.zero & size, overflowChildRect, overflowHints: debugOverflowHints);
return true;
}());

View file

@ -252,42 +252,34 @@ class RenderListBody extends RenderBox
@override
double computeMinIntrinsicWidth(double height) {
switch (mainAxis) {
case Axis.horizontal:
return _getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicWidth(height));
case Axis.vertical:
return _getIntrinsicCrossAxis((RenderBox child) => child.getMinIntrinsicWidth(height));
}
return switch (mainAxis) {
Axis.horizontal => _getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicWidth(height)),
Axis.vertical => _getIntrinsicCrossAxis((RenderBox child) => child.getMinIntrinsicWidth(height)),
};
}
@override
double computeMaxIntrinsicWidth(double height) {
switch (mainAxis) {
case Axis.horizontal:
return _getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicWidth(height));
case Axis.vertical:
return _getIntrinsicCrossAxis((RenderBox child) => child.getMaxIntrinsicWidth(height));
}
return switch (mainAxis) {
Axis.horizontal => _getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicWidth(height)),
Axis.vertical => _getIntrinsicCrossAxis((RenderBox child) => child.getMaxIntrinsicWidth(height)),
};
}
@override
double computeMinIntrinsicHeight(double width) {
switch (mainAxis) {
case Axis.horizontal:
return _getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicHeight(width));
case Axis.vertical:
return _getIntrinsicCrossAxis((RenderBox child) => child.getMinIntrinsicHeight(width));
}
return switch (mainAxis) {
Axis.horizontal => _getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicHeight(width)),
Axis.vertical => _getIntrinsicCrossAxis((RenderBox child) => child.getMinIntrinsicHeight(width)),
};
}
@override
double computeMaxIntrinsicHeight(double width) {
switch (mainAxis) {
case Axis.horizontal:
return _getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicHeight(width));
case Axis.vertical:
return _getIntrinsicCrossAxis((RenderBox child) => child.getMaxIntrinsicHeight(width));
}
return switch (mainAxis) {
Axis.horizontal => _getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicHeight(width)),
Axis.vertical => _getIntrinsicCrossAxis((RenderBox child) => child.getMaxIntrinsicHeight(width)),
};
}
@override

View file

@ -843,15 +843,10 @@ class RenderParagraph extends RenderBox with ContainerRenderObjectMixin<RenderBo
locale: locale,
)..layout();
if (didOverflowWidth) {
double fadeEnd, fadeStart;
switch (textDirection) {
case TextDirection.rtl:
fadeEnd = 0.0;
fadeStart = fadeSizePainter.width;
case TextDirection.ltr:
fadeEnd = size.width;
fadeStart = fadeEnd - fadeSizePainter.width;
}
final (double fadeStart, double fadeEnd) = switch (textDirection) {
TextDirection.rtl => (fadeSizePainter.width, 0.0),
TextDirection.ltr => (size.width - fadeSizePainter.width, size.width),
};
_overflowShader = ui.Gradient.linear(
Offset(fadeStart, 0.0),
Offset(fadeEnd, 0.0),

View file

@ -1958,12 +1958,10 @@ class RenderPhysicalModel extends _RenderPhysicalModelBase<RRect> {
RRect get _defaultClip {
assert(hasSize);
final Rect rect = Offset.zero & size;
switch (_shape) {
case BoxShape.rectangle:
return (borderRadius ?? BorderRadius.zero).toRRect(rect);
case BoxShape.circle:
return RRect.fromRectXY(rect, rect.width / 2, rect.height / 2);
}
return switch (_shape) {
BoxShape.rectangle => (borderRadius ?? BorderRadius.zero).toRRect(rect),
BoxShape.circle => RRect.fromRectXY(rect, rect.width / 2, rect.height / 2),
};
}
@override

View file

@ -671,25 +671,21 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
@override
bool get sizedByParent {
switch (fit) {
case OverflowBoxFit.max:
return true;
case OverflowBoxFit.deferToChild:
// If deferToChild, the size will be as small as its child when non-overflowing,
// thus it cannot be sizedByParent.
return false;
}
return switch (fit) {
OverflowBoxFit.max => true,
// If deferToChild, the size will be as small as its child when non-overflowing,
// thus it cannot be sizedByParent.
OverflowBoxFit.deferToChild => false,
};
}
@override
@protected
Size computeDryLayout(covariant BoxConstraints constraints) {
switch (fit) {
case OverflowBoxFit.max:
return constraints.biggest;
case OverflowBoxFit.deferToChild:
return child?.getDryLayout(constraints) ?? constraints.smallest;
}
return switch (fit) {
OverflowBoxFit.max => constraints.biggest,
OverflowBoxFit.deferToChild => child?.getDryLayout(constraints) ?? constraints.smallest,
};
}
@override

View file

@ -150,12 +150,10 @@ enum GrowthDirection {
/// [AxisDirection] and a [GrowthDirection] and wish to compute the
/// [AxisDirection] in which growth will occur.
AxisDirection applyGrowthDirectionToAxisDirection(AxisDirection axisDirection, GrowthDirection growthDirection) {
switch (growthDirection) {
case GrowthDirection.forward:
return axisDirection;
case GrowthDirection.reverse:
return flipAxisDirection(axisDirection);
}
return switch (growthDirection) {
GrowthDirection.forward => axisDirection,
GrowthDirection.reverse => flipAxisDirection(axisDirection),
};
}
/// Flips the [ScrollDirection] if the [GrowthDirection] is
@ -169,12 +167,10 @@ AxisDirection applyGrowthDirectionToAxisDirection(AxisDirection axisDirection, G
/// [ScrollDirection] and a [GrowthDirection] and wish to compute the
/// [ScrollDirection] in which growth will occur.
ScrollDirection applyGrowthDirectionToScrollDirection(ScrollDirection scrollDirection, GrowthDirection growthDirection) {
switch (growthDirection) {
case GrowthDirection.forward:
return scrollDirection;
case GrowthDirection.reverse:
return flipScrollDirection(scrollDirection);
}
return switch (growthDirection) {
GrowthDirection.forward => scrollDirection,
GrowthDirection.reverse => flipScrollDirection(scrollDirection),
};
}
/// Immutable layout constraints for [RenderSliver] layout.
@ -442,19 +438,13 @@ class SliverConstraints extends Constraints {
/// This can be useful in combination with [axis] to view the [axisDirection]
/// and [growthDirection] in different terms.
GrowthDirection get normalizedGrowthDirection {
switch (axisDirection) {
case AxisDirection.down:
case AxisDirection.right:
return growthDirection;
case AxisDirection.up:
case AxisDirection.left:
switch (growthDirection) {
case GrowthDirection.forward:
return GrowthDirection.reverse;
case GrowthDirection.reverse:
return GrowthDirection.forward;
}
if (axisDirectionIsReversed(axisDirection)) {
return switch (growthDirection) {
GrowthDirection.forward => GrowthDirection.reverse,
GrowthDirection.reverse => GrowthDirection.forward,
};
}
return growthDirection;
}
@override
@ -1582,16 +1572,12 @@ abstract class RenderSliver extends RenderObject {
Size getAbsoluteSizeRelativeToOrigin() {
assert(geometry != null);
assert(!debugNeedsLayout);
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
return Size(constraints.crossAxisExtent, -geometry!.paintExtent);
case AxisDirection.right:
return Size(geometry!.paintExtent, constraints.crossAxisExtent);
case AxisDirection.down:
return Size(constraints.crossAxisExtent, geometry!.paintExtent);
case AxisDirection.left:
return Size(-geometry!.paintExtent, constraints.crossAxisExtent);
}
return switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
AxisDirection.up => Size(constraints.crossAxisExtent, -geometry!.paintExtent),
AxisDirection.down => Size(constraints.crossAxisExtent, geometry!.paintExtent),
AxisDirection.left => Size(-geometry!.paintExtent, constraints.crossAxisExtent),
AxisDirection.right => Size(geometry!.paintExtent, constraints.crossAxisExtent),
};
}
/// This returns the absolute [Size] of the sliver.
@ -1843,16 +1829,12 @@ abstract class RenderSliverSingleBoxAdapter extends RenderSliver with RenderObje
@protected
void setChildParentData(RenderObject child, SliverConstraints constraints, SliverGeometry geometry) {
final SliverPhysicalParentData childParentData = child.parentData! as SliverPhysicalParentData;
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
childParentData.paintOffset = Offset(0.0, -(geometry.scrollExtent - (geometry.paintExtent + constraints.scrollOffset)));
case AxisDirection.right:
childParentData.paintOffset = Offset(-constraints.scrollOffset, 0.0);
case AxisDirection.down:
childParentData.paintOffset = Offset(0.0, -constraints.scrollOffset);
case AxisDirection.left:
childParentData.paintOffset = Offset(-(geometry.scrollExtent - (geometry.paintExtent + constraints.scrollOffset)), 0.0);
}
childParentData.paintOffset = switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
AxisDirection.up => Offset(0.0, geometry.paintExtent + constraints.scrollOffset - geometry.scrollExtent),
AxisDirection.left => Offset(geometry.paintExtent + constraints.scrollOffset - geometry.scrollExtent, 0.0),
AxisDirection.right => Offset(-constraints.scrollOffset, 0.0),
AxisDirection.down => Offset(0.0, -constraints.scrollOffset),
};
}
@override
@ -1911,13 +1893,10 @@ class RenderSliverToBoxAdapter extends RenderSliverSingleBoxAdapter {
}
final SliverConstraints constraints = this.constraints;
child!.layout(constraints.asBoxConstraints(), parentUsesSize: true);
final double childExtent;
switch (constraints.axis) {
case Axis.horizontal:
childExtent = child!.size.width;
case Axis.vertical:
childExtent = child!.size.height;
}
final double childExtent = switch (constraints.axis) {
Axis.horizontal => child!.size.width,
Axis.vertical => child!.size.height,
};
final double paintedChildSize = calculatePaintOffset(constraints, from: 0.0, to: childExtent);
final double cacheExtent = calculateCacheOffset(constraints, from: 0.0, to: childExtent);

View file

@ -138,13 +138,10 @@ class RenderSliverFillRemaining extends RenderSliverSingleBoxAdapter {
double extent = constraints.viewportMainAxisExtent - constraints.precedingScrollExtent;
if (child != null) {
final double childExtent;
switch (constraints.axis) {
case Axis.horizontal:
childExtent = child!.getMaxIntrinsicWidth(constraints.crossAxisExtent);
case Axis.vertical:
childExtent = child!.getMaxIntrinsicHeight(constraints.crossAxisExtent);
}
final double childExtent = switch (constraints.axis) {
Axis.horizontal => child!.getMaxIntrinsicWidth(constraints.crossAxisExtent),
Axis.vertical => child!.getMaxIntrinsicHeight(constraints.crossAxisExtent),
};
// If the childExtent is greater than the computed extent, we want to use
// that instead of potentially cutting off the child. This allows us to
@ -213,13 +210,10 @@ class RenderSliverFillRemainingAndOverscroll extends RenderSliverSingleBoxAdapte
double maxExtent = constraints.remainingPaintExtent - math.min(constraints.overlap, 0.0);
if (child != null) {
final double childExtent;
switch (constraints.axis) {
case Axis.horizontal:
childExtent = child!.getMaxIntrinsicWidth(constraints.crossAxisExtent);
case Axis.vertical:
childExtent = child!.getMaxIntrinsicHeight(constraints.crossAxisExtent);
}
final double childExtent = switch (constraints.axis) {
Axis.horizontal => child!.getMaxIntrinsicWidth(constraints.crossAxisExtent),
Axis.vertical => child!.getMaxIntrinsicHeight(constraints.crossAxisExtent),
};
// If the childExtent is greater than the computed extent, we want to use
// that instead of potentially cutting off the child. This allows us to

View file

@ -110,12 +110,10 @@ class RenderSliverCrossAxisGroup extends RenderSliver with ContainerRenderObject
: 0.0;
final double childExtent = child.geometry!.crossAxisExtent ?? extentPerFlexValue * (childParentData.crossAxisFlex ?? 0);
// Set child parent data.
switch (constraints.axis) {
case Axis.vertical:
childParentData.paintOffset = Offset(offset, -paintCorrection);
case Axis.horizontal:
childParentData.paintOffset = Offset(-paintCorrection, offset);
}
childParentData.paintOffset = switch (constraints.axis) {
Axis.vertical => Offset(offset, -paintCorrection),
Axis.horizontal => Offset(-paintCorrection, offset),
};
offset += childExtent;
child = childAfter(child);
}
@ -229,14 +227,11 @@ class RenderSliverMainAxisGroup extends RenderSliver with ContainerRenderObjectM
@override
double childMainAxisPosition(RenderSliver child) {
switch (constraints.axisDirection) {
case AxisDirection.up:
case AxisDirection.down:
return (child.parentData! as SliverPhysicalParentData).paintOffset.dy;
case AxisDirection.left:
case AxisDirection.right:
return (child.parentData! as SliverPhysicalParentData).paintOffset.dx;
}
final Offset paintOffset = (child.parentData! as SliverPhysicalParentData).paintOffset;
return switch (constraints.axis) {
Axis.horizontal => paintOffset.dx,
Axis.vertical => paintOffset.dy,
};
}
@override
@ -269,12 +264,10 @@ class RenderSliverMainAxisGroup extends RenderSliver with ContainerRenderObjectM
);
final SliverGeometry childLayoutGeometry = child.geometry!;
final SliverPhysicalParentData childParentData = child.parentData! as SliverPhysicalParentData;
switch (constraints.axis) {
case Axis.vertical:
childParentData.paintOffset = Offset(0.0, beforeOffsetPaintExtent);
case Axis.horizontal:
childParentData.paintOffset = Offset(beforeOffsetPaintExtent, 0.0);
}
childParentData.paintOffset = switch (constraints.axis) {
Axis.vertical => Offset(0.0, beforeOffsetPaintExtent),
Axis.horizontal => Offset(beforeOffsetPaintExtent, 0.0),
};
offset += childLayoutGeometry.scrollExtent;
maxPaintExtent += child.geometry!.maxPaintExtent;
child = childAfter(child);
@ -304,12 +297,10 @@ class RenderSliverMainAxisGroup extends RenderSliver with ContainerRenderObjectM
final double remainingExtent = totalScrollExtent - constraints.scrollOffset;
if (childLayoutGeometry.paintExtent > remainingExtent) {
final double paintCorrection = childLayoutGeometry.paintExtent - remainingExtent;
switch (constraints.axis) {
case Axis.vertical:
childParentData.paintOffset = Offset(0.0, beforeOffsetPaintExtent - paintCorrection);
case Axis.horizontal:
childParentData.paintOffset = Offset(beforeOffsetPaintExtent - paintCorrection, 0.0);
}
childParentData.paintOffset = switch (constraints.axis) {
Axis.vertical => Offset(0.0, beforeOffsetPaintExtent - paintCorrection),
Axis.horizontal => Offset(beforeOffsetPaintExtent - paintCorrection, 0.0),
};
}
offset += child.geometry!.scrollExtent;
child = childAfter(child);

View file

@ -602,12 +602,10 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
@protected
double paintExtentOf(RenderBox child) {
assert(child.hasSize);
switch (constraints.axis) {
case Axis.horizontal:
return child.size.width;
case Axis.vertical:
return child.size.height;
}
return switch (constraints.axis) {
Axis.horizontal => child.size.width,
Axis.vertical => child.size.height,
};
}
@override

View file

@ -36,16 +36,12 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
/// doesn't know what direction it will be laid out in.
double get beforePadding {
assert(resolvedPadding != null);
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
return resolvedPadding!.bottom;
case AxisDirection.right:
return resolvedPadding!.left;
case AxisDirection.down:
return resolvedPadding!.top;
case AxisDirection.left:
return resolvedPadding!.right;
}
return switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
AxisDirection.up => resolvedPadding!.bottom,
AxisDirection.right => resolvedPadding!.left,
AxisDirection.down => resolvedPadding!.top,
AxisDirection.left => resolvedPadding!.right,
};
}
/// The padding in the scroll direction on the side furthest from the 0.0 scroll offset.
@ -54,16 +50,12 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
/// doesn't know what direction it will be laid out in.
double get afterPadding {
assert(resolvedPadding != null);
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
return resolvedPadding!.top;
case AxisDirection.right:
return resolvedPadding!.right;
case AxisDirection.down:
return resolvedPadding!.bottom;
case AxisDirection.left:
return resolvedPadding!.left;
}
return switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
AxisDirection.up => resolvedPadding!.top,
AxisDirection.right => resolvedPadding!.right,
AxisDirection.down => resolvedPadding!.bottom,
AxisDirection.left => resolvedPadding!.left,
};
}
/// The total padding in the [SliverConstraints.axisDirection]. (In other
@ -85,12 +77,10 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
/// doesn't know what direction it will be laid out in.
double get crossAxisPadding {
assert(resolvedPadding != null);
switch (constraints.axis) {
case Axis.horizontal:
return resolvedPadding!.vertical;
case Axis.vertical:
return resolvedPadding!.horizontal;
}
return switch (constraints.axis) {
Axis.horizontal => resolvedPadding!.vertical,
Axis.vertical => resolvedPadding!.horizontal,
};
}
@override
@ -103,22 +93,18 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
@override
void performLayout() {
final SliverConstraints constraints = this.constraints;
assert(resolvedPadding != null);
double paintOffset({required double from, required double to}) => calculatePaintOffset(constraints, from: from, to: to);
double cacheOffset({required double from, required double to}) => calculateCacheOffset(constraints, from: from, to: to);
assert(this.resolvedPadding != null);
final EdgeInsets resolvedPadding = this.resolvedPadding!;
final double beforePadding = this.beforePadding;
final double afterPadding = this.afterPadding;
final double mainAxisPadding = this.mainAxisPadding;
final double crossAxisPadding = this.crossAxisPadding;
if (child == null) {
final double paintExtent = calculatePaintOffset(
constraints,
from: 0.0,
to: mainAxisPadding,
);
final double cacheExtent = calculateCacheOffset(
constraints,
from: 0.0,
to: mainAxisPadding,
);
final double paintExtent = paintOffset(from: 0.0, to: mainAxisPadding);
final double cacheExtent = cacheOffset(from: 0.0, to: mainAxisPadding);
geometry = SliverGeometry(
scrollExtent: mainAxisPadding,
paintExtent: math.min(paintExtent, constraints.remainingPaintExtent),
@ -127,11 +113,7 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
);
return;
}
final double beforePaddingPaintExtent = calculatePaintOffset(
constraints,
from: 0.0,
to: beforePadding,
);
final double beforePaddingPaintExtent = paintOffset(from: 0.0, to: beforePadding);
double overlap = constraints.overlap;
if (overlap > 0) {
overlap = math.max(0.0, constraints.overlap - beforePaddingPaintExtent);
@ -141,8 +123,8 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
scrollOffset: math.max(0.0, constraints.scrollOffset - beforePadding),
cacheOrigin: math.min(0.0, constraints.cacheOrigin + beforePadding),
overlap: overlap,
remainingPaintExtent: constraints.remainingPaintExtent - calculatePaintOffset(constraints, from: 0.0, to: beforePadding),
remainingCacheExtent: constraints.remainingCacheExtent - calculateCacheOffset(constraints, from: 0.0, to: beforePadding),
remainingPaintExtent: constraints.remainingPaintExtent - paintOffset(from: 0.0, to: beforePadding),
remainingCacheExtent: constraints.remainingCacheExtent - cacheOffset(from: 0.0, to: beforePadding),
crossAxisExtent: math.max(0.0, constraints.crossAxisExtent - crossAxisPadding),
precedingScrollExtent: beforePadding + constraints.precedingScrollExtent,
),
@ -155,30 +137,19 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
);
return;
}
final double afterPaddingPaintExtent = calculatePaintOffset(
constraints,
from: beforePadding + childLayoutGeometry.scrollExtent,
to: mainAxisPadding + childLayoutGeometry.scrollExtent,
);
final double scrollExtent = childLayoutGeometry.scrollExtent;
final double beforePaddingCacheExtent = cacheOffset(from: 0.0, to: beforePadding);
final double afterPaddingCacheExtent = cacheOffset(from: beforePadding + scrollExtent, to: mainAxisPadding + scrollExtent);
final double afterPaddingPaintExtent = paintOffset(from: beforePadding + scrollExtent, to: mainAxisPadding + scrollExtent);
final double mainAxisPaddingCacheExtent = beforePaddingCacheExtent + afterPaddingCacheExtent;
final double mainAxisPaddingPaintExtent = beforePaddingPaintExtent + afterPaddingPaintExtent;
final double beforePaddingCacheExtent = calculateCacheOffset(
constraints,
from: 0.0,
to: beforePadding,
);
final double afterPaddingCacheExtent = calculateCacheOffset(
constraints,
from: beforePadding + childLayoutGeometry.scrollExtent,
to: mainAxisPadding + childLayoutGeometry.scrollExtent,
);
final double mainAxisPaddingCacheExtent = afterPaddingCacheExtent + beforePaddingCacheExtent;
final double paintExtent = math.min(
beforePaddingPaintExtent + math.max(childLayoutGeometry.paintExtent, childLayoutGeometry.layoutExtent + afterPaddingPaintExtent),
constraints.remainingPaintExtent,
);
geometry = SliverGeometry(
paintOrigin: childLayoutGeometry.paintOrigin,
scrollExtent: mainAxisPadding + childLayoutGeometry.scrollExtent,
scrollExtent: mainAxisPadding + scrollExtent,
paintExtent: paintExtent,
layoutExtent: math.min(mainAxisPaddingPaintExtent + childLayoutGeometry.layoutExtent, paintExtent),
cacheExtent: math.min(mainAxisPaddingCacheExtent + childLayoutGeometry.cacheExtent, constraints.remainingCacheExtent),
@ -189,18 +160,17 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
),
hasVisualOverflow: childLayoutGeometry.hasVisualOverflow,
);
final double calculatedOffset = switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
AxisDirection.up => paintOffset(from: resolvedPadding.bottom + scrollExtent, to: resolvedPadding.vertical + scrollExtent),
AxisDirection.left => paintOffset(from: resolvedPadding.right + scrollExtent, to: resolvedPadding.horizontal + scrollExtent),
AxisDirection.right => paintOffset(from: 0.0, to: resolvedPadding.left),
AxisDirection.down => paintOffset(from: 0.0, to: resolvedPadding.top),
};
final SliverPhysicalParentData childParentData = child!.parentData! as SliverPhysicalParentData;
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
childParentData.paintOffset = Offset(resolvedPadding!.left, calculatePaintOffset(constraints, from: resolvedPadding!.bottom + childLayoutGeometry.scrollExtent, to: resolvedPadding!.bottom + childLayoutGeometry.scrollExtent + resolvedPadding!.top));
case AxisDirection.right:
childParentData.paintOffset = Offset(calculatePaintOffset(constraints, from: 0.0, to: resolvedPadding!.left), resolvedPadding!.top);
case AxisDirection.down:
childParentData.paintOffset = Offset(resolvedPadding!.left, calculatePaintOffset(constraints, from: 0.0, to: resolvedPadding!.top));
case AxisDirection.left:
childParentData.paintOffset = Offset(calculatePaintOffset(constraints, from: resolvedPadding!.right + childLayoutGeometry.scrollExtent, to: resolvedPadding!.right + childLayoutGeometry.scrollExtent + resolvedPadding!.left), resolvedPadding!.top);
}
childParentData.paintOffset = switch (constraints.axis) {
Axis.horizontal => Offset(calculatedOffset, resolvedPadding.top),
Axis.vertical => Offset(resolvedPadding.left, calculatedOffset),
};
assert(beforePadding == this.beforePadding);
assert(afterPadding == this.afterPadding);
assert(mainAxisPadding == this.mainAxisPadding);
@ -233,14 +203,10 @@ abstract class RenderSliverEdgeInsetsPadding extends RenderSliver with RenderObj
double childCrossAxisPosition(RenderSliver child) {
assert(child == this.child);
assert(resolvedPadding != null);
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
case AxisDirection.down:
return resolvedPadding!.left;
case AxisDirection.left:
case AxisDirection.right:
return resolvedPadding!.top;
}
return switch (constraints.axis) {
Axis.horizontal => resolvedPadding!.top,
Axis.vertical => resolvedPadding!.left,
};
}
@override

View file

@ -152,12 +152,10 @@ abstract class RenderSliverPersistentHeader extends RenderSliver with RenderObje
return 0.0;
}
assert(child!.hasSize);
switch (constraints.axis) {
case Axis.vertical:
return child!.size.height;
case Axis.horizontal:
return child!.size.width;
}
return switch (constraints.axis) {
Axis.vertical => child!.size.height,
Axis.horizontal => child!.size.width,
};
}
bool _needsUpdateChild = true;
@ -298,16 +296,12 @@ abstract class RenderSliverPersistentHeader extends RenderSliver with RenderObje
@override
void paint(PaintingContext context, Offset offset) {
if (child != null && geometry!.visible) {
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
offset += Offset(0.0, geometry!.paintExtent - childMainAxisPosition(child!) - childExtent);
case AxisDirection.down:
offset += Offset(0.0, childMainAxisPosition(child!));
case AxisDirection.left:
offset += Offset(geometry!.paintExtent - childMainAxisPosition(child!) - childExtent, 0.0);
case AxisDirection.right:
offset += Offset(childMainAxisPosition(child!), 0.0);
}
offset += switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
AxisDirection.up => Offset(0.0, geometry!.paintExtent - childMainAxisPosition(child!) - childExtent),
AxisDirection.left => Offset(geometry!.paintExtent - childMainAxisPosition(child!) - childExtent, 0.0),
AxisDirection.right => Offset(childMainAxisPosition(child!), 0.0),
AxisDirection.down => Offset(0.0, childMainAxisPosition(child!)),
};
context.paintChild(child!, offset);
}
}
@ -446,17 +440,12 @@ abstract class RenderSliverPinnedPersistentHeader extends RenderSliverPersistent
? MatrixUtils.transformRect(descendant.getTransformTo(this), rect ?? descendant.paintBounds)
: rect;
Rect? newRect;
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
newRect = _trim(localBounds, bottom: childExtent);
case AxisDirection.right:
newRect = _trim(localBounds, left: 0);
case AxisDirection.down:
newRect = _trim(localBounds, top: 0);
case AxisDirection.left:
newRect = _trim(localBounds, right: childExtent);
}
final Rect? newRect = switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
AxisDirection.up => _trim(localBounds, bottom: childExtent),
AxisDirection.left => _trim(localBounds, right: childExtent),
AxisDirection.right => _trim(localBounds, left: 0),
AxisDirection.down => _trim(localBounds, top: 0),
};
super.showOnScreen(
descendant: this,

View file

@ -66,17 +66,10 @@ class RelativeRect {
required double end,
required double bottom,
}) {
double left;
double right;
switch (textDirection) {
case TextDirection.rtl:
left = end;
right = start;
case TextDirection.ltr:
left = start;
right = end;
}
final (double left, double right) = switch (textDirection) {
TextDirection.rtl => (end, start),
TextDirection.ltr => (start, end),
};
return RelativeRect.fromLTRB(left, top, right, bottom);
}

View file

@ -770,13 +770,10 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
final Canvas canvas = context.canvas;
RenderSliver? child = firstChild;
while (child != null) {
final Size size;
switch (axis) {
case Axis.vertical:
size = Size(child.constraints.crossAxisExtent, child.geometry!.layoutExtent);
case Axis.horizontal:
size = Size(child.geometry!.layoutExtent, child.constraints.crossAxisExtent);
}
final Size size = switch (axis) {
Axis.vertical => Size(child.constraints.crossAxisExtent, child.geometry!.layoutExtent),
Axis.horizontal => Size(child.geometry!.layoutExtent, child.constraints.crossAxisExtent),
};
canvas.drawRect(((offset + paintOffsetOf(child)) & size).deflate(0.5), paint);
child = childAfter(child);
}
@ -786,15 +783,10 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
@override
bool hitTestChildren(BoxHitTestResult result, { required Offset position }) {
double mainAxisPosition, crossAxisPosition;
switch (axis) {
case Axis.vertical:
mainAxisPosition = position.dy;
crossAxisPosition = position.dx;
case Axis.horizontal:
mainAxisPosition = position.dx;
crossAxisPosition = position.dy;
}
final (double mainAxisPosition, double crossAxisPosition) = switch (axis) {
Axis.vertical => (position.dy, position.dx),
Axis.horizontal => (position.dx, position.dy),
};
final SliverHitTestResult sliverResult = SliverHitTestResult.wrap(result);
for (final RenderSliver child in childrenInHitTestOrder) {
if (!child.geometry!.visible) {
@ -883,12 +875,10 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
assert(pivot.parent is RenderSliver); // TODO(abarth): Support other kinds of render objects besides slivers.
final RenderSliver pivotParent = pivot.parent! as RenderSliver;
growthDirection = pivotParent.constraints.growthDirection;
switch (axis) {
case Axis.horizontal:
pivotExtent = pivot.size.width;
case Axis.vertical:
pivotExtent = pivot.size.height;
}
pivotExtent = switch (axis) {
Axis.horizontal => pivot.size.width,
Axis.vertical => pivot.size.height,
};
rect ??= target.paintBounds;
rectLocal = MatrixUtils.transformRect(target.getTransformTo(pivot), rect);
} else if (onlySlivers) {
@ -1002,16 +992,12 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
Offset computeAbsolutePaintOffset(RenderSliver child, double layoutOffset, GrowthDirection growthDirection) {
assert(hasSize); // this is only usable once we have a size
assert(child.geometry != null);
switch (applyGrowthDirectionToAxisDirection(axisDirection, growthDirection)) {
case AxisDirection.up:
return Offset(0.0, size.height - (layoutOffset + child.geometry!.paintExtent));
case AxisDirection.right:
return Offset(layoutOffset, 0.0);
case AxisDirection.down:
return Offset(0.0, layoutOffset);
case AxisDirection.left:
return Offset(size.width - (layoutOffset + child.geometry!.paintExtent), 0.0);
}
return switch (applyGrowthDirectionToAxisDirection(axisDirection, growthDirection)) {
AxisDirection.up => Offset(0.0, size.height - layoutOffset - child.geometry!.paintExtent),
AxisDirection.left => Offset(size.width - layoutOffset - child.geometry!.paintExtent, 0.0),
AxisDirection.right => Offset(layoutOffset, 0.0),
AxisDirection.down => Offset(0.0, layoutOffset),
};
}
@override
@ -1427,16 +1413,10 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
}
assert(center!.parent == this);
final double mainAxisExtent;
final double crossAxisExtent;
switch (axis) {
case Axis.vertical:
mainAxisExtent = size.height;
crossAxisExtent = size.width;
case Axis.horizontal:
mainAxisExtent = size.width;
crossAxisExtent = size.height;
}
final (double mainAxisExtent, double crossAxisExtent) = switch (axis) {
Axis.vertical => (size.height, size.width),
Axis.horizontal => (size.width, size.height),
};
final double centerOffsetAdjustment = center!.centerOffsetAdjustment;
@ -1499,12 +1479,10 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
final double reverseDirectionRemainingPaintExtent = clampDouble(centerOffset, 0.0, mainAxisExtent);
final double forwardDirectionRemainingPaintExtent = clampDouble(mainAxisExtent - centerOffset, 0.0, mainAxisExtent);
switch (cacheExtentStyle) {
case CacheExtentStyle.pixel:
_calculatedCacheExtent = cacheExtent;
case CacheExtentStyle.viewport:
_calculatedCacheExtent = mainAxisExtent * _cacheExtent;
}
_calculatedCacheExtent = switch (cacheExtentStyle) {
CacheExtentStyle.pixel => cacheExtent,
CacheExtentStyle.viewport => mainAxisExtent * _cacheExtent,
};
final double fullCacheExtent = mainAxisExtent + 2 * _calculatedCacheExtent!;
final double centerCacheOffset = centerOffset + _calculatedCacheExtent!;
@ -1634,17 +1612,13 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
@override
double computeChildMainAxisPosition(RenderSliver child, double parentMainAxisPosition) {
final SliverPhysicalParentData childParentData = child.parentData! as SliverPhysicalParentData;
switch (applyGrowthDirectionToAxisDirection(child.constraints.axisDirection, child.constraints.growthDirection)) {
case AxisDirection.down:
return parentMainAxisPosition - childParentData.paintOffset.dy;
case AxisDirection.right:
return parentMainAxisPosition - childParentData.paintOffset.dx;
case AxisDirection.up:
return child.geometry!.paintExtent - (parentMainAxisPosition - childParentData.paintOffset.dy);
case AxisDirection.left:
return child.geometry!.paintExtent - (parentMainAxisPosition - childParentData.paintOffset.dx);
}
final Offset paintOffset = (child.parentData! as SliverPhysicalParentData).paintOffset;
return switch (applyGrowthDirectionToAxisDirection(child.constraints.axisDirection, child.constraints.growthDirection)) {
AxisDirection.down => parentMainAxisPosition - paintOffset.dy,
AxisDirection.right => parentMainAxisPosition - paintOffset.dx,
AxisDirection.up => child.geometry!.paintExtent - (parentMainAxisPosition - paintOffset.dy),
AxisDirection.left => child.geometry!.paintExtent - (parentMainAxisPosition - paintOffset.dx),
};
}
@override
@ -1826,12 +1800,10 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
if (firstChild == null) {
// Shrinkwrapping viewport only requires the cross axis to be bounded.
assert(_debugCheckHasBoundedCrossAxis());
switch (axis) {
case Axis.vertical:
size = Size(constraints.maxWidth, constraints.minHeight);
case Axis.horizontal:
size = Size(constraints.minWidth, constraints.maxHeight);
}
size = switch (axis) {
Axis.vertical => Size(constraints.maxWidth, constraints.minHeight),
Axis.horizontal => Size(constraints.minWidth, constraints.maxHeight),
};
offset.applyViewportDimension(0.0);
_maxScrollExtent = 0.0;
_shrinkWrapExtent = 0.0;
@ -1840,18 +1812,12 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
return;
}
final double mainAxisExtent;
final double crossAxisExtent;
// Shrinkwrapping viewport only requires the cross axis to be bounded.
assert(_debugCheckHasBoundedCrossAxis());
switch (axis) {
case Axis.vertical:
mainAxisExtent = constraints.maxHeight;
crossAxisExtent = constraints.maxWidth;
case Axis.horizontal:
mainAxisExtent = constraints.maxWidth;
crossAxisExtent = constraints.maxHeight;
}
final (double mainAxisExtent, double crossAxisExtent) = switch (axis) {
Axis.vertical => (constraints.maxHeight, constraints.maxWidth),
Axis.horizontal => (constraints.maxWidth, constraints.maxHeight),
};
double correction;
double effectiveExtent;
@ -1860,12 +1826,10 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
if (correction != 0.0) {
offset.correctBy(correction);
} else {
switch (axis) {
case Axis.vertical:
effectiveExtent = constraints.constrainHeight(_shrinkWrapExtent);
case Axis.horizontal:
effectiveExtent = constraints.constrainWidth(_shrinkWrapExtent);
}
effectiveExtent = switch (axis) {
Axis.vertical => constraints.constrainHeight(_shrinkWrapExtent),
Axis.horizontal => constraints.constrainWidth(_shrinkWrapExtent),
};
final bool didAcceptViewportDimension = offset.applyViewportDimension(effectiveExtent);
final bool didAcceptContentDimension = offset.applyContentDimensions(0.0, math.max(0.0, _maxScrollExtent - effectiveExtent));
if (didAcceptViewportDimension && didAcceptContentDimension) {
@ -1873,12 +1837,10 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
}
}
}
switch (axis) {
case Axis.vertical:
size = constraints.constrainDimensions(crossAxisExtent, effectiveExtent);
case Axis.horizontal:
size = constraints.constrainDimensions(effectiveExtent, crossAxisExtent);
}
size = switch (axis) {
Axis.vertical => constraints.constrainDimensions(crossAxisExtent, effectiveExtent),
Axis.horizontal => constraints.constrainDimensions(effectiveExtent, crossAxisExtent),
};
}
double _attemptLayout(double mainAxisExtent, double crossAxisExtent, double correctedOffset) {
@ -1898,12 +1860,10 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
// into the potentially infinite mainAxisExtent will overflow the end of
// the viewport.
_hasVisualOverflow = correctedOffset < 0.0;
switch (cacheExtentStyle) {
case CacheExtentStyle.pixel:
_calculatedCacheExtent = cacheExtent;
case CacheExtentStyle.viewport:
_calculatedCacheExtent = mainAxisExtent * _cacheExtent;
}
_calculatedCacheExtent = switch (cacheExtentStyle) {
CacheExtentStyle.pixel => cacheExtent,
CacheExtentStyle.viewport => mainAxisExtent * _cacheExtent,
};
return layoutChildSequence(
child: firstChild,
@ -1982,16 +1942,12 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
@override
double computeChildMainAxisPosition(RenderSliver child, double parentMainAxisPosition) {
assert(hasSize);
final SliverLogicalParentData childParentData = child.parentData! as SliverLogicalParentData;
switch (applyGrowthDirectionToAxisDirection(child.constraints.axisDirection, child.constraints.growthDirection)) {
case AxisDirection.down:
case AxisDirection.right:
return parentMainAxisPosition - childParentData.layoutOffset!;
case AxisDirection.up:
return (size.height - parentMainAxisPosition) - childParentData.layoutOffset!;
case AxisDirection.left:
return (size.width - parentMainAxisPosition) - childParentData.layoutOffset!;
}
final double layoutOffset = (child.parentData! as SliverLogicalParentData).layoutOffset!;
return switch (applyGrowthDirectionToAxisDirection(child.constraints.axisDirection, child.constraints.growthDirection)) {
AxisDirection.down || AxisDirection.right => parentMainAxisPosition - layoutOffset,
AxisDirection.up => size.height - parentMainAxisPosition - layoutOffset,
AxisDirection.left => size.width - parentMainAxisPosition - layoutOffset,
};
}
@override

View file

@ -69,14 +69,11 @@ enum ScrollDirection {
/// (and vice versa) and returns [ScrollDirection.idle] for
/// [ScrollDirection.idle].
ScrollDirection flipScrollDirection(ScrollDirection direction) {
switch (direction) {
case ScrollDirection.idle:
return ScrollDirection.idle;
case ScrollDirection.forward:
return ScrollDirection.reverse;
case ScrollDirection.reverse:
return ScrollDirection.forward;
}
return switch (direction) {
ScrollDirection.idle => ScrollDirection.idle,
ScrollDirection.forward => ScrollDirection.reverse,
ScrollDirection.reverse => ScrollDirection.forward,
};
}
/// Which part of the content inside the viewport should be visible.

View file

@ -454,42 +454,33 @@ class RenderWrap extends RenderBox
}
double _getMainAxisExtent(Size childSize) {
switch (direction) {
case Axis.horizontal:
return childSize.width;
case Axis.vertical:
return childSize.height;
}
return switch (direction) {
Axis.horizontal => childSize.width,
Axis.vertical => childSize.height,
};
}
double _getCrossAxisExtent(Size childSize) {
switch (direction) {
case Axis.horizontal:
return childSize.height;
case Axis.vertical:
return childSize.width;
}
return switch (direction) {
Axis.horizontal => childSize.height,
Axis.vertical => childSize.width,
};
}
Offset _getOffset(double mainAxisOffset, double crossAxisOffset) {
switch (direction) {
case Axis.horizontal:
return Offset(mainAxisOffset, crossAxisOffset);
case Axis.vertical:
return Offset(crossAxisOffset, mainAxisOffset);
}
return switch (direction) {
Axis.horizontal => Offset(mainAxisOffset, crossAxisOffset),
Axis.vertical => Offset(crossAxisOffset, mainAxisOffset),
};
}
double _getChildCrossAxisOffset(bool flipCrossAxis, double runCrossAxisExtent, double childCrossAxisExtent) {
final double freeSpace = runCrossAxisExtent - childCrossAxisExtent;
switch (crossAxisAlignment) {
case WrapCrossAlignment.start:
return flipCrossAxis ? freeSpace : 0.0;
case WrapCrossAlignment.end:
return flipCrossAxis ? 0.0 : freeSpace;
case WrapCrossAlignment.center:
return freeSpace / 2.0;
}
return switch (crossAxisAlignment) {
WrapCrossAlignment.start => flipCrossAxis ? freeSpace : 0.0,
WrapCrossAlignment.end => flipCrossAxis ? 0.0 : freeSpace,
WrapCrossAlignment.center => freeSpace / 2.0,
};
}
bool _hasVisualOverflow = false;
@ -501,16 +492,10 @@ class RenderWrap extends RenderBox
}
Size _computeDryLayout(BoxConstraints constraints, [ChildLayouter layoutChild = ChildLayoutHelper.dryLayoutChild]) {
final BoxConstraints childConstraints;
double mainAxisLimit = 0.0;
switch (direction) {
case Axis.horizontal:
childConstraints = BoxConstraints(maxWidth: constraints.maxWidth);
mainAxisLimit = constraints.maxWidth;
case Axis.vertical:
childConstraints = BoxConstraints(maxHeight: constraints.maxHeight);
mainAxisLimit = constraints.maxHeight;
}
final (BoxConstraints childConstraints, double mainAxisLimit) = switch (direction) {
Axis.horizontal => (BoxConstraints(maxWidth: constraints.maxWidth), constraints.maxWidth),
Axis.vertical => (BoxConstraints(maxHeight: constraints.maxHeight), constraints.maxHeight),
};
double mainAxisExtent = 0.0;
double crossAxisExtent = 0.0;
@ -541,12 +526,10 @@ class RenderWrap extends RenderBox
crossAxisExtent += runCrossAxisExtent;
mainAxisExtent = math.max(mainAxisExtent, runMainAxisExtent);
switch (direction) {
case Axis.horizontal:
return constraints.constrain(Size(mainAxisExtent, crossAxisExtent));
case Axis.vertical:
return constraints.constrain(Size(crossAxisExtent, mainAxisExtent));
}
return constraints.constrain(switch (direction) {
Axis.horizontal => Size(mainAxisExtent, crossAxisExtent),
Axis.vertical => Size(crossAxisExtent, mainAxisExtent),
});
}
@override