Implement switch expressions in lib/src/material/ (#142634)

This PR is step 5 in the journey to solve issue #136139 and make the entire Flutter repo more readable.

(previous pull requests: #139048, #139882, #141591, #142279)

The current focus is on `packages/flutter/lib/src/material/`.  
The previous PR covered files in this directory starting with `a`, `b`, and `c`; this pull request is for `d` through `m`.
This commit is contained in:
Nate 2024-02-01 15:31:10 -07:00 committed by GitHub
parent 81574cba85
commit 5b947c889b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 146 additions and 256 deletions

View file

@ -119,13 +119,10 @@ class _DropdownMenuItemButton<T> extends StatefulWidget {
class _DropdownMenuItemButtonState<T> extends State<_DropdownMenuItemButton<T>> {
void _handleFocusChange(bool focused) {
final bool inTraditionalMode;
switch (FocusManager.instance.highlightMode) {
case FocusHighlightMode.touch:
inTraditionalMode = false;
case FocusHighlightMode.traditional:
inTraditionalMode = true;
}
final bool inTraditionalMode = switch (FocusManager.instance.highlightMode) {
FocusHighlightMode.touch => false,
FocusHighlightMode.traditional => true,
};
if (focused && inTraditionalMode) {
final _MenuLimits menuLimits = widget.route.getMenuLimits(
@ -377,13 +374,10 @@ class _DropdownMenuRouteLayout<T> extends SingleChildLayoutDelegate {
return true;
}());
assert(textDirection != null);
final double left;
switch (textDirection!) {
case TextDirection.rtl:
left = clampDouble(buttonRect.right, 0.0, size.width) - childSize.width;
case TextDirection.ltr:
left = clampDouble(buttonRect.left, 0.0, size.width - childSize.width);
}
final double left = switch (textDirection!) {
TextDirection.rtl => clampDouble(buttonRect.right, 0.0, size.width) - childSize.width,
TextDirection.ltr => clampDouble(buttonRect.left, 0.0, size.width - childSize.width),
};
return Offset(left, menuLimits.top);
}
@ -1379,28 +1373,17 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
Color get _iconColor {
// These colors are not defined in the Material Design spec.
final Brightness brightness = Theme.of(context).brightness;
if (_enabled) {
if (widget.iconEnabledColor != null) {
return widget.iconEnabledColor!;
}
switch (Theme.of(context).brightness) {
case Brightness.light:
return Colors.grey.shade700;
case Brightness.dark:
return Colors.white70;
}
return widget.iconEnabledColor ?? switch (brightness) {
Brightness.light => Colors.grey.shade700,
Brightness.dark => Colors.white70,
};
} else {
if (widget.iconDisabledColor != null) {
return widget.iconDisabledColor!;
}
switch (Theme.of(context).brightness) {
case Brightness.light:
return Colors.grey.shade400;
case Brightness.dark:
return Colors.white10;
}
return widget.iconDisabledColor ?? switch (brightness) {
Brightness.light => Colors.grey.shade400,
Brightness.dark => Colors.white10,
};
}
}

View file

@ -546,17 +546,10 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
// paddings so its leading icon will be aligned with the leading icon of
// the text field.
final double padding = entry.leadingIcon == null ? (leadingPadding ?? _kDefaultHorizontalPadding) : _kDefaultHorizontalPadding;
final ButtonStyle defaultStyle;
switch (textDirection) {
case TextDirection.rtl:
defaultStyle = MenuItemButton.styleFrom(
padding: EdgeInsets.only(left: _kDefaultHorizontalPadding, right: padding),
);
case TextDirection.ltr:
defaultStyle = MenuItemButton.styleFrom(
padding: EdgeInsets.only(left: padding, right: _kDefaultHorizontalPadding),
);
}
final ButtonStyle defaultStyle = switch (textDirection) {
TextDirection.rtl => MenuItemButton.styleFrom(padding: EdgeInsets.only(left: _kDefaultHorizontalPadding, right: padding)),
TextDirection.ltr => MenuItemButton.styleFrom(padding: EdgeInsets.only(left: padding, right: _kDefaultHorizontalPadding)),
};
ButtonStyle effectiveStyle = entry.style ?? defaultStyle;
final Color focusedBackgroundColor = effectiveStyle.foregroundColor?.resolve(<MaterialState>{MaterialState.focused})

View file

@ -152,12 +152,10 @@ class _ExpandIconState extends State<ExpandIcon> with SingleTickerProviderStateM
return widget.color!;
}
switch (Theme.of(context).brightness) {
case Brightness.light:
return Colors.black54;
case Brightness.dark:
return Colors.white60;
}
return switch (Theme.of(context).brightness) {
Brightness.light => Colors.black54,
Brightness.dark => Colors.white60,
};
}
@override

View file

@ -425,12 +425,10 @@ class FilledButton extends ButtonStyleButton {
/// [padding] is reduced from 24 to 16.
@override
ButtonStyle defaultStyleOf(BuildContext context) {
switch (_variant) {
case _FilledButtonVariant.filled:
return _FilledButtonDefaultsM3(context);
case _FilledButtonVariant.tonal:
return _FilledTonalButtonDefaultsM3(context);
}
return switch (_variant) {
_FilledButtonVariant.filled => _FilledButtonDefaultsM3(context),
_FilledButtonVariant.tonal => _FilledTonalButtonDefaultsM3(context),
};
}
/// Returns the [FilledButtonThemeData.style] of the closest

View file

@ -185,32 +185,20 @@ class FlexibleSpaceBar extends StatefulWidget {
class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
bool _getEffectiveCenterTitle(ThemeData theme) {
if (widget.centerTitle != null) {
return widget.centerTitle!;
}
switch (theme.platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
return false;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return true;
}
return widget.centerTitle ?? switch (theme.platform) {
TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.linux || TargetPlatform.windows => false,
TargetPlatform.iOS || TargetPlatform.macOS => true,
};
}
Alignment _getTitleAlignment(bool effectiveCenterTitle) {
if (effectiveCenterTitle) {
return Alignment.bottomCenter;
}
final TextDirection textDirection = Directionality.of(context);
switch (textDirection) {
case TextDirection.rtl:
return Alignment.bottomRight;
case TextDirection.ltr:
return Alignment.bottomLeft;
}
return switch (Directionality.of(context)) {
TextDirection.rtl => Alignment.bottomRight,
TextDirection.ltr => Alignment.bottomLeft,
};
}
double _getCollapsePadding(double t, FlexibleSpaceBarSettings settings) {

View file

@ -814,26 +814,22 @@ class _FABDefaultsM3 extends FloatingActionButtonThemeData {
@override
ShapeBorder? get shape {
switch (type) {
case _FloatingActionButtonType.regular:
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
case _FloatingActionButtonType.small:
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0)));
case _FloatingActionButtonType.large:
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(28.0)));
case _FloatingActionButtonType.extended:
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
}
return switch (type) {
_FloatingActionButtonType.regular => const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))),
_FloatingActionButtonType.small => const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0))),
_FloatingActionButtonType.large => const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(28.0))),
_FloatingActionButtonType.extended => const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))),
};
}
@override
double? get iconSize {
switch (type) {
case _FloatingActionButtonType.regular: return 24.0;
case _FloatingActionButtonType.small: return 24.0;
case _FloatingActionButtonType.large: return 36.0;
case _FloatingActionButtonType.extended: return 24.0;
}
return switch (type) {
_FloatingActionButtonType.regular => 24.0,
_FloatingActionButtonType.small => 24.0,
_FloatingActionButtonType.large => 36.0,
_FloatingActionButtonType.extended => 24.0,
};
}
@override EdgeInsetsGeometry? get extendedPadding => EdgeInsetsDirectional.only(start: hasChild && _isExtended ? 16.0 : 20.0, end: 20.0);

View file

@ -656,12 +656,10 @@ mixin FabStartOffsetX on StandardFabLocation {
/// Calculates x-offset for start-aligned [FloatingActionButtonLocation]s.
@override
double getOffsetX(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
switch (scaffoldGeometry.textDirection) {
case TextDirection.rtl:
return StandardFabLocation._rightOffsetX(scaffoldGeometry, adjustment);
case TextDirection.ltr:
return StandardFabLocation._leftOffsetX(scaffoldGeometry, adjustment);
}
return switch (scaffoldGeometry.textDirection) {
TextDirection.rtl => StandardFabLocation._rightOffsetX(scaffoldGeometry, adjustment),
TextDirection.ltr => StandardFabLocation._leftOffsetX(scaffoldGeometry, adjustment),
};
}
}
@ -679,12 +677,10 @@ mixin FabEndOffsetX on StandardFabLocation {
/// Calculates x-offset for end-aligned [FloatingActionButtonLocation]s.
@override
double getOffsetX(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
switch (scaffoldGeometry.textDirection) {
case TextDirection.rtl:
return StandardFabLocation._leftOffsetX(scaffoldGeometry, adjustment);
case TextDirection.ltr:
return StandardFabLocation._rightOffsetX(scaffoldGeometry, adjustment);
}
return switch (scaffoldGeometry.textDirection) {
TextDirection.rtl => StandardFabLocation._leftOffsetX(scaffoldGeometry, adjustment),
TextDirection.ltr => StandardFabLocation._rightOffsetX(scaffoldGeometry, adjustment),
};
}
}

View file

@ -944,16 +944,12 @@ class _IconButtonM3 extends ButtonStyleButton {
/// * `splashFactory` - Theme.splashFactory
@override
ButtonStyle defaultStyleOf(BuildContext context) {
switch (variant) {
case _IconButtonVariant.filled:
return _FilledIconButtonDefaultsM3(context, toggleable);
case _IconButtonVariant.filledTonal:
return _FilledTonalIconButtonDefaultsM3(context, toggleable);
case _IconButtonVariant.outlined:
return _OutlinedIconButtonDefaultsM3(context, toggleable);
case _IconButtonVariant.standard:
return _IconButtonDefaultsM3(context, toggleable);
}
return switch (variant) {
_IconButtonVariant.filled => _FilledIconButtonDefaultsM3(context, toggleable),
_IconButtonVariant.filledTonal => _FilledTonalIconButtonDefaultsM3(context, toggleable),
_IconButtonVariant.outlined => _OutlinedIconButtonDefaultsM3(context, toggleable),
_IconButtonVariant.standard => _IconButtonDefaultsM3(context, toggleable),
};
}
/// Returns the [IconButtonThemeData.style] of the closest [IconButtonTheme] ancestor.

View file

@ -1373,13 +1373,10 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
width: overallWidth - _boxSize(icon).width,
);
container.layout(containerConstraints, parentUsesSize: true);
final double x;
switch (textDirection) {
case TextDirection.rtl:
x = 0.0;
case TextDirection.ltr:
x = _boxSize(icon).width;
}
final double x = switch (textDirection) {
TextDirection.rtl => 0.0,
TextDirection.ltr => _boxSize(icon).width,
};
_boxParentData(container).offset = Offset(x, 0.0);
}
@ -1402,13 +1399,10 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
baseline = _isOutlineAligned ? layout.outlineBaseline : layout.inputBaseline;
if (icon != null) {
final double x;
switch (textDirection) {
case TextDirection.rtl:
x = overallWidth - icon!.size.width;
case TextDirection.ltr:
x = 0.0;
}
final double x = switch (textDirection) {
TextDirection.rtl => overallWidth - icon!.size.width,
TextDirection.ltr => 0.0,
};
centerLayout(icon!, x);
}
@ -1673,30 +1667,19 @@ class _Decorator extends SlottedMultiChildRenderObjectWidget<_DecorationSlot, Re
@override
Widget? childForSlot(_DecorationSlot slot) {
switch (slot) {
case _DecorationSlot.icon:
return decoration.icon;
case _DecorationSlot.input:
return decoration.input;
case _DecorationSlot.label:
return decoration.label;
case _DecorationSlot.hint:
return decoration.hint;
case _DecorationSlot.prefix:
return decoration.prefix;
case _DecorationSlot.suffix:
return decoration.suffix;
case _DecorationSlot.prefixIcon:
return decoration.prefixIcon;
case _DecorationSlot.suffixIcon:
return decoration.suffixIcon;
case _DecorationSlot.helperError:
return decoration.helperError;
case _DecorationSlot.counter:
return decoration.counter;
case _DecorationSlot.container:
return decoration.container;
}
return switch (slot) {
_DecorationSlot.icon => decoration.icon,
_DecorationSlot.input => decoration.input,
_DecorationSlot.label => decoration.label,
_DecorationSlot.hint => decoration.hint,
_DecorationSlot.prefix => decoration.prefix,
_DecorationSlot.suffix => decoration.suffix,
_DecorationSlot.prefixIcon => decoration.prefixIcon,
_DecorationSlot.suffixIcon => decoration.suffixIcon,
_DecorationSlot.helperError => decoration.helperError,
_DecorationSlot.counter => decoration.counter,
_DecorationSlot.container => decoration.container,
};
}
@override
@ -4558,22 +4541,12 @@ class _InputDecoratorDefaultsM2 extends InputDecorationTheme {
@override
Color? get fillColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
// dark theme: 5% white
// light theme: 2% black
switch (Theme.of(context).brightness) {
case Brightness.dark:
return const Color(0x0DFFFFFF);
case Brightness.light:
return const Color(0x05000000) ;
}
}
// dark theme: 10% white
// light theme: 4% black
switch (Theme.of(context).brightness) {
case Brightness.dark: return const Color(0x1AFFFFFF);
case Brightness.light:return const Color(0x0A000000) ;
}
return switch ((Theme.of(context).brightness, states.contains(MaterialState.disabled))) {
(Brightness.dark, true) => const Color(0x0DFFFFFF), // 5% white
(Brightness.dark, false) => const Color(0x1AFFFFFF), // 10% white
(Brightness.light, true) => const Color(0x05000000), // 2% black
(Brightness.light, false) => const Color(0x0A000000), // 4% black
};
});
@override
@ -4584,12 +4557,10 @@ class _InputDecoratorDefaultsM2 extends InputDecorationTheme {
if (states.contains(MaterialState.focused)) {
return Theme.of(context).colorScheme.primary;
}
switch (Theme.of(context).brightness) {
case Brightness.dark:
return Colors.white70;
case Brightness.light:
return Colors.black45;
}
return switch (Theme.of(context).brightness) {
Brightness.dark => Colors.white70,
Brightness.light => Colors.black45,
};
});
@override
@ -4600,12 +4571,10 @@ class _InputDecoratorDefaultsM2 extends InputDecorationTheme {
if (states.contains(MaterialState.focused)) {
return Theme.of(context).colorScheme.primary;
}
switch (Theme.of(context).brightness) {
case Brightness.dark:
return Colors.white70;
case Brightness.light:
return Colors.black45;
}
return switch (Theme.of(context).brightness) {
Brightness.dark => Colors.white70,
Brightness.light => Colors.black45,
};
});
@override
@ -4616,12 +4585,10 @@ class _InputDecoratorDefaultsM2 extends InputDecorationTheme {
if (states.contains(MaterialState.focused)) {
return Theme.of(context).colorScheme.primary;
}
switch (Theme.of(context).brightness) {
case Brightness.dark:
return Colors.white70;
case Brightness.light:
return Colors.black45;
}
return switch (Theme.of(context).brightness) {
Brightness.dark => Colors.white70,
Brightness.light => Colors.black45,
};
});
}

View file

@ -1002,16 +1002,12 @@ class _ListTile extends SlottedMultiChildRenderObjectWidget<_ListTileSlot, Rende
@override
Widget? childForSlot(_ListTileSlot slot) {
switch (slot) {
case _ListTileSlot.leading:
return leading;
case _ListTileSlot.title:
return title;
case _ListTileSlot.subtitle:
return subtitle;
case _ListTileSlot.trailing:
return trailing;
}
return switch (slot) {
_ListTileSlot.leading => leading,
_ListTileSlot.title => title,
_ListTileSlot.subtitle => subtitle,
_ListTileSlot.trailing => trailing,
};
}
@override
@ -1521,12 +1517,10 @@ class _LisTileDefaultsM2 extends ListTileThemeData {
@override
TextStyle? get titleTextStyle {
switch (style!) {
case ListTileStyle.drawer:
return _textTheme.bodyLarge;
case ListTileStyle.list:
return _textTheme.titleMedium;
}
return switch (style!) {
ListTileStyle.drawer => _textTheme.bodyLarge,
ListTileStyle.list => _textTheme.titleMedium,
};
}
@override

View file

@ -994,12 +994,10 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
String get inputTimeModeButtonLabel => 'Switch to text input mode';
String _formatDayPeriod(TimeOfDay timeOfDay) {
switch (timeOfDay.period) {
case DayPeriod.am:
return anteMeridiemAbbreviation;
case DayPeriod.pm:
return postMeridiemAbbreviation;
}
return switch (timeOfDay.period) {
DayPeriod.am => anteMeridiemAbbreviation,
DayPeriod.pm => postMeridiemAbbreviation,
};
}
@override
@ -1128,14 +1126,11 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
@override
String licensesPackageDetailText(int licenseCount) {
assert(licenseCount >= 0);
switch (licenseCount) {
case 0:
return 'No licenses.';
case 1:
return '1 license.';
default:
return '$licenseCount licenses.';
}
return switch (licenseCount) {
0 => 'No licenses.',
1 => '1 license.',
_ => '$licenseCount licenses.',
};
}
@override
@ -1157,14 +1152,11 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
@override
String selectedRowCountTitle(int selectedRowCount) {
switch (selectedRowCount) {
case 0:
return 'No items selected';
case 1:
return '1 item selected';
default:
return '$selectedRowCount items selected';
}
return switch (selectedRowCount) {
0 => 'No items selected',
1 => '1 item selected',
_ => '$selectedRowCount items selected',
};
}
@override
@ -1307,14 +1299,11 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
@override
String remainingTextFieldCharacterCount(int remaining) {
switch (remaining) {
case 0:
return 'No characters remaining';
case 1:
return '1 character remaining';
default:
return '$remaining characters remaining';
}
return switch (remaining) {
0 => 'No characters remaining',
1 => '1 character remaining',
_ => '$remaining characters remaining',
};
}
@override

View file

@ -1871,19 +1871,15 @@ class _SubmenuButtonState extends State<SubmenuButton> {
Widget build(BuildContext context) {
Offset menuPaddingOffset = widget.alignmentOffset ?? Offset.zero;
final EdgeInsets menuPadding = _computeMenuPadding(context);
final Axis orientation = _anchor?._orientation ?? Axis.vertical;
// Move the submenu over by the size of the menu padding, so that
// the first menu item aligns with the submenu button that opens it.
switch (_anchor?._orientation ?? Axis.vertical) {
case Axis.horizontal:
switch (Directionality.of(context)) {
case TextDirection.rtl:
menuPaddingOffset += Offset(menuPadding.right, 0);
case TextDirection.ltr:
menuPaddingOffset += Offset(-menuPadding.left, 0);
}
case Axis.vertical:
menuPaddingOffset += Offset(0, -menuPadding.top);
}
menuPaddingOffset += switch ((orientation, Directionality.of(context))) {
(Axis.horizontal, TextDirection.rtl) => Offset(menuPadding.right, 0),
(Axis.horizontal, TextDirection.ltr) => Offset(-menuPadding.left, 0),
(Axis.vertical, TextDirection.rtl) => Offset(0, -menuPadding.top),
(Axis.vertical, TextDirection.ltr) => Offset(0, -menuPadding.top),
};
return MenuAnchor(
controller: _menuController,
@ -3204,12 +3200,10 @@ class _MenuLayout extends SingleChildLayoutDelegate {
Offset desiredPosition = alignment.resolve(textDirection).withinRect(anchorRect);
final Offset directionalOffset;
if (alignment is AlignmentDirectional) {
switch (textDirection) {
case TextDirection.rtl:
directionalOffset = Offset(-alignmentOffset.dx, alignmentOffset.dy);
case TextDirection.ltr:
directionalOffset = alignmentOffset;
}
directionalOffset = switch (textDirection) {
TextDirection.rtl => Offset(-alignmentOffset.dx, alignmentOffset.dy),
TextDirection.ltr => alignmentOffset,
};
} else {
directionalOffset = alignmentOffset;
}
@ -3493,12 +3487,10 @@ class _MenuPanelState extends State<_MenuPanel> {
}
Widget _intrinsicCrossSize({required Widget child}) {
switch (widget.orientation) {
case Axis.horizontal:
return IntrinsicHeight(child: child);
case Axis.vertical:
return IntrinsicWidth(child: child);
}
return switch (widget.orientation) {
Axis.horizontal => IntrinsicHeight(child: child),
Axis.vertical => IntrinsicWidth(child: child),
};
}
}