Skip to content

Commit

Permalink
Update ButtonStyleButton.scaledPadding documentation. Migrate calle…
Browse files Browse the repository at this point in the history
…rs in flutter/flutter (#139014)

Fixes flutter/flutter#138547. 

It makes more sense to me for the default padding values to use the scaled font sizes instead of the `textScaleFactor`.
  • Loading branch information
LongCatIsLooong authored Nov 29, 2023
1 parent 716b34c commit 075b9f7
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 96 deletions.
26 changes: 18 additions & 8 deletions packages/flutter/lib/src/material/button_style_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -170,24 +170,34 @@ abstract class ButtonStyleButton extends StatefulWidget {
/// A convenience method for subclasses.
static MaterialStateProperty<T>? allOrNull<T>(T? value) => value == null ? null : MaterialStatePropertyAll<T>(value);

/// Returns an interpolated value based on the [textScaleFactor] parameter:
/// A convenience method used by subclasses in the framework, that returns an
/// interpolated value based on the [fontSizeMultiplier] parameter:
///
/// * 0 - 1 [geometry1x]
/// * 1 - 2 lerp([geometry1x], [geometry2x], [textScaleFactor] - 1)
/// * 2 - 3 lerp([geometry2x], [geometry3x], [textScaleFactor] - 2)
/// * 1 - 2 lerp([geometry1x], [geometry2x], [fontSizeMultiplier] - 1)
/// * 2 - 3 lerp([geometry2x], [geometry3x], [fontSizeMultiplier] - 2)
/// * otherwise [geometry3x]
///
/// A convenience method for subclasses.
/// This method is used by the framework for estimating the default paddings to
/// use on a button with a text label, when the system text scaling setting
/// changes. It's usually supplied with empirical [geometry1x], [geometry2x],
/// [geometry3x] values adjusted for different system text scaling values, when
/// the unscaled font size is set to 14.0 (the default [TextTheme.labelLarge]
/// value).
///
/// The `fontSizeMultiplier` argument, for historical reasons, is the default
/// font size specified in the [ButtonStyle], scaled by the ambient font
/// scaler, then divided by 14.0 (the default font size used in buttons).
static EdgeInsetsGeometry scaledPadding(
EdgeInsetsGeometry geometry1x,
EdgeInsetsGeometry geometry2x,
EdgeInsetsGeometry geometry3x,
double textScaleFactor,
double fontSizeMultiplier,
) {
return switch (textScaleFactor) {
return switch (fontSizeMultiplier) {
<= 1 => geometry1x,
< 2 => EdgeInsetsGeometry.lerp(geometry1x, geometry2x, textScaleFactor - 1)!,
< 3 => EdgeInsetsGeometry.lerp(geometry2x, geometry3x, textScaleFactor - 2)!,
< 2 => EdgeInsetsGeometry.lerp(geometry1x, geometry2x, fontSizeMultiplier - 1)!,
< 3 => EdgeInsetsGeometry.lerp(geometry2x, geometry3x, fontSizeMultiplier - 2)!,
_ => geometry3x,
};
}
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter/lib/src/material/dropdown_menu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import 'theme_data.dart';
typedef SearchCallback<T> = int? Function(List<DropdownMenuEntry<T>> entries, String query);

// Navigation shortcuts to move the selected menu items up or down.
Map<ShortcutActivator, Intent> _kMenuTraversalShortcuts = <ShortcutActivator, Intent> {
final Map<ShortcutActivator, Intent> _kMenuTraversalShortcuts = <ShortcutActivator, Intent> {
LogicalKeySet(LogicalKeyboardKey.arrowUp): const _ArrowUpIntent(),
LogicalKeySet(LogicalKeyboardKey.arrowDown): const _ArrowDownIntent(),
};
Expand Down
57 changes: 34 additions & 23 deletions packages/flutter/lib/src/material/elevated_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,13 @@ class ElevatedButton extends ButtonStyleButton {
/// value for all states, otherwise the values are as specified for
/// each state, and "others" means all other states.
///
/// The `textScaleFactor` is the value of
/// `MediaQuery.textScaleFactorOf(context)` and the names of the
/// EdgeInsets constructors and `EdgeInsetsGeometry.lerp` have been
/// abbreviated for readability.
/// {@template flutter.material.elevated_button.default_font_size}
/// The "default font size" below refers to the font size specified in the
/// [defaultStyleOf] method (or 14.0 if unspecified), scaled by the
/// `MediaQuery.textScalerOf(context).scale` method. The names of the
/// EdgeInsets constructors and `EdgeInsetsGeometry.lerp` have been abbreviated
/// for readability.
/// {@endtemplate}
///
/// The color of the [ButtonStyle.textStyle] is not used, the
/// [ButtonStyle.foregroundColor] color is used instead.
Expand All @@ -272,10 +275,10 @@ class ElevatedButton extends ButtonStyleButton {
/// * hovered or focused - 4
/// * pressed - 8
/// * `padding`
/// * `textScaleFactor <= 1` - horizontal(16)
/// * `1 < textScaleFactor <= 2` - lerp(horizontal(16), horizontal(8))
/// * `2 < textScaleFactor <= 3` - lerp(horizontal(8), horizontal(4))
/// * `3 < textScaleFactor` - horizontal(4)
/// * `default font size <= 14` - horizontal(16)
/// * `14 < default font size <= 28` - lerp(horizontal(16), horizontal(8))
/// * `28 < default font size <= 36` - lerp(horizontal(8), horizontal(4))
/// * `36 < default font size` - horizontal(4)
/// * `minimumSize` - Size(64, 36)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
Expand All @@ -294,10 +297,10 @@ class ElevatedButton extends ButtonStyleButton {
/// The default padding values for the [ElevatedButton.icon] factory are slightly different:
///
/// * `padding`
/// * `textScaleFactor <= 1` - start(12) end(16)
/// * `1 < textScaleFactor <= 2` - lerp(start(12) end(16), horizontal(8))
/// * `2 < textScaleFactor <= 3` - lerp(horizontal(8), horizontal(4))
/// * `3 < textScaleFactor` - horizontal(4)
/// * `default font size <= 14` - start(12) end(16)
/// * `14 < default font size <= 28` - lerp(start(12) end(16), horizontal(8))
/// * `28 < default font size <= 36` - lerp(horizontal(8), horizontal(4))
/// * `36 < default font size` - horizontal(4)
///
/// The default value for `side`, which defines the appearance of the button's
/// outline, is null. That means that the outline is defined by the button
Expand Down Expand Up @@ -327,10 +330,10 @@ class ElevatedButton extends ButtonStyleButton {
/// * hovered - 3
/// * focused or pressed - 1
/// * `padding`
/// * `textScaleFactor <= 1` - horizontal(24)
/// * `1 < textScaleFactor <= 2` - lerp(horizontal(24), horizontal(12))
/// * `2 < textScaleFactor <= 3` - lerp(horizontal(12), horizontal(6))
/// * `3 < textScaleFactor` - horizontal(6)
/// * `default font size <= 14` - horizontal(24)
/// * `14 < default font size <= 28` - lerp(horizontal(24), horizontal(12))
/// * `28 < default font size <= 36` - lerp(horizontal(12), horizontal(6))
/// * `36 < default font size` - horizontal(6)
/// * `minimumSize` - Size(64, 40)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
Expand Down Expand Up @@ -388,13 +391,16 @@ class ElevatedButton extends ButtonStyleButton {
}

EdgeInsetsGeometry _scaledPadding(BuildContext context) {
final bool useMaterial3 = Theme.of(context).useMaterial3;
final double padding1x = useMaterial3 ? 24.0 : 16.0;
final ThemeData theme = Theme.of(context);
final double padding1x = theme.useMaterial3 ? 24.0 : 16.0;
final double defaultFontSize = theme.textTheme.labelLarge?.fontSize ?? 14.0;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0;

return ButtonStyleButton.scaledPadding(
EdgeInsets.symmetric(horizontal: padding1x),
EdgeInsets.symmetric(horizontal: padding1x / 2),
EdgeInsets.symmetric(horizontal: padding1x / 2 / 2),
MediaQuery.textScalerOf(context).textScaleFactor,
effectiveTextScale,
);
}

Expand Down Expand Up @@ -498,18 +504,23 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
@override
ButtonStyle defaultStyleOf(BuildContext context) {
final bool useMaterial3 = Theme.of(context).useMaterial3;
final EdgeInsetsGeometry scaledPadding = useMaterial3 ? ButtonStyleButton.scaledPadding(
final ButtonStyle buttonStyle = super.defaultStyleOf(context);
final double defaultFontSize = buttonStyle.textStyle?.resolve(const <MaterialState>{})?.fontSize ?? 14.0;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0;

final EdgeInsetsGeometry scaledPadding = useMaterial3
? ButtonStyleButton.scaledPadding(
const EdgeInsetsDirectional.fromSTEB(16, 0, 24, 0),
const EdgeInsetsDirectional.fromSTEB(8, 0, 12, 0),
const EdgeInsetsDirectional.fromSTEB(4, 0, 6, 0),
MediaQuery.textScalerOf(context).textScaleFactor,
effectiveTextScale,
) : ButtonStyleButton.scaledPadding(
const EdgeInsetsDirectional.fromSTEB(12, 0, 16, 0),
const EdgeInsets.symmetric(horizontal: 8),
const EdgeInsetsDirectional.fromSTEB(8, 0, 4, 0),
MediaQuery.textScalerOf(context).textScaleFactor,
effectiveTextScale,
);
return super.defaultStyleOf(context).copyWith(
return buttonStyle.copyWith(
padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(scaledPadding),
);
}
Expand Down
66 changes: 35 additions & 31 deletions packages/flutter/lib/src/material/filled_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,7 @@ class FilledButton extends ButtonStyleButton {
/// value for all states, otherwise the values are as specified for
/// each state, and "others" means all other states.
///
/// The `textScaleFactor` is the value of
/// `MediaQuery.textScalerOf(context).textScaleFactor` and the names of the
/// EdgeInsets constructors and `EdgeInsetsGeometry.lerp` have been
/// abbreviated for readability.
/// {@macro flutter.material.elevated_button.default_font_size}
///
/// The color of the [ButtonStyle.textStyle] is not used, the
/// [ButtonStyle.foregroundColor] color is used instead.
Expand All @@ -302,10 +299,10 @@ class FilledButton extends ButtonStyleButton {
/// * hovered - 1
/// * focused or pressed - 0
/// * `padding`
/// * `textScaleFactor <= 1` - horizontal(16)
/// * `1 < textScaleFactor <= 2` - lerp(horizontal(16), horizontal(8))
/// * `2 < textScaleFactor <= 3` - lerp(horizontal(8), horizontal(4))
/// * `3 < textScaleFactor` - horizontal(4)
/// * `default font size <= 14` - horizontal(16)
/// * `14 < default font size <= 28` - lerp(horizontal(16), horizontal(8))
/// * `28 < default font size <= 36` - lerp(horizontal(8), horizontal(4))
/// * `36 < default font size` - horizontal(4)
/// * `minimumSize` - Size(64, 40)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
Expand All @@ -324,10 +321,10 @@ class FilledButton extends ButtonStyleButton {
/// The default padding values for the [FilledButton.icon] factory are slightly different:
///
/// * `padding`
/// * `textScaleFactor <= 1` - start(12) end(16)
/// * `1 < textScaleFactor <= 2` - lerp(start(12) end(16), horizontal(8))
/// * `2 < textScaleFactor <= 3` - lerp(horizontal(8), horizontal(4))
/// * `3 < textScaleFactor` - horizontal(4)
/// * `default font size <= 14` - start(12) end(16)
/// * `14 < default font size <= 28` - lerp(start(12) end(16), horizontal(8))
/// * `28 < default font size <= 36` - lerp(horizontal(8), horizontal(4))
/// * `36 < default font size` - horizontal(4)
///
/// The default value for `side`, which defines the appearance of the button's
/// outline, is null. That means that the outline is defined by the button
Expand Down Expand Up @@ -357,10 +354,10 @@ class FilledButton extends ButtonStyleButton {
/// * hovered - 3
/// * focused or pressed - 1
/// * `padding`
/// * `textScaleFactor <= 1` - horizontal(24)
/// * `1 < textScaleFactor <= 2` - lerp(horizontal(24), horizontal(12))
/// * `2 < textScaleFactor <= 3` - lerp(horizontal(12), horizontal(6))
/// * `3 < textScaleFactor` - horizontal(6)
/// * `default font size <= 14` - horizontal(24)
/// * `14 < default font size <= 28` - lerp(horizontal(24), horizontal(12))
/// * `28 < default font size <= 36` - lerp(horizontal(12), horizontal(6))
/// * `36 < default font size` - horizontal(6)
/// * `minimumSize` - Size(64, 40)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
Expand Down Expand Up @@ -397,13 +394,15 @@ class FilledButton extends ButtonStyleButton {
}

EdgeInsetsGeometry _scaledPadding(BuildContext context) {
final bool useMaterial3 = Theme.of(context).useMaterial3;
final double padding1x = useMaterial3 ? 24.0 : 16.0;
final ThemeData theme = Theme.of(context);
final double defaultFontSize = theme.textTheme.labelLarge?.fontSize ?? 14.0;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0;
final double padding1x = theme.useMaterial3 ? 24.0 : 16.0;
return ButtonStyleButton.scaledPadding(
EdgeInsets.symmetric(horizontal: padding1x),
EdgeInsets.symmetric(horizontal: padding1x / 2),
EdgeInsets.symmetric(horizontal: padding1x / 2 / 2),
MediaQuery.textScalerOf(context).textScaleFactor,
effectiveTextScale,
);
}

Expand Down Expand Up @@ -502,18 +501,23 @@ class _FilledButtonWithIcon extends FilledButton {
@override
ButtonStyle defaultStyleOf(BuildContext context) {
final bool useMaterial3 = Theme.of(context).useMaterial3;
final EdgeInsetsGeometry scaledPadding = useMaterial3 ? ButtonStyleButton.scaledPadding(
const EdgeInsetsDirectional.fromSTEB(16, 0, 24, 0),
const EdgeInsetsDirectional.fromSTEB(8, 0, 12, 0),
const EdgeInsetsDirectional.fromSTEB(4, 0, 6, 0),
MediaQuery.textScalerOf(context).textScaleFactor,
) : ButtonStyleButton.scaledPadding(
const EdgeInsetsDirectional.fromSTEB(12, 0, 16, 0),
const EdgeInsets.symmetric(horizontal: 8),
const EdgeInsetsDirectional.fromSTEB(8, 0, 4, 0),
MediaQuery.textScalerOf(context).textScaleFactor,
);
return super.defaultStyleOf(context).copyWith(
final ButtonStyle buttonStyle = super.defaultStyleOf(context);
final double defaultFontSize = buttonStyle.textStyle?.resolve(const <MaterialState>{})?.fontSize ?? 14.0;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0;

final EdgeInsetsGeometry scaledPadding = useMaterial3
? ButtonStyleButton.scaledPadding(
const EdgeInsetsDirectional.fromSTEB(16, 0, 24, 0),
const EdgeInsetsDirectional.fromSTEB(8, 0, 12, 0),
const EdgeInsetsDirectional.fromSTEB(4, 0, 6, 0),
effectiveTextScale,
) : ButtonStyleButton.scaledPadding(
const EdgeInsetsDirectional.fromSTEB(12, 0, 16, 0),
const EdgeInsets.symmetric(horizontal: 8),
const EdgeInsetsDirectional.fromSTEB(8, 0, 4, 0),
effectiveTextScale,
);
return buttonStyle.copyWith(
padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(scaledPadding),
);
}
Expand Down
31 changes: 18 additions & 13 deletions packages/flutter/lib/src/material/outlined_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,10 @@ class OutlinedButton extends ButtonStyleButton {
/// * `shadowColor` - Theme.shadowColor
/// * `elevation` - 0
/// * `padding`
/// * `textScaleFactor <= 1` - horizontal(16)
/// * `1 < textScaleFactor <= 2` - lerp(horizontal(16), horizontal(8))
/// * `2 < textScaleFactor <= 3` - lerp(horizontal(8), horizontal(4))
/// * `3 < textScaleFactor` - horizontal(4)
/// * `default font size <= 14` - horizontal(16)
/// * `14 < default font size <= 28` - lerp(horizontal(16), horizontal(8))
/// * `28 < default font size <= 36` - lerp(horizontal(8), horizontal(4))
/// * `36 < default font size` - horizontal(4)
/// * `minimumSize` - Size(64, 36)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
Expand Down Expand Up @@ -281,10 +281,10 @@ class OutlinedButton extends ButtonStyleButton {
/// * `surfaceTintColor` - null
/// * `elevation` - 0
/// * `padding`
/// * `textScaleFactor <= 1` - horizontal(24)
/// * `1 < textScaleFactor <= 2` - lerp(horizontal(24), horizontal(12))
/// * `2 < textScaleFactor <= 3` - lerp(horizontal(12), horizontal(6))
/// * `3 < textScaleFactor` - horizontal(6)
/// * `default font size <= 14` - horizontal(24)
/// * `14 < default font size <= 28` - lerp(horizontal(24), horizontal(12))
/// * `28 < default font size <= 36` - lerp(horizontal(12), horizontal(6))
/// * `36 < default font size` - horizontal(6)
/// * `minimumSize` - Size(64, 40)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
Expand Down Expand Up @@ -344,13 +344,15 @@ class OutlinedButton extends ButtonStyleButton {
}

EdgeInsetsGeometry _scaledPadding(BuildContext context) {
final bool useMaterial3 = Theme.of(context).useMaterial3;
final double padding1x = useMaterial3 ? 24.0 : 16.0;
final ThemeData theme = Theme.of(context);
final double padding1x = theme.useMaterial3 ? 24.0 : 16.0;
final double defaultFontSize = theme.textTheme.labelLarge?.fontSize ?? 14.0;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0;
return ButtonStyleButton.scaledPadding(
EdgeInsets.symmetric(horizontal: padding1x),
EdgeInsets.symmetric(horizontal: padding1x / 2),
EdgeInsets.symmetric(horizontal: padding1x / 2 / 2),
MediaQuery.textScalerOf(context).textScaleFactor,
effectiveTextScale,
);
}

Expand Down Expand Up @@ -431,13 +433,16 @@ class _OutlinedButtonWithIcon extends OutlinedButton {
if (!useMaterial3) {
return super.defaultStyleOf(context);
}
final ButtonStyle buttonStyle = super.defaultStyleOf(context);
final double defaultFontSize = buttonStyle.textStyle?.resolve(const <MaterialState>{})?.fontSize ?? 14.0;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0;
final EdgeInsetsGeometry scaledPadding = ButtonStyleButton.scaledPadding(
const EdgeInsetsDirectional.fromSTEB(16, 0, 24, 0),
const EdgeInsetsDirectional.fromSTEB(8, 0, 12, 0),
const EdgeInsetsDirectional.fromSTEB(4, 0, 6, 0),
MediaQuery.textScalerOf(context).textScaleFactor,
effectiveTextScale,
);
return super.defaultStyleOf(context).copyWith(
return buttonStyle.copyWith(
padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(scaledPadding),
);
}
Expand Down
Loading

0 comments on commit 075b9f7

Please sign in to comment.