Unverified Commit 01c07e18 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Remove `nullOk` parameter from Cupertino color resolution APIs (#68905)

* Remove nullOk from cupertino color resolution

* Add CupertinoDynamicColor.maybeResolveFrom

* Remove CupertinoDynamicColor.maybeResolveFrom again
parent 55a1d0ae
......@@ -450,14 +450,14 @@ class _CupertinoAlertRenderWidget extends RenderObjectWidget {
assert(debugCheckHasMediaQuery(context));
return _RenderCupertinoAlert(
dividerThickness: _kDividerThickness / MediaQuery.of(context).devicePixelRatio,
dividerColor: CupertinoDynamicColor.resolve(_kButtonDividerColor, context)!,
dividerColor: CupertinoDynamicColor.resolve(_kButtonDividerColor, context),
);
}
@override
void updateRenderObject(BuildContext context, _RenderCupertinoAlert renderObject) {
super.updateRenderObject(context, renderObject);
renderObject.dividerColor = CupertinoDynamicColor.resolve(_kButtonDividerColor, context)!;
renderObject.dividerColor = CupertinoDynamicColor.resolve(_kButtonDividerColor, context);
}
@override
......@@ -1071,10 +1071,10 @@ class _CupertinoAlertActionsRenderWidget extends MultiChildRenderObjectWidget {
RenderObject createRenderObject(BuildContext context) {
return _RenderCupertinoAlertActions(
dividerThickness: _dividerThickness,
dividerColor: CupertinoDynamicColor.resolve(_kButtonDividerColor, context)!,
dividerColor: CupertinoDynamicColor.resolve(_kButtonDividerColor, context),
hasCancelButton: _hasCancelButton,
backgroundColor: CupertinoDynamicColor.resolve(_kBackgroundColor, context)!,
pressedColor: CupertinoDynamicColor.resolve(_kPressedColor, context)!,
backgroundColor: CupertinoDynamicColor.resolve(_kBackgroundColor, context),
pressedColor: CupertinoDynamicColor.resolve(_kPressedColor, context),
);
}
......@@ -1082,10 +1082,10 @@ class _CupertinoAlertActionsRenderWidget extends MultiChildRenderObjectWidget {
void updateRenderObject(BuildContext context, _RenderCupertinoAlertActions renderObject) {
renderObject
..dividerThickness = _dividerThickness
..dividerColor = CupertinoDynamicColor.resolve(_kButtonDividerColor, context)!
..dividerColor = CupertinoDynamicColor.resolve(_kButtonDividerColor, context)
..hasCancelButton = _hasCancelButton
..backgroundColor = CupertinoDynamicColor.resolve(_kBackgroundColor, context)!
..pressedColor = CupertinoDynamicColor.resolve(_kPressedColor, context)!;
..backgroundColor = CupertinoDynamicColor.resolve(_kBackgroundColor, context)
..pressedColor = CupertinoDynamicColor.resolve(_kPressedColor, context);
}
}
......
......@@ -119,7 +119,7 @@ class _CupertinoActivityIndicatorState extends State<CupertinoActivityIndicator>
painter: _CupertinoActivityIndicatorPainter(
position: _controller,
activeColor:
CupertinoDynamicColor.resolve(_kActiveTickColor, context)!,
CupertinoDynamicColor.resolve(_kActiveTickColor, context),
radius: widget.radius,
progress: widget.progress,
),
......
......@@ -378,7 +378,7 @@ class _CupertinoAppState extends State<CupertinoApp> {
WidgetsApp _buildWidgetApp(BuildContext context) {
final CupertinoThemeData effectiveThemeData = CupertinoTheme.of(context);
final Color color = CupertinoDynamicColor.resolve(widget.color ?? effectiveThemeData.primaryColor, context)!;
final Color color = CupertinoDynamicColor.resolve(widget.color ?? effectiveThemeData.primaryColor, context);
if (_usesRouter) {
return WidgetsApp.router(
......
......@@ -137,7 +137,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
bool opaque(BuildContext context) {
final Color backgroundColor =
this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor;
return CupertinoDynamicColor.resolve(backgroundColor, context)!.alpha == 0xFF;
return CupertinoDynamicColor.resolve(backgroundColor, context).alpha == 0xFF;
}
@override
......@@ -145,7 +145,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
assert(debugCheckHasMediaQuery(context));
final double bottomPadding = MediaQuery.of(context).padding.bottom;
final Color? backgroundColor = CupertinoDynamicColor.resolve(
final Color backgroundColor = CupertinoDynamicColor.resolve(
this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor,
context,
);
......@@ -166,7 +166,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
right: resolveBorderSide(border!.right),
);
final Color? inactive = CupertinoDynamicColor.resolve(inactiveColor, context);
final Color inactive = CupertinoDynamicColor.resolve(inactiveColor, context);
Widget result = DecoratedBox(
decoration: BoxDecoration(
border: resolvedBorder,
......@@ -259,7 +259,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
if (!active)
return item;
final Color? activeColor = CupertinoDynamicColor.resolve(
final Color activeColor = CupertinoDynamicColor.resolve(
this.activeColor ?? CupertinoTheme.of(context).primaryColor,
context,
);
......
......@@ -214,9 +214,9 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
final Color primaryColor = themeData.primaryColor;
final Color? backgroundColor = widget.color == null
? (widget._filled ? primaryColor : null)
: CupertinoDynamicColor.resolve(widget.color, context);
: CupertinoDynamicColor.maybeResolve(widget.color, context);
final Color? foregroundColor = backgroundColor != null
final Color foregroundColor = backgroundColor != null
? themeData.primaryContrastingColor
: enabled
? primaryColor
......
......@@ -876,6 +876,25 @@ class CupertinoDynamicColor extends Color with Diagnosticable {
/// - has a [CupertinoUserInterfaceLevel] that indicates [CupertinoUserInterfaceLevelData.elevated].
final Color darkHighContrastElevatedColor;
/// Resolves the given [Color] by calling [resolveFrom].
///
/// If the given color is already a concrete [Color], it will be returned as is.
/// If the given color is a [CupertinoDynamicColor], but the given [BuildContext]
/// lacks the dependencies required to the color resolution, the default trait
/// value will be used ([Brightness.light] platform brightness, normal contrast,
/// [CupertinoUserInterfaceLevelData.base] elevation level).
///
/// See also:
///
/// * [maybeResolve], which is similar to this function, but will allow a
/// null `resolvable` color.
static Color resolve(Color resolvable, BuildContext context) {
assert(context != null);
return (resolvable is CupertinoDynamicColor)
? resolvable.resolveFrom(context)
: resolvable;
}
/// Resolves the given [Color] by calling [resolveFrom].
///
/// If the given color is already a concrete [Color], it will be returned as is.
......@@ -883,14 +902,18 @@ class CupertinoDynamicColor extends Color with Diagnosticable {
/// If the given color is a [CupertinoDynamicColor], but the given [BuildContext]
/// lacks the dependencies required to the color resolution, the default trait
/// value will be used ([Brightness.light] platform brightness, normal contrast,
/// [CupertinoUserInterfaceLevelData.base] elevation level), unless [nullOk] is
/// set to false, in which case an exception will be thrown.
static Color? resolve(Color? resolvable, BuildContext context, { bool nullOk = true }) {
/// [CupertinoUserInterfaceLevelData.base] elevation level).
///
/// See also:
///
/// * [resolve], which is similar to this function, but returns a
/// non-nullable value, and does not allow a null `resolvable` color.
static Color? maybeResolve(Color? resolvable, BuildContext context) {
if (resolvable == null)
return null;
assert(context != null);
return (resolvable is CupertinoDynamicColor)
? resolvable.resolveFrom(context, nullOk: nullOk)
? resolvable.resolveFrom(context)
: resolvable;
}
......@@ -921,15 +944,17 @@ class CupertinoDynamicColor extends Color with Diagnosticable {
/// identical to this [CupertinoDynamicColor], except the effective color is
/// changed to adapt to the given [BuildContext].
///
/// For example, if the given [BuildContext] indicates the widgets in the subtree
/// should be displayed in dark mode (the surrounding [CupertinoTheme]'s [CupertinoThemeData.brightness]
/// or [MediaQuery]'s [MediaQueryData.platformBrightness] is [Brightness.dark]),
/// with a high accessibility contrast (the surrounding [MediaQuery]'s [MediaQueryData.highContrast]
/// is `true`), and an elevated interface elevation (the surrounding [CupertinoUserInterfaceLevel]'s
/// `data` is [CupertinoUserInterfaceLevelData.elevated]), the resolved
/// For example, if the given [BuildContext] indicates the widgets in the
/// subtree should be displayed in dark mode (the surrounding
/// [CupertinoTheme]'s [CupertinoThemeData.brightness] or [MediaQuery]'s
/// [MediaQueryData.platformBrightness] is [Brightness.dark]), with a high
/// accessibility contrast (the surrounding [MediaQuery]'s
/// [MediaQueryData.highContrast] is `true`), and an elevated interface
/// elevation (the surrounding [CupertinoUserInterfaceLevel]'s `data` is
/// [CupertinoUserInterfaceLevelData.elevated]), the resolved
/// [CupertinoDynamicColor] will be the same as this [CupertinoDynamicColor],
/// except its effective color will be the `darkHighContrastElevatedColor` variant
/// from the original [CupertinoDynamicColor].
/// except its effective color will be the `darkHighContrastElevatedColor`
/// variant from the original [CupertinoDynamicColor].
///
/// Calling this function may create dependencies on the closest instance of some
/// [InheritedWidget]s that enclose the given [BuildContext]. E.g., if [darkColor]
......@@ -941,24 +966,19 @@ class CupertinoDynamicColor extends Color with Diagnosticable {
/// If any of the required dependencies are missing from the given context, the
/// default value of that trait will be used ([Brightness.light] platform
/// brightness, normal contrast, [CupertinoUserInterfaceLevelData.base] elevation
/// level), unless [nullOk] is set to false, in which case an exception will be
/// thrown.
CupertinoDynamicColor resolveFrom(BuildContext context, { bool nullOk = true }) {
/// level).
CupertinoDynamicColor resolveFrom(BuildContext context) {
Brightness brightness = Brightness.light;
if (_isPlatformBrightnessDependent) {
brightness = nullOk
? CupertinoTheme.maybeBrightnessOf(context) ?? Brightness.light
: CupertinoTheme.brightnessOf(context);
brightness = CupertinoTheme.maybeBrightnessOf(context) ?? Brightness.light;
}
bool isHighContrastEnabled = false;
if (_isHighContrastDependent) {
isHighContrastEnabled = nullOk
? MediaQuery.maybeOf(context)?.highContrast ?? false
: MediaQuery.of(context).highContrast;
isHighContrastEnabled = MediaQuery.maybeOf(context)?.highContrast ?? false;
}
final CupertinoUserInterfaceLevelData level = _isInterfaceElevationDependent
? CupertinoUserInterfaceLevel.of(context, nullOk: nullOk) ?? CupertinoUserInterfaceLevelData.base
? CupertinoUserInterfaceLevel.maybeOf(context) ?? CupertinoUserInterfaceLevelData.base
: CupertinoUserInterfaceLevelData.base;
final Color resolved;
......
......@@ -2087,7 +2087,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
child: Align(
alignment: widget.alignment,
child: Container(
color: CupertinoDynamicColor.resolve(widget.backgroundColor, context),
color: CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context),
width: totalWidth,
height: _kPickerHeight,
child: DefaultTextStyle(
......
......@@ -390,7 +390,7 @@ class _CupertinoDialogRenderWidget extends RenderObjectWidget {
return _RenderCupertinoDialog(
dividerThickness: _kDividerThickness / MediaQuery.of(context).devicePixelRatio,
isInAccessibilityMode: _isInAccessibilityMode(context),
dividerColor: CupertinoDynamicColor.resolve(CupertinoColors.separator, context)!,
dividerColor: CupertinoDynamicColor.resolve(CupertinoColors.separator, context),
);
}
......@@ -398,7 +398,7 @@ class _CupertinoDialogRenderWidget extends RenderObjectWidget {
void updateRenderObject(BuildContext context, _RenderCupertinoDialog renderObject) {
renderObject
..isInAccessibilityMode = _isInAccessibilityMode(context)
..dividerColor = CupertinoDynamicColor.resolve(CupertinoColors.separator, context)!;
..dividerColor = CupertinoDynamicColor.resolve(CupertinoColors.separator, context);
}
@override
......@@ -1269,9 +1269,9 @@ class _CupertinoDialogActionsRenderWidget extends MultiChildRenderObjectWidget {
? _kAccessibilityCupertinoDialogWidth
: _kCupertinoDialogWidth,
dividerThickness: _dividerThickness,
dialogColor: CupertinoDynamicColor.resolve(_kDialogColor, context)!,
dialogPressedColor: CupertinoDynamicColor.resolve(_kDialogPressedColor, context)!,
dividerColor: CupertinoDynamicColor.resolve(CupertinoColors.separator, context)!,
dialogColor: CupertinoDynamicColor.resolve(_kDialogColor, context),
dialogPressedColor: CupertinoDynamicColor.resolve(_kDialogPressedColor, context),
dividerColor: CupertinoDynamicColor.resolve(CupertinoColors.separator, context),
);
}
......@@ -1282,9 +1282,9 @@ class _CupertinoDialogActionsRenderWidget extends MultiChildRenderObjectWidget {
? _kAccessibilityCupertinoDialogWidth
: _kCupertinoDialogWidth
..dividerThickness = _dividerThickness
..dialogColor = CupertinoDynamicColor.resolve(_kDialogColor, context)!
..dialogPressedColor = CupertinoDynamicColor.resolve(_kDialogPressedColor, context)!
..dividerColor = CupertinoDynamicColor.resolve(CupertinoColors.separator, context)!;
..dialogColor = CupertinoDynamicColor.resolve(_kDialogColor, context)
..dialogPressedColor = CupertinoDynamicColor.resolve(_kDialogPressedColor, context)
..dividerColor = CupertinoDynamicColor.resolve(CupertinoColors.separator, context);
}
}
......
......@@ -22,7 +22,7 @@ class CupertinoIconThemeData extends IconThemeData with Diagnosticable {
/// Called by [IconTheme.of] to resolve [color] against the given [BuildContext].
@override
IconThemeData resolve(BuildContext context) {
final Color? resolvedColor = CupertinoDynamicColor.resolve(color, context);
final Color? resolvedColor = CupertinoDynamicColor.maybeResolve(color, context);
return resolvedColor == color ? this : copyWith(color: resolvedColor);
}
......
......@@ -57,14 +57,16 @@ class CupertinoUserInterfaceLevel extends InheritedWidget {
/// You can use this function to query the user interface elevation level within
/// the given [BuildContext]. When that information changes, your widget will
/// be scheduled to be rebuilt, keeping your widget up-to-date.
static CupertinoUserInterfaceLevelData? of(BuildContext context, { bool nullOk = false }) {
///
/// See also:
///
/// * [maybeOf], which is similar, but will return null if no
/// [CupertinoUserInterfaceLevel] encloses the given context.
static CupertinoUserInterfaceLevelData of(BuildContext context) {
assert(context != null);
assert(nullOk != null);
final CupertinoUserInterfaceLevel? query = context.dependOnInheritedWidgetOfExactType<CupertinoUserInterfaceLevel>();
if (query != null)
return query._data;
if (nullOk)
return null;
throw FlutterError(
'CupertinoUserInterfaceLevel.of() called with a context that does not contain a CupertinoUserInterfaceLevel.\n'
'No CupertinoUserInterfaceLevel ancestor could be found starting from the context that was passed '
......@@ -76,6 +78,27 @@ class CupertinoUserInterfaceLevel extends InheritedWidget {
);
}
/// The data from the closest instance of this class that encloses the given
/// context, if there is one.
///
/// Returns null if no [CupertinoUserInterfaceLevel] encloses the given context.
///
/// You can use this function to query the user interface elevation level within
/// the given [BuildContext]. When that information changes, your widget will
/// be scheduled to be rebuilt, keeping your widget up-to-date.
///
/// See also:
///
/// * [of], which is similar, but will throw an exception if no
/// [CupertinoUserInterfaceLevel] encloses the given context.
static CupertinoUserInterfaceLevelData? maybeOf(BuildContext context) {
assert(context != null);
final CupertinoUserInterfaceLevel? query = context.dependOnInheritedWidgetOfExactType<CupertinoUserInterfaceLevel>();
if (query != null)
return query._data;
return null;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
......
......@@ -399,7 +399,7 @@ class CupertinoNavigationBar extends StatefulWidget implements ObstructingPrefer
/// True if the navigation bar's background color has no transparency.
@override
bool shouldFullyObstruct(BuildContext context) {
final Color backgroundColor = CupertinoDynamicColor.resolve(this.backgroundColor, context)
final Color backgroundColor = CupertinoDynamicColor.maybeResolve(this.backgroundColor, context)
?? CupertinoTheme.of(context).barBackgroundColor;
return backgroundColor.alpha == 0xFF;
}
......@@ -430,7 +430,7 @@ class _CupertinoNavigationBarState extends State<CupertinoNavigationBar> {
@override
Widget build(BuildContext context) {
final Color backgroundColor =
CupertinoDynamicColor.resolve(widget.backgroundColor, context) ?? CupertinoTheme.of(context).barBackgroundColor;
CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context) ?? CupertinoTheme.of(context).barBackgroundColor;
final _NavigationBarStaticComponents components = _NavigationBarStaticComponents(
keys: keys,
......@@ -459,7 +459,7 @@ class _CupertinoNavigationBarState extends State<CupertinoNavigationBar> {
),
);
final Color? actionsForegroundColor = CupertinoDynamicColor.resolve(
final Color? actionsForegroundColor = CupertinoDynamicColor.maybeResolve(
widget.actionsForegroundColor,
context,
);
......@@ -691,7 +691,7 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
@override
Widget build(BuildContext context) {
// Lint ignore to maintain backward compatibility.
final Color actionsForegroundColor = CupertinoDynamicColor.resolve(widget.actionsForegroundColor, context)
final Color actionsForegroundColor = CupertinoDynamicColor.maybeResolve(widget.actionsForegroundColor, context)
?? CupertinoTheme.of(context).primaryColor;
final _NavigationBarStaticComponents components = _NavigationBarStaticComponents(
......@@ -720,7 +720,7 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
keys: keys,
components: components,
userMiddle: widget.middle,
backgroundColor: CupertinoDynamicColor.resolve(widget.backgroundColor, context) ?? CupertinoTheme.of(context).barBackgroundColor,
backgroundColor: CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context) ?? CupertinoTheme.of(context).barBackgroundColor,
brightness: widget.brightness,
border: widget.border,
padding: widget.padding,
......@@ -789,7 +789,7 @@ class _LargeTitleNavigationBarSliverDelegate
final Widget navBar = _wrapWithBackground(
border: border,
backgroundColor: CupertinoDynamicColor.resolve(backgroundColor, context)!,
backgroundColor: CupertinoDynamicColor.resolve(backgroundColor, context),
brightness: brightness,
child: DefaultTextStyle(
style: CupertinoTheme.of(context).textTheme.textStyle,
......@@ -1325,7 +1325,7 @@ class CupertinoNavigationBarBackButton extends StatelessWidget {
TextStyle actionTextStyle = CupertinoTheme.of(context).textTheme.navActionTextStyle;
if (color != null) {
actionTextStyle = actionTextStyle.copyWith(color: CupertinoDynamicColor.resolve(color, context));
actionTextStyle = actionTextStyle.copyWith(color: CupertinoDynamicColor.maybeResolve(color, context));
}
return CupertinoButton(
......
......@@ -157,7 +157,7 @@ class _CupertinoPageScaffoldState extends State<CupertinoPageScaffold> {
return DecoratedBox(
decoration: BoxDecoration(
color: CupertinoDynamicColor.resolve(widget.backgroundColor, context)
color: CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context)
?? CupertinoTheme.of(context).scaffoldBackgroundColor,
),
child: Stack(
......
......@@ -278,7 +278,7 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
@override
Widget build(BuildContext context) {
final Color? resolvedBackgroundColor = CupertinoDynamicColor.resolve(widget.backgroundColor, context);
final Color? resolvedBackgroundColor = CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context);
final Widget result = DefaultTextStyle(
style: CupertinoTheme.of(context).textTheme.pickerTextStyle,
......
......@@ -1145,7 +1145,7 @@ Future<T?> showCupertinoDialog<T>({
context: context,
barrierDismissible: barrierDismissible,
barrierLabel: CupertinoLocalizations.of(context).modalBarrierDismissLabel,
barrierColor: CupertinoDynamicColor.resolve(_kModalBarrierColor, context)!,
barrierColor: CupertinoDynamicColor.resolve(_kModalBarrierColor, context),
// This transition duration was eyeballed comparing with iOS
transitionDuration: const Duration(milliseconds: 250),
pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
......
......@@ -284,7 +284,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
} else {
_painter!
..textDirection = Directionality.of(context)
..color = CupertinoDynamicColor.resolve(_kScrollbarColor, context)!
..color = CupertinoDynamicColor.resolve(_kScrollbarColor, context)
..padding = MediaQuery.of(context).padding;
}
_triggerScrollbar();
......@@ -308,7 +308,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
/// Returns a [ScrollbarPainter] visually styled like the iOS scrollbar.
ScrollbarPainter _buildCupertinoScrollbarPainter(BuildContext context) {
return ScrollbarPainter(
color: CupertinoDynamicColor.resolve(_kScrollbarColor, context)!,
color: CupertinoDynamicColor.resolve(_kScrollbarColor, context),
textDirection: Directionality.of(context),
thickness: _thickness,
fadeoutOpacityAnimation: _fadeoutOpacityAnimation,
......
......@@ -243,7 +243,7 @@ class _CupertinoSliderState extends State<CupertinoSlider> with TickerProviderSt
activeColor: CupertinoDynamicColor.resolve(
widget.activeColor ?? CupertinoTheme.of(context).primaryColor,
context,
)!,
),
thumbColor: widget.thumbColor,
onChanged: widget.onChanged != null ? _handleChanged : null,
onChangeStart: widget.onChangeStart != null ? _handleDragStart : null,
......@@ -282,8 +282,8 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
value: value,
divisions: divisions,
activeColor: activeColor,
thumbColor: CupertinoDynamicColor.resolve(thumbColor, context)!,
trackColor: CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context)!,
thumbColor: CupertinoDynamicColor.resolve(thumbColor, context),
trackColor: CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context),
onChanged: onChanged,
onChangeStart: onChangeStart,
onChangeEnd: onChangeEnd,
......@@ -299,8 +299,8 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
..value = value
..divisions = divisions
..activeColor = activeColor
..thumbColor = CupertinoDynamicColor.resolve(thumbColor, context)!
..trackColor = CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context)!
..thumbColor = CupertinoDynamicColor.resolve(thumbColor, context)
..trackColor = CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context)
..onChanged = onChanged
..onChangeStart = onChangeStart
..onChangeEnd = onChangeEnd
......
......@@ -483,7 +483,7 @@ class _SegmentedControlRenderWidget<T> extends MultiChildRenderObjectWidget {
RenderObject createRenderObject(BuildContext context) {
return _RenderSegmentedControl<T>(
selectedIndex: selectedIndex,
thumbColor: CupertinoDynamicColor.resolve(thumbColor, context),
thumbColor: CupertinoDynamicColor.maybeResolve(thumbColor, context),
state: state,
);
}
......@@ -491,7 +491,7 @@ class _SegmentedControlRenderWidget<T> extends MultiChildRenderObjectWidget {
@override
void updateRenderObject(BuildContext context, _RenderSegmentedControl<T> renderObject) {
renderObject
..thumbColor = CupertinoDynamicColor.resolve(thumbColor, context)
..thumbColor = CupertinoDynamicColor.maybeResolve(thumbColor, context)
..guardedSetHighlightedIndex(selectedIndex);
}
}
......
......@@ -299,8 +299,8 @@ class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderSt
activeColor: CupertinoDynamicColor.resolve(
widget.activeColor ?? CupertinoColors.systemGreen,
context,
)!,
trackColor: CupertinoDynamicColor.resolve(widget.trackColor ?? CupertinoColors.secondarySystemFill, context)!,
),
trackColor: CupertinoDynamicColor.resolve(widget.trackColor ?? CupertinoColors.secondarySystemFill, context),
onChanged: widget.onChanged,
textDirection: Directionality.of(context),
state: this,
......
......@@ -440,7 +440,7 @@ class _CupertinoTabScaffoldState extends State<CupertinoTabScaffold> with Restor
return DecoratedBox(
decoration: BoxDecoration(
color: CupertinoDynamicColor.resolve(widget.backgroundColor, context)
color: CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context)
?? CupertinoTheme.of(context).scaffoldBackgroundColor,
),
child: Stack(
......
......@@ -888,24 +888,24 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
final CupertinoThemeData themeData = CupertinoTheme.of(context);
final TextStyle? resolvedStyle = widget.style?.copyWith(
color: CupertinoDynamicColor.resolve(widget.style?.color, context),
backgroundColor: CupertinoDynamicColor.resolve(widget.style?.backgroundColor, context),
color: CupertinoDynamicColor.maybeResolve(widget.style?.color, context),
backgroundColor: CupertinoDynamicColor.maybeResolve(widget.style?.backgroundColor, context),
);
final TextStyle textStyle = themeData.textTheme.textStyle.merge(resolvedStyle);
final TextStyle? resolvedPlaceholderStyle = widget.placeholderStyle?.copyWith(
color: CupertinoDynamicColor.resolve(widget.placeholderStyle?.color, context),
backgroundColor: CupertinoDynamicColor.resolve(widget.placeholderStyle?.backgroundColor, context),
color: CupertinoDynamicColor.maybeResolve(widget.placeholderStyle?.color, context),
backgroundColor: CupertinoDynamicColor.maybeResolve(widget.placeholderStyle?.backgroundColor, context),
);
final TextStyle placeholderStyle = textStyle.merge(resolvedPlaceholderStyle);
final Brightness keyboardAppearance = widget.keyboardAppearance ?? CupertinoTheme.brightnessOf(context);
final Color cursorColor = CupertinoDynamicColor.resolve(widget.cursorColor, context) ?? themeData.primaryColor;
final Color? disabledColor = CupertinoDynamicColor.resolve(_kDisabledBackground, context);
final Color cursorColor = CupertinoDynamicColor.maybeResolve(widget.cursorColor, context) ?? themeData.primaryColor;
final Color disabledColor = CupertinoDynamicColor.resolve(_kDisabledBackground, context);
final Color? decorationColor = CupertinoDynamicColor.resolve(widget.decoration?.color, context);
final Color? decorationColor = CupertinoDynamicColor.maybeResolve(widget.decoration?.color, context);
final BoxBorder? border = widget.decoration?.border;
Border? resolvedBorder = border as Border?;
......@@ -978,7 +978,7 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
cursorOffset: cursorOffset,
paintCursorAboveText: true,
autocorrectionTextRectColor: selectionColor,
backgroundCursorColor: CupertinoDynamicColor.resolve(CupertinoColors.inactiveGray, context)!,
backgroundCursorColor: CupertinoDynamicColor.resolve(CupertinoColors.inactiveGray, context),
selectionHeightStyle: widget.selectionHeightStyle,
selectionWidthStyle: widget.selectionWidthStyle,
scrollPadding: widget.scrollPadding,
......
......@@ -101,12 +101,12 @@ const TextStyle _kDefaultDateTimePickerTextStyle = TextStyle(
color: CupertinoColors.label,
);
TextStyle? _resolveTextStyle(TextStyle? style, BuildContext context, bool nullOk) {
TextStyle? _resolveTextStyle(TextStyle? style, BuildContext context) {
// This does not resolve the shadow color, foreground, background, etc.
return style?.copyWith(
color: CupertinoDynamicColor.resolve(style.color, context, nullOk: nullOk),
backgroundColor: CupertinoDynamicColor.resolve(style.backgroundColor, context, nullOk: nullOk),
decorationColor: CupertinoDynamicColor.resolve(style.decorationColor, context, nullOk: nullOk),
color: CupertinoDynamicColor.maybeResolve(style.color, context),
backgroundColor: CupertinoDynamicColor.maybeResolve(style.backgroundColor, context),
decorationColor: CupertinoDynamicColor.maybeResolve(style.decorationColor, context),
);
}
......@@ -206,22 +206,23 @@ class CupertinoTextThemeData with Diagnosticable {
/// Returns a copy of the current [CupertinoTextThemeData] with all the colors
/// resolved against the given [BuildContext].
///
/// Throws an exception if any of the [InheritedWidget]s required to resolve
/// this [CupertinoTextThemeData] is not found in [context], unless [nullOk] is
/// set to true, in which case [CupertinoDynamicColor]s that fail to resolve will
/// be used as-is.
CupertinoTextThemeData resolveFrom(BuildContext context, { bool nullOk = false }) {
/// If any of the [InheritedWidget]s required to resolve this
/// [CupertinoTextThemeData] is not found in [context], any unresolved
/// [CupertinoDynamicColor]s will use the default trait value
/// ([Brightness.light] platform brightness, normal contrast,
/// [CupertinoUserInterfaceLevelData.base] elevation level).
CupertinoTextThemeData resolveFrom(BuildContext context) {
return CupertinoTextThemeData._raw(
_defaults.resolveFrom(context, nullOk),
CupertinoDynamicColor.resolve(_primaryColor, context, nullOk: nullOk),
_resolveTextStyle(_textStyle, context, nullOk),
_resolveTextStyle(_actionTextStyle, context, nullOk),
_resolveTextStyle(_tabLabelTextStyle, context, nullOk),
_resolveTextStyle(_navTitleTextStyle, context, nullOk),
_resolveTextStyle(_navLargeTitleTextStyle, context, nullOk),
_resolveTextStyle(_navActionTextStyle, context, nullOk),
_resolveTextStyle(_pickerTextStyle, context, nullOk),
_resolveTextStyle(_dateTimePickerTextStyle, context, nullOk),
_defaults.resolveFrom(context),
CupertinoDynamicColor.maybeResolve(_primaryColor, context),
_resolveTextStyle(_textStyle, context),
_resolveTextStyle(_actionTextStyle, context),
_resolveTextStyle(_tabLabelTextStyle, context),
_resolveTextStyle(_navTitleTextStyle, context),
_resolveTextStyle(_navLargeTitleTextStyle, context),
_resolveTextStyle(_navActionTextStyle, context),
_resolveTextStyle(_pickerTextStyle, context),
_resolveTextStyle(_dateTimePickerTextStyle, context),
);
}
......@@ -300,9 +301,9 @@ class _TextThemeDefaultsBuilder {
TextStyle actionTextStyle({ Color? primaryColor }) => _kDefaultActionTextStyle.copyWith(color: primaryColor);
TextStyle navActionTextStyle({ Color? primaryColor }) => actionTextStyle(primaryColor: primaryColor);
_TextThemeDefaultsBuilder resolveFrom(BuildContext context, bool nullOk) {
final Color resolvedLabelColor = CupertinoDynamicColor.resolve(labelColor, context, nullOk: nullOk)!;
final Color resolvedInactiveGray = CupertinoDynamicColor.resolve(inactiveGrayColor, context, nullOk: nullOk)!;
_TextThemeDefaultsBuilder resolveFrom(BuildContext context) {
final Color resolvedLabelColor = CupertinoDynamicColor.resolve(labelColor, context);
final Color resolvedInactiveGray = CupertinoDynamicColor.resolve(inactiveGrayColor, context);
return resolvedLabelColor == labelColor && resolvedInactiveGray == CupertinoColors.inactiveGray
? this
: _TextThemeDefaultsBuilder(resolvedLabelColor, resolvedInactiveGray);
......
......@@ -68,7 +68,7 @@ class CupertinoTheme extends StatelessWidget {
/// given [BuildContext] on a best-effort basis.
static CupertinoThemeData of(BuildContext context) {
final _InheritedCupertinoTheme? inheritedTheme = context.dependOnInheritedWidgetOfExactType<_InheritedCupertinoTheme>();
return (inheritedTheme?.theme.data ?? const CupertinoThemeData()).resolveFrom(context, nullOk: true);
return (inheritedTheme?.theme.data ?? const CupertinoThemeData()).resolveFrom(context);
}
/// Retrieves the [Brightness] to use for descendant Cupertino widgets, based
......@@ -256,17 +256,17 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
}
@override
CupertinoThemeData resolveFrom(BuildContext context, { bool nullOk = false }) {
Color? convertColor(Color? color) => CupertinoDynamicColor.resolve(color, context, nullOk: nullOk);
CupertinoThemeData resolveFrom(BuildContext context) {
Color? convertColor(Color? color) => CupertinoDynamicColor.maybeResolve(color, context);
return CupertinoThemeData._rawWithDefaults(
brightness,
convertColor(super.primaryColor),
convertColor(super.primaryContrastingColor),
super.textTheme?.resolveFrom(context, nullOk: nullOk),
super.textTheme?.resolveFrom(context),
convertColor(super.barBackgroundColor),
convertColor(super.scaffoldBackgroundColor),
_defaults.resolveFrom(context, super.textTheme == null, nullOk: nullOk),
_defaults.resolveFrom(context, super.textTheme == null),
);
}
......@@ -406,14 +406,14 @@ class NoDefaultCupertinoThemeData {
/// Called by [CupertinoTheme.of] to resolve colors defined in the retrieved
/// [CupertinoThemeData].
@protected
NoDefaultCupertinoThemeData resolveFrom(BuildContext context, { bool nullOk = false }) {
Color? convertColor(Color? color) => CupertinoDynamicColor.resolve(color, context, nullOk: nullOk);
NoDefaultCupertinoThemeData resolveFrom(BuildContext context) {
Color? convertColor(Color? color) => CupertinoDynamicColor.maybeResolve(color, context);
return NoDefaultCupertinoThemeData(
brightness: brightness,
primaryColor: convertColor(primaryColor),
primaryContrastingColor: convertColor(primaryContrastingColor),
textTheme: textTheme?.resolveFrom(context, nullOk: nullOk),
textTheme: textTheme?.resolveFrom(context),
barBackgroundColor: convertColor(barBackgroundColor),
scaffoldBackgroundColor: convertColor(scaffoldBackgroundColor),
);
......@@ -462,9 +462,8 @@ class _CupertinoThemeDefaults {
final Color scaffoldBackgroundColor;
final _CupertinoTextThemeDefaults textThemeDefaults;
_CupertinoThemeDefaults resolveFrom(BuildContext context, bool resolveTextTheme, { required bool nullOk }) {
assert(nullOk != null);
Color convertColor(Color color) => CupertinoDynamicColor.resolve(color, context, nullOk: nullOk)!;
_CupertinoThemeDefaults resolveFrom(BuildContext context, bool resolveTextTheme) {
Color convertColor(Color color) => CupertinoDynamicColor.resolve(color, context);
return _CupertinoThemeDefaults(
brightness,
......@@ -472,7 +471,7 @@ class _CupertinoThemeDefaults {
convertColor(primaryContrastingColor),
convertColor(barBackgroundColor),
convertColor(scaffoldBackgroundColor),
resolveTextTheme ? textThemeDefaults.resolveFrom(context, nullOk: nullOk) : textThemeDefaults,
resolveTextTheme ? textThemeDefaults.resolveFrom(context) : textThemeDefaults,
);
}
}
......@@ -487,10 +486,10 @@ class _CupertinoTextThemeDefaults {
final Color labelColor;
final Color inactiveGray;
_CupertinoTextThemeDefaults resolveFrom(BuildContext context, { required bool nullOk }) {
_CupertinoTextThemeDefaults resolveFrom(BuildContext context) {
return _CupertinoTextThemeDefaults(
CupertinoDynamicColor.resolve(labelColor, context, nullOk: nullOk)!,
CupertinoDynamicColor.resolve(inactiveGray, context, nullOk: nullOk)!,
CupertinoDynamicColor.resolve(labelColor, context),
CupertinoDynamicColor.resolve(inactiveGray, context),
);
}
......
......@@ -1849,12 +1849,12 @@ class MaterialBasedCupertinoThemeData extends CupertinoThemeData {
}
@override
CupertinoThemeData resolveFrom(BuildContext context, { bool nullOk = false }) {
CupertinoThemeData resolveFrom(BuildContext context) {
// Only the cupertino override theme part will be resolved.
// If the color comes from the material theme it's not resolved.
return MaterialBasedCupertinoThemeData._(
_materialTheme,
_cupertinoOverrideTheme.resolveFrom(context, nullOk: nullOk),
_cupertinoOverrideTheme.resolveFrom(context),
);
}
}
......
......@@ -19,7 +19,7 @@ class DependentWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final Color resolved = CupertinoDynamicColor.resolve(color, context, nullOk: false)!;
final Color resolved = CupertinoDynamicColor.resolve(color, context);
return DecoratedBox(
decoration: BoxDecoration(color: resolved),
child: const SizedBox.expand(),
......@@ -165,7 +165,7 @@ void main() {
});
test('can resolve null color', () {
expect(CupertinoDynamicColor.resolve(null, _NullElement.instance), isNull);
expect(CupertinoDynamicColor.maybeResolve(null, _NullElement.instance), isNull);
});
test('withVibrancy constructor creates colors that may depend on vibrancy', () {
......@@ -280,10 +280,6 @@ void main() {
expect(tester.takeException(), null);
expect(find.byType(DependentWidget), paints..rect(color: color0));
expect(find.byType(DependentWidget), isNot(paints..rect(color: color1)));
// Asserts when the required dependency is missing.
await tester.pumpWidget(const DependentWidget(color: contrastDependentColor1));
expect(tester.takeException()?.toString(), contains('No MediaQuery widget ancestor found'));
});
testWidgets(
......@@ -312,10 +308,6 @@ void main() {
expect(tester.takeException(), null);
expect(find.byType(DependentWidget), paints..rect(color: color0));
expect(find.byType(DependentWidget), isNot(paints..rect(color: color1)));
// Asserts when the required dependency is missing.
await tester.pumpWidget(const DependentWidget(color: elevationDependentColor1));
expect(tester.takeException()?.toString(), contains('does not contain a CupertinoUserInterfaceLevel'));
});
testWidgets('Dynamic color with all 3 dependencies works', (WidgetTester tester) async {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment