CupertinoSegmentedControl/CupertinoSlidingSegmentedControl: Add clickable cursor for web (#99551)

This commit is contained in:
Taha Tesser 2022-03-28 11:40:11 +03:00 committed by GitHub
parent d2cb63c8fa
commit e4bd5d5562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 113 additions and 25 deletions

View File

@ -5,6 +5,7 @@
import 'dart:collection';
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
@ -351,24 +352,27 @@ class _SegmentedControlState<T extends Object> extends State<CupertinoSegmentedC
child: widget.children[currentKey],
);
child = GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (TapDownDetails event) {
_onTapDown(currentKey);
},
onTapCancel: _onTapCancel,
onTap: () {
_onTap(currentKey);
},
child: IconTheme(
data: iconTheme,
child: DefaultTextStyle(
style: textStyle,
child: Semantics(
button: true,
inMutuallyExclusiveGroup: true,
selected: widget.groupValue == currentKey,
child: child,
child = MouseRegion(
cursor: kIsWeb ? SystemMouseCursors.click : MouseCursor.defer,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (TapDownDetails event) {
_onTapDown(currentKey);
},
onTapCancel: _onTapCancel,
onTap: () {
_onTap(currentKey);
},
child: IconTheme(
data: iconTheme,
child: DefaultTextStyle(
style: textStyle,
child: Semantics(
button: true,
inMutuallyExclusiveGroup: true,
selected: widget.groupValue == currentKey,
child: child,
),
),
),
),

View File

@ -4,6 +4,7 @@
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/physics.dart';
import 'package:flutter/rendering.dart';
@ -656,12 +657,15 @@ class _SegmentedControlState<T> extends State<CupertinoSlidingSegmentedControl<T
onTap: () { widget.onValueChanged(entry.key); },
inMutuallyExclusiveGroup: true,
selected: widget.groupValue == entry.key,
child: _Segment<T>(
key: ValueKey<T>(entry.key),
highlighted: isHighlighted,
pressed: pressed == entry.key,
isDragging: isThumbDragging,
child: entry.value,
child: MouseRegion(
cursor: kIsWeb ? SystemMouseCursors.click : MouseCursor.defer,
child: _Segment<T>(
key: ValueKey<T>(entry.key),
highlighted: isHighlighted,
pressed: pressed == entry.key,
isDragging: isThumbDragging,
child: entry.value,
),
),
),
);

View File

@ -9,6 +9,8 @@
import 'dart:ui' as ui;
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
@ -1577,4 +1579,47 @@ void main() {
matchesGoldenFile('segmented_control_test.1.png'),
);
});
testWidgets('Hovering over Cupertino segmented control updates cursor to clickable on Web', (WidgetTester tester) async {
final Map<int, Widget> children = <int, Widget>{};
children[0] = const Text('A');
children[1] = const Text('B');
children[2] = const Text('C');
const int currentValue = 0;
await tester.pumpWidget(
RepaintBoundary(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return boilerplate(
child: SizedBox(
width: 800.0,
child: CupertinoSegmentedControl<int>(
key: const ValueKey<String>('Segmented Control'),
children: children,
onValueChanged: (int newValue) { },
groupValue: currentValue,
),
),
);
},
),
),
);
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
await gesture.addPointer(location: const Offset(10, 10));
await tester.pumpAndSettle();
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
final Offset firstChild = tester.getCenter(find.text('A'));
await gesture.moveTo(firstChild);
addTearDown(gesture.removePointer);
await tester.pumpAndSettle();
expect(
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
);
});
}

View File

@ -5,6 +5,8 @@
import 'dart:collection';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
@ -1244,7 +1246,6 @@ void main() {
}
});
testWidgets('ScrollView + SlidingSegmentedControl interaction', (WidgetTester tester) async {
const Map<int, Widget> children = <int, Widget>{
0: Text('Child 1'),
@ -1330,4 +1331,38 @@ void main() {
expect(scrollController.offset, 0);
expect(groupValue, 1);
});
testWidgets('Hovering over Cupertino sliding segmented control updates cursor to clickable on Web', (WidgetTester tester) async {
const Map<int, Widget> children = <int, Widget>{
0: Text('A'),
1: Text('BB'),
2: Text('CCCC'),
};
await tester.pumpWidget(
boilerplate(
builder: (BuildContext context) {
return CupertinoSlidingSegmentedControl<int>(
key: const ValueKey<String>('Segmented Control'),
children: children,
onValueChanged: defaultCallback,
);
},
),
);
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
await gesture.addPointer(location: const Offset(10, 10));
await tester.pumpAndSettle();
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
final Offset firstChild = tester.getCenter(find.text('A'));
await gesture.moveTo(firstChild);
addTearDown(gesture.removePointer);
await tester.pumpAndSettle();
expect(
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
);
});
}