Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/flutter/lib/rendering.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export 'src/rendering/flex.dart';
export 'src/rendering/flow.dart';
export 'src/rendering/image.dart';
export 'src/rendering/layer.dart';
export 'src/rendering/layout_helper.dart';
export 'src/rendering/list_body.dart';
export 'src/rendering/list_wheel_viewport.dart';
export 'src/rendering/mouse_cursor.dart';
Expand Down
91 changes: 65 additions & 26 deletions packages/flutter/lib/src/cupertino/action_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -721,40 +721,58 @@ class _RenderCupertinoAlert extends RenderBox {
return 0.0;
}

@override
void performLayout() {
final BoxConstraints constraints = this.constraints;
double _computeDividerThickness(BoxConstraints constraints) {
final bool hasDivider = contentSection!.getMaxIntrinsicHeight(constraints.maxWidth) > 0.0
&& actionsSection!.getMaxIntrinsicHeight(constraints.maxWidth) > 0.0;
final double dividerThickness = hasDivider ? _dividerThickness : 0.0;
return hasDivider ? _dividerThickness : 0.0;
}

_AlertSizes _computeSizes({required BoxConstraints constraints, required ChildLayouter layoutChild, required double dividerThickness}) {
final double minActionsHeight = actionsSection!.getMinIntrinsicHeight(constraints.maxWidth);

// Size alert content.
contentSection!.layout(
final Size contentSize = layoutChild(
contentSection!,
constraints.deflate(EdgeInsets.only(bottom: minActionsHeight + dividerThickness)),
parentUsesSize: true,
);
final Size contentSize = contentSection!.size;

// Size alert actions.
actionsSection!.layout(
final Size actionsSize = layoutChild(
actionsSection!,
constraints.deflate(EdgeInsets.only(top: contentSize.height + dividerThickness)),
parentUsesSize: true,
);
final Size actionsSize = actionsSection!.size;

// Calculate overall alert height.
final double actionSheetHeight = contentSize.height + dividerThickness + actionsSize.height;
return _AlertSizes(
size: Size(constraints.maxWidth, actionSheetHeight),
contentHeight: contentSize.height,
);
}

// Set our size now that layout calculations are complete.
size = Size(constraints.maxWidth, actionSheetHeight);
@override
Size computeDryLayout(BoxConstraints constraints) {
return _computeSizes(
constraints: constraints,
layoutChild: ChildLayoutHelper.dryLayoutChild,
dividerThickness: _computeDividerThickness(constraints),
).size;
}

@override
void performLayout() {
final BoxConstraints constraints = this.constraints;
final double dividerThickness = _computeDividerThickness(constraints);
final _AlertSizes alertSizes = _computeSizes(
constraints: constraints,
layoutChild: ChildLayoutHelper.layoutChild,
dividerThickness: dividerThickness,
);

size = alertSizes.size;

// Set the position of the actions box to sit at the bottom of the alert.
// The content box defaults to the top left, which is where we want it.
assert(actionsSection!.parentData is MultiChildLayoutParentData);
final MultiChildLayoutParentData actionParentData = actionsSection!.parentData! as MultiChildLayoutParentData;
actionParentData.offset = Offset(0.0, contentSize.height + dividerThickness);
actionParentData.offset = Offset(0.0, alertSizes.contentHeight + dividerThickness);
}

@override
Expand Down Expand Up @@ -806,6 +824,13 @@ class _RenderCupertinoAlert extends RenderBox {
}
}

class _AlertSizes {
const _AlertSizes({required this.size, required this.contentHeight});

final Size size;
final double contentHeight;
}

// Visual components of an alert that need to be explicitly sized and
// laid out at runtime.
enum _AlertSections {
Expand Down Expand Up @@ -1264,8 +1289,17 @@ class _RenderCupertinoAlertActions extends RenderBox
return heightAccumulation;
}

@override
Size computeDryLayout(BoxConstraints constraints) {
return _performLayout(constraints, dry: true);
}

@override
void performLayout() {
size = _performLayout(constraints, dry: false);
}

Size _performLayout(BoxConstraints constraints, {bool dry = false}) {
final BoxConstraints perButtonConstraints = constraints.copyWith(
minHeight: 0.0,
maxHeight: double.infinity,
Expand All @@ -1275,16 +1309,21 @@ class _RenderCupertinoAlertActions extends RenderBox
int index = 0;
double verticalOffset = 0.0;
while (child != null) {
child.layout(
perButtonConstraints,
parentUsesSize: true,
);

assert(child.parentData is MultiChildLayoutParentData);
final MultiChildLayoutParentData parentData = child.parentData! as MultiChildLayoutParentData;
parentData.offset = Offset(0.0, verticalOffset);
final Size childSize;
if (!dry) {
child.layout(
perButtonConstraints,
parentUsesSize: true,
);
childSize = child.size;
assert(child.parentData is MultiChildLayoutParentData);
final MultiChildLayoutParentData parentData = child.parentData! as MultiChildLayoutParentData;
parentData.offset = Offset(0.0, verticalOffset);
} else {
childSize = child.getDryLayout(constraints);
}

verticalOffset += child.size.height;
verticalOffset += childSize.height;
if (index < childCount - 1) {
// Add a gap for the next divider.
verticalOffset += dividerThickness;
Expand All @@ -1294,7 +1333,7 @@ class _RenderCupertinoAlertActions extends RenderBox
child = childAfter(child);
}

size = constraints.constrain(
return constraints.constrain(
Size(constraints.maxWidth, verticalOffset)
);
}
Expand Down
Loading