Skip to content

Commit 373efb0

Browse files
authored
Revert "Make CupertinoRadio's mouseCursor a WidgetStateProperty" (flutter#152254)
Reverts flutter#151910, awaiting further discussion on `WidgetStateProperty`.
1 parent 00eeabf commit 373efb0

File tree

4 files changed

+41
-93
lines changed

4 files changed

+41
-93
lines changed

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

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,24 @@ class CupertinoRadio<T> extends StatefulWidget {
132132
/// The cursor for a mouse pointer when it enters or is hovering over the
133133
/// widget.
134134
///
135-
/// Resolves in the following states:
135+
/// If [mouseCursor] is a [WidgetStateMouseCursor],
136+
/// [WidgetStateMouseCursor.resolve] is used for the following [WidgetState]s:
136137
///
137138
/// * [WidgetState.selected].
139+
/// * [WidgetState.hovered].
138140
/// * [WidgetState.focused].
139141
/// * [WidgetState.disabled].
140142
///
141-
/// Defaults to [defaultMouseCursor].
143+
/// If null, then [SystemMouseCursors.basic] is used when this radio button is disabled.
144+
/// When this radio button is enabled, [SystemMouseCursors.click] is used on Web, and
145+
/// [SystemMouseCursors.basic] is used on other platforms.
142146
///
143147
/// See also:
144148
///
145149
/// * [WidgetStateMouseCursor], a [MouseCursor] that implements
146150
/// `WidgetStateProperty` which is used in APIs that need to accept
147-
/// either a [MouseCursor] or a [WidgetStateProperty].
148-
final WidgetStateProperty<MouseCursor>? mouseCursor;
151+
/// either a [MouseCursor] or a [WidgetStateProperty<MouseCursor>].
152+
final MouseCursor? mouseCursor;
149153

150154
/// Set to true if this radio button is allowed to be returned to an
151155
/// indeterminate state by selecting it again when selected.
@@ -206,18 +210,6 @@ class CupertinoRadio<T> extends StatefulWidget {
206210

207211
bool get _selected => value == groupValue;
208212

209-
/// The default [mouseCursor] of a [CupertinoRadio].
210-
///
211-
/// If [onChanged] is null, indicating the radio button is disabled,
212-
/// [SystemMouseCursors.basic] is used. Otherwise, [SystemMouseCursors.click]
213-
/// is used on Web, and [SystemMouseCursors.basic] is used on other platforms.
214-
static WidgetStateProperty<MouseCursor> defaultMouseCursor(Function? onChanged) {
215-
final MouseCursor mouseCursor = (onChanged != null && kIsWeb)
216-
? SystemMouseCursors.click
217-
: SystemMouseCursors.basic;
218-
return WidgetStateProperty.all<MouseCursor>(mouseCursor);
219-
}
220-
221213
@override
222214
State<CupertinoRadio<T>> createState() => _CupertinoRadioState<T>();
223215
}
@@ -277,6 +269,15 @@ class _CupertinoRadioState<T> extends State<CupertinoRadio<T>> with TickerProvid
277269

278270
final Color effectiveFillColor = widget.fillColor ?? CupertinoColors.white;
279271

272+
final WidgetStateProperty<MouseCursor> effectiveMouseCursor =
273+
WidgetStateProperty.resolveWith<MouseCursor>((Set<WidgetState> states) {
274+
return WidgetStateProperty.resolveAs<MouseCursor?>(widget.mouseCursor, states)
275+
?? (states.contains(WidgetState.disabled)
276+
? SystemMouseCursors.basic
277+
: kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic
278+
);
279+
});
280+
280281
final bool? accessibilitySelected;
281282
// Apple devices also use `selected` to annotate radio button's semantics
282283
// state.
@@ -296,7 +297,7 @@ class _CupertinoRadioState<T> extends State<CupertinoRadio<T>> with TickerProvid
296297
checked: widget._selected,
297298
selected: accessibilitySelected,
298299
child: buildToggleable(
299-
mouseCursor: widget.mouseCursor ?? CupertinoRadio.defaultMouseCursor(widget.onChanged),
300+
mouseCursor: effectiveMouseCursor,
300301
focusNode: widget.focusNode,
301302
autofocus: widget.autofocus,
302303
onFocusChange: onFocusChange,

packages/flutter/lib/src/material/radio.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,11 +455,7 @@ class _RadioState<T> extends State<Radio<T>> with TickerProviderStateMixin, Togg
455455
value: widget.value,
456456
groupValue: widget.groupValue,
457457
onChanged: widget.onChanged,
458-
mouseCursor: widget.mouseCursor == null
459-
? CupertinoRadio.defaultMouseCursor(widget.onChanged)
460-
: WidgetStateProperty.resolveWith((Set<MaterialState> states) {
461-
return WidgetStateProperty.resolveAs<MouseCursor>(widget.mouseCursor!, states);
462-
}),
458+
mouseCursor: widget.mouseCursor,
463459
toggleable: widget.toggleable,
464460
activeColor: widget.activeColor,
465461
focusColor: widget.focusColor,

packages/flutter/test/cupertino/radio_test.dart

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ void main() {
441441
value: 1,
442442
groupValue: 1,
443443
onChanged: (int? i) { },
444-
mouseCursor: WidgetStateProperty.all(SystemMouseCursors.forbidden),
444+
mouseCursor: SystemMouseCursors.forbidden,
445445
),
446446
),
447447
));
@@ -463,25 +463,13 @@ void main() {
463463
final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
464464
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
465465

466-
MouseCursor getMouseCursor(Set<WidgetState> states) {
467-
if (states.contains(WidgetState.disabled)) {
468-
return SystemMouseCursors.forbidden;
469-
}
470-
if (states.contains(WidgetState.focused)) {
471-
return SystemMouseCursors.basic;
472-
}
473-
return SystemMouseCursors.click;
474-
}
475-
476-
final WidgetStateProperty<MouseCursor> mouseCursor = WidgetStateProperty.resolveWith(getMouseCursor);
477-
478466
await tester.pumpWidget(CupertinoApp(
479467
home: Center(
480468
child: CupertinoRadio<int>(
481469
value: 1,
482470
groupValue: 1,
483471
onChanged: (int? i) { },
484-
mouseCursor: mouseCursor,
472+
mouseCursor: const RadioMouseCursor(),
485473
focusNode: focusNode
486474
),
487475
),
@@ -510,13 +498,13 @@ void main() {
510498
);
511499

512500
// Test disabled case.
513-
await tester.pumpWidget(CupertinoApp(
501+
await tester.pumpWidget(const CupertinoApp(
514502
home: Center(
515503
child: CupertinoRadio<int>(
516504
value: 1,
517505
groupValue: 1,
518506
onChanged: null,
519-
mouseCursor: mouseCursor,
507+
mouseCursor: RadioMouseCursor(),
520508
),
521509
),
522510
));
@@ -553,3 +541,21 @@ void main() {
553541
);
554542
});
555543
}
544+
545+
class RadioMouseCursor extends WidgetStateMouseCursor {
546+
const RadioMouseCursor();
547+
548+
@override
549+
MouseCursor resolve(Set<WidgetState> states) {
550+
if (states.contains(WidgetState.disabled)) {
551+
return SystemMouseCursors.forbidden;
552+
}
553+
if (states.contains(WidgetState.focused)){
554+
return SystemMouseCursors.basic;
555+
}
556+
return SystemMouseCursors.click;
557+
}
558+
559+
@override
560+
String get debugDescription => 'RadioMouseCursor()';
561+
}

packages/flutter/test/material/radio_test.dart

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,46 +1859,6 @@ void main() {
18591859
}
18601860
});
18611861

1862-
testWidgets('Radio.adaptive respects Radio.mouseCursor', (WidgetTester tester) async {
1863-
Widget buildApp({required TargetPlatform platform, MouseCursor? mouseCursor}) {
1864-
return MaterialApp(
1865-
theme: ThemeData(platform: platform),
1866-
home: Material(
1867-
child: Radio<int>.adaptive(
1868-
value: 1,
1869-
groupValue: 1,
1870-
onChanged: (int? i) {},
1871-
mouseCursor: mouseCursor,
1872-
),
1873-
),
1874-
);
1875-
}
1876-
1877-
for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.iOS, TargetPlatform.macOS ]) {
1878-
await tester.pumpWidget(buildApp(platform: platform));
1879-
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
1880-
1881-
// Test default mouse cursor.
1882-
await gesture.addPointer(location: tester.getCenter(find.byType(CupertinoRadio<int>)));
1883-
await tester.pump();
1884-
await gesture.moveTo(tester.getCenter(find.byType(CupertinoRadio<int>)));
1885-
expect(
1886-
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
1887-
kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
1888-
);
1889-
1890-
// Test mouse cursor can be configured.
1891-
await tester.pumpWidget(buildApp(platform: platform, mouseCursor: SystemMouseCursors.forbidden));
1892-
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);
1893-
1894-
// Test Radio.adaptive can resolve a WidgetStateMouseCursor.
1895-
await tester.pumpWidget(buildApp(platform: platform, mouseCursor: const _SelectedGrabMouseCursor()));
1896-
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.grab);
1897-
1898-
await gesture.removePointer();
1899-
}
1900-
});
1901-
19021862
testWidgets('Material2 - Radio default overlayColor and fillColor resolves pressed state', (WidgetTester tester) async {
19031863
final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
19041864
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
@@ -2033,18 +1993,3 @@ void main() {
20331993
focusNode.dispose();
20341994
});
20351995
}
2036-
2037-
class _SelectedGrabMouseCursor extends WidgetStateMouseCursor {
2038-
const _SelectedGrabMouseCursor();
2039-
2040-
@override
2041-
MouseCursor resolve(Set<WidgetState> states) {
2042-
if (states.contains(WidgetState.selected)) {
2043-
return SystemMouseCursors.grab;
2044-
}
2045-
return SystemMouseCursors.basic;
2046-
}
2047-
2048-
@override
2049-
String get debugDescription => '_SelectedGrabMouseCursor()';
2050-
}

0 commit comments

Comments
 (0)