Skip to content

Commit 5e42c80

Browse files
authored
Add RoundedSuperellipseBorder and apply it to CupertinoActionSheet (#166303)
This PR creates a new class `RoundedSuperellipseBorder`, which is the main way to draw a rounded superellipse with filling and/or stroking. The new class is very similar to `RoundedRectangleBorder` and shares a lot of private code, therefore they reside in the same file. For demonstration purposes, the rounded superellipse is also applied to `CupertinoActionSheet`, whose cancel button was drawn with the border class. https://github.com/user-attachments/assets/39599dcf-5cf1-46e1-ab34-8c477cbef9d4 (Sadly this demo wouldn't fit for dartpad because rounded superellipses are not yet supported on Web.) ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent 242f413 commit 5e42c80

File tree

6 files changed

+514
-66
lines changed

6 files changed

+514
-66
lines changed

packages/flutter/lib/src/cupertino/dialog.dart

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ class _CupertinoActionSheetState extends State<CupertinoActionSheet> {
12991299

13001300
final List<Widget> children = <Widget>[
13011301
Flexible(
1302-
child: ClipRRect(
1302+
child: ClipRSuperellipse(
13031303
borderRadius: const BorderRadius.all(Radius.circular(12.0)),
13041304
child: BackdropFilter(
13051305
filter: ImageFilter.blur(
@@ -1593,24 +1593,30 @@ class _ActionSheetButtonBackgroundState extends State<_ActionSheetButtonBackgrou
15931593

15941594
@override
15951595
Widget build(BuildContext context) {
1596-
late final Color backgroundColor;
1597-
BorderRadius? borderRadius;
1596+
late final Widget child;
15981597
if (!widget.isCancel) {
1599-
backgroundColor = widget.pressed ? _kActionSheetPressedColor : _kActionSheetBackgroundColor;
1598+
child = ColoredBox(
1599+
color: CupertinoDynamicColor.resolve(
1600+
widget.pressed ? _kActionSheetPressedColor : _kActionSheetBackgroundColor,
1601+
context,
1602+
),
1603+
child: widget.child,
1604+
);
16001605
} else {
1601-
backgroundColor = widget.pressed ? _kActionSheetCancelPressedColor : _kActionSheetCancelColor;
1602-
borderRadius = const BorderRadius.all(Radius.circular(_kCornerRadius));
1603-
}
1604-
return MetaData(
1605-
metaData: this,
1606-
child: Container(
1607-
decoration: BoxDecoration(
1608-
color: CupertinoDynamicColor.resolve(backgroundColor, context),
1609-
borderRadius: borderRadius,
1606+
child = DecoratedBox(
1607+
decoration: ShapeDecoration(
1608+
shape: const RoundedSuperellipseBorder(
1609+
borderRadius: BorderRadius.all(Radius.circular(_kCornerRadius)),
1610+
),
1611+
color: CupertinoDynamicColor.resolve(
1612+
widget.pressed ? _kActionSheetCancelPressedColor : _kActionSheetCancelColor,
1613+
context,
1614+
),
16101615
),
16111616
child: widget.child,
1612-
),
1613-
);
1617+
);
1618+
}
1619+
return MetaData(metaData: this, child: child);
16141620
}
16151621
}
16161622

packages/flutter/lib/src/painting/box_border.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ import 'edge_insets.dart';
2424
/// interpolated or animated. The [Border] class cannot interpolate between
2525
/// different shapes.
2626
enum BoxShape {
27-
/// An axis-aligned, 2D rectangle. May have rounded corners (described by a
28-
/// [BorderRadius]). The edges of the rectangle will match the edges of the box
29-
/// into which the [Border] or [BoxDecoration] is painted.
27+
/// An axis-aligned rectangle, optionally with rounded corners.
28+
///
29+
/// The amount of corner rounding, if any, is determined by the border radius
30+
/// specified by classes such as [BoxDecoration] or [Border]. The rectangle's
31+
/// edges match those of the box in which it is painted.
3032
///
3133
/// See also:
3234
///

packages/flutter/lib/src/painting/box_decoration.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ import 'image_provider.dart';
2828
///
2929
/// The box has a [border], a body, and may cast a [boxShadow].
3030
///
31-
/// The [shape] of the box can be a circle or a rectangle. If it is a rectangle,
32-
/// then the [borderRadius] property controls the roundness of the corners.
31+
/// The [shape] of the box can be [BoxShape.circle] or [BoxShape.rectangle]. If
32+
/// it is [BoxShape.rectangle], then the [borderRadius] property can be used to
33+
/// make it a rounded rectangle ([RRect]).
3334
///
3435
/// The body of the box is painted in layers. The bottom-most layer is the
3536
/// [color], which fills the box. Above that is the [gradient], which also fills

0 commit comments

Comments
 (0)