Unverified Commit a4d570f0 authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

SelectableText handles after Select All (#62072)

parent f707f6f6
......@@ -477,27 +477,44 @@ class _SelectableTextState extends State<SelectableText> with AutomaticKeepAlive
_controller = _TextSpanEditingController(
textSpan: widget.textSpan ?? TextSpan(text: widget.data)
);
_controller.addListener(_onControllerChanged);
}
@override
void didUpdateWidget(SelectableText oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.data != oldWidget.data || widget.textSpan != oldWidget.textSpan) {
_controller.removeListener(_onControllerChanged);
_controller = _TextSpanEditingController(
textSpan: widget.textSpan ?? TextSpan(text: widget.data)
);
_controller.addListener(_onControllerChanged);
}
if (_effectiveFocusNode.hasFocus && _controller.selection.isCollapsed) {
_showSelectionHandles = false;
} else {
_showSelectionHandles = true;
}
}
@override
void dispose() {
_focusNode?.dispose();
_controller.removeListener(_onControllerChanged);
super.dispose();
}
void _onControllerChanged() {
final bool showSelectionHandles = !_effectiveFocusNode.hasFocus
|| !_controller.selection.isCollapsed;
if (showSelectionHandles == _showSelectionHandles) {
return;
}
setState(() {
_showSelectionHandles = showSelectionHandles;
});
}
void _handleSelectionChanged(TextSelection selection, SelectionChangedCause cause) {
final bool willShowSelectionHandles = _shouldShowSelectionHandles(cause);
if (willShowSelectionHandles != _showSelectionHandles) {
......
......@@ -440,8 +440,6 @@ class TextSelectionOverlay {
OverlayEntry(builder: (BuildContext context) => _buildHandle(context, _TextSelectionHandlePosition.end)),
];
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor).insertAll(_handles);
}
......
......@@ -3894,4 +3894,77 @@ void main() {
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
});
testWidgets('The handles show after pressing Select All', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Material(
child: SelectableText('abc def ghi'),
),
),
);
// Long press at 'e' in 'def'.
final Offset ePos = textOffsetToPosition(tester, 5);
await tester.longPressAt(ePos);
await tester.pumpAndSettle();
expect(find.text('Select all'), findsOneWidget);
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Paste'), findsNothing);
expect(find.text('Cut'), findsNothing);
EditableTextState editableText = tester.state(find.byType(EditableText));
expect(editableText.selectionOverlay.handlesAreVisible, isTrue);
expect(editableText.selectionOverlay.toolbarIsVisible, isTrue);
await tester.tap(find.text('Select all'));
await tester.pump();
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Select all'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Cut'), findsNothing);
editableText = tester.state(find.byType(EditableText));
expect(editableText.selectionOverlay.handlesAreVisible, isTrue);
},
variant: const TargetPlatformVariant(<TargetPlatform>{
TargetPlatform.android,
TargetPlatform.fuchsia,
TargetPlatform.linux,
TargetPlatform.windows,
}),
);
testWidgets('The handles show after pressing Select All (iOS and Mac)', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Material(
child: SelectableText('abc def ghi'),
),
),
);
// Long press at 'e' in 'def'.
final Offset ePos = textOffsetToPosition(tester, 5);
await tester.longPressAt(ePos);
await tester.pumpAndSettle();
expect(find.text('Select All'), findsOneWidget);
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Cut'), findsNothing);
EditableTextState editableText = tester.state(find.byType(EditableText));
expect(editableText.selectionOverlay.handlesAreVisible, isFalse);
expect(editableText.selectionOverlay.toolbarIsVisible, isTrue);
await tester.tap(find.text('Select All'));
await tester.pumpAndSettle();
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Select All'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Cut'), findsNothing);
editableText = tester.state(find.byType(EditableText));
expect(editableText.selectionOverlay.handlesAreVisible, isTrue);
},
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
}
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