mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Match iOS Longpress behavior with native (#123630)
Match iOS Longpress behavior with native
This commit is contained in:
parent
9f2ac97174
commit
142dd6022f
@ -2005,6 +2005,14 @@ class TextSelectionGestureDetectorBuilder {
|
||||
// cursor will not move on drag update.
|
||||
bool? _dragBeganOnPreviousSelection;
|
||||
|
||||
// For iOS long press behavior when the field is not focused. iOS uses this value
|
||||
// to determine if a long press began on a field that was not focused.
|
||||
//
|
||||
// If the field was not focused when the long press began, a long press will select
|
||||
// the word and a long press move will select word-by-word. If the field was
|
||||
// focused, the cursor moves to the long press position.
|
||||
bool _longPressStartedWithoutFocus = false;
|
||||
|
||||
/// Handler for [TextSelectionGestureDetector.onTapDown].
|
||||
///
|
||||
/// By default, it forwards the tap to [RenderEditable.handleTapDown] and sets
|
||||
@ -2240,10 +2248,15 @@ class TextSelectionGestureDetectorBuilder {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
renderEditable.selectPositionAt(
|
||||
from: details.globalPosition,
|
||||
cause: SelectionChangedCause.longPress,
|
||||
);
|
||||
if (!renderEditable.hasFocus) {
|
||||
_longPressStartedWithoutFocus = true;
|
||||
renderEditable.selectWord(cause: SelectionChangedCause.longPress);
|
||||
} else {
|
||||
renderEditable.selectPositionAt(
|
||||
from: details.globalPosition,
|
||||
cause: SelectionChangedCause.longPress,
|
||||
);
|
||||
}
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
case TargetPlatform.linux:
|
||||
@ -2291,10 +2304,18 @@ class TextSelectionGestureDetectorBuilder {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
renderEditable.selectPositionAt(
|
||||
from: details.globalPosition,
|
||||
cause: SelectionChangedCause.longPress,
|
||||
);
|
||||
if (_longPressStartedWithoutFocus) {
|
||||
renderEditable.selectWordsInRange(
|
||||
from: details.globalPosition - details.offsetFromOrigin - editableOffset - scrollableOffset,
|
||||
to: details.globalPosition,
|
||||
cause: SelectionChangedCause.longPress,
|
||||
);
|
||||
} else {
|
||||
renderEditable.selectPositionAt(
|
||||
from: details.globalPosition,
|
||||
cause: SelectionChangedCause.longPress,
|
||||
);
|
||||
}
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
case TargetPlatform.linux:
|
||||
@ -2342,6 +2363,7 @@ class TextSelectionGestureDetectorBuilder {
|
||||
if (shouldShowSelectionToolbar) {
|
||||
editableText.showToolbar();
|
||||
}
|
||||
_longPressStartedWithoutFocus = false;
|
||||
_dragStartViewportOffset = 0.0;
|
||||
_dragStartScrollOffset = 0.0;
|
||||
}
|
||||
|
||||
@ -1591,6 +1591,7 @@ void main() {
|
||||
home: Column(
|
||||
children: <Widget>[
|
||||
CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
toolbarOptions: const ToolbarOptions(copy: true),
|
||||
),
|
||||
@ -1599,6 +1600,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
// Long press to put the cursor after the "w".
|
||||
const int index = 3;
|
||||
await tester.longPressAt(textOffsetToPosition(tester, index));
|
||||
@ -2060,12 +2064,16 @@ void main() {
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
// Long press to put the cursor after the "w".
|
||||
const int index = 3;
|
||||
await tester.longPressAt(textOffsetToPosition(tester, index));
|
||||
@ -2830,12 +2838,16 @@ void main() {
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final Offset textFieldStart = tester.getTopLeft(find.byType(CupertinoTextField));
|
||||
|
||||
await tester.longPressAt(textFieldStart + const Offset(50.0, 5.0));
|
||||
@ -2870,12 +2882,16 @@ void main() {
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final Offset ePos = textOffsetToPosition(tester, 6); // Index of 'Atwate|r'
|
||||
|
||||
await tester.longPressAt(ePos);
|
||||
@ -2971,7 +2987,7 @@ void main() {
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'long press drag moves the cursor under the drag and shows toolbar on lift on Apple platforms',
|
||||
'long press drag on a focused TextField moves the cursor under the drag and shows toolbar on lift on Apple platforms',
|
||||
(WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
@ -2980,12 +2996,16 @@ void main() {
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final Offset textFieldStart = tester.getTopLeft(find.byType(CupertinoTextField));
|
||||
|
||||
final TestGesture gesture =
|
||||
@ -3135,12 +3155,16 @@ void main() {
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final RenderEditable renderEditable = tester.renderObject<RenderEditable>(
|
||||
find.byElementPredicate((Element element) => element.renderObject is RenderEditable).last,
|
||||
);
|
||||
@ -3289,12 +3313,16 @@ void main() {
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
// Use a position higher than wPos to avoid tapping the context menu on
|
||||
// desktop.
|
||||
final Offset pPos = textOffsetToPosition(tester, 9) + const Offset(0.0, -20.0); // Index of 'P|eel'
|
||||
@ -7313,6 +7341,7 @@ void main() {
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
CupertinoTextField(
|
||||
autofocus: true,
|
||||
key: const Key('field0'),
|
||||
controller: controller,
|
||||
style: const TextStyle(height: 4, color: ui.Color.fromARGB(100, 0, 0, 0)),
|
||||
@ -7329,6 +7358,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final Offset textFieldStart = tester.getTopLeft(find.byKey(const Key('field0')));
|
||||
|
||||
await tester.longPressAt(textFieldStart + const Offset(50.0, 2.0));
|
||||
@ -7363,6 +7395,7 @@ void main() {
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
CupertinoTextField(
|
||||
autofocus: true,
|
||||
key: const Key('field0'),
|
||||
controller: controller,
|
||||
style: const TextStyle(height: 4, color: ui.Color.fromARGB(100, 0, 0, 0)),
|
||||
@ -7378,6 +7411,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final Offset textFieldStart = tester.getTopLeft(find.byKey(const Key('field0')));
|
||||
|
||||
await tester.longPressAt(textFieldStart + const Offset(50.0, 2.0));
|
||||
|
||||
@ -200,6 +200,7 @@ void main() {
|
||||
data: const MediaQueryData(size: Size(800.0, 600.0)),
|
||||
child: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
@ -207,6 +208,9 @@ void main() {
|
||||
),
|
||||
));
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
// Initially, the menu isn't shown at all.
|
||||
expect(find.text('Cut'), findsNothing);
|
||||
expect(find.text('Copy'), findsNothing);
|
||||
@ -432,6 +436,7 @@ void main() {
|
||||
data: const MediaQueryData(size: Size(800.0, 600.0)),
|
||||
child: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
@ -439,6 +444,9 @@ void main() {
|
||||
),
|
||||
));
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
// Initially, the menu isn't shown at all.
|
||||
expect(find.text(_longLocalizations.cutButtonLabel), findsNothing);
|
||||
expect(find.text(_longLocalizations.copyButtonLabel), findsNothing);
|
||||
@ -546,6 +554,7 @@ void main() {
|
||||
data: const MediaQueryData(size: Size(800.0, 600.0)),
|
||||
child: Center(
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
controller: controller,
|
||||
maxLines: 2,
|
||||
@ -555,6 +564,9 @@ void main() {
|
||||
),
|
||||
));
|
||||
|
||||
// This extra pump is so autofocus can propagate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
// Initially, the menu isn't shown at all.
|
||||
expect(find.text('Cut'), findsNothing);
|
||||
expect(find.text('Copy'), findsNothing);
|
||||
|
||||
@ -10717,7 +10717,51 @@ void main() {
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'long press moves cursor to the exact long press position and shows toolbar',
|
||||
'long press moves cursor to the exact long press position and shows toolbar when the field is focused',
|
||||
(WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump allows the selection set by autofocus to propagate to
|
||||
// the RenderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
|
||||
|
||||
await tester.longPressAt(textfieldStart + const Offset(50.0, 9.0));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Collapsed cursor for iOS long press.
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection.collapsed(offset: 3),
|
||||
);
|
||||
|
||||
// Collapsed toolbar shows 2 buttons.
|
||||
final int buttons = defaultTargetPlatform == TargetPlatform.iOS ? 2 : 1;
|
||||
expect(
|
||||
find.byType(CupertinoButton),
|
||||
isContextMenuProvidedByPlatform ? findsNothing : findsNWidgets(buttons),
|
||||
);
|
||||
},
|
||||
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'long press that starts on an unfocused TextField selects the word at the exact long press position and shows toolbar',
|
||||
(WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
@ -10742,14 +10786,13 @@ void main() {
|
||||
// Collapsed cursor for iOS long press.
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection.collapsed(offset: 3),
|
||||
const TextSelection(baseOffset: 0, extentOffset: 7),
|
||||
);
|
||||
|
||||
// Collapsed toolbar shows 2 buttons.
|
||||
final int buttons = defaultTargetPlatform == TargetPlatform.iOS ? 2 : 1;
|
||||
// Collapsed toolbar shows 3 buttons.
|
||||
expect(
|
||||
find.byType(CupertinoButton),
|
||||
isContextMenuProvidedByPlatform ? findsNothing : findsNWidgets(buttons),
|
||||
isContextMenuProvidedByPlatform ? findsNothing : findsNWidgets(3),
|
||||
);
|
||||
},
|
||||
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
|
||||
@ -10800,6 +10843,7 @@ void main() {
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
@ -10807,6 +10851,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propogate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final Offset ePos = textOffsetToPosition(tester, 6); // Index of 'Atwate|r'
|
||||
|
||||
await tester.longPressAt(ePos);
|
||||
@ -10910,7 +10957,7 @@ void main() {
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'long press drag moves the cursor under the drag and shows toolbar on lift',
|
||||
'long press drag on a focused TextField moves the cursor under the drag and shows toolbar on lift',
|
||||
(WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
@ -10920,6 +10967,7 @@ void main() {
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
@ -10927,6 +10975,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propogate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
|
||||
|
||||
final TestGesture gesture =
|
||||
@ -10981,6 +11032,77 @@ void main() {
|
||||
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'long press drag on an unfocused TextField selects word-by-word and shows toolbar on lift',
|
||||
(WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
|
||||
|
||||
final TestGesture gesture =
|
||||
await tester.startGesture(textfieldStart + const Offset(50.0, 9.0));
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Long press on iOS shows collapsed selection cursor.
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 7),
|
||||
);
|
||||
// Cursor move doesn't trigger a toolbar initially.
|
||||
expect(find.byType(CupertinoButton), findsNothing);
|
||||
|
||||
await gesture.moveBy(const Offset(100, 0));
|
||||
await tester.pump();
|
||||
|
||||
// The selection position is now moved with the drag.
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 12),
|
||||
);
|
||||
// Still no toolbar.
|
||||
expect(find.byType(CupertinoButton), findsNothing);
|
||||
|
||||
await gesture.moveBy(const Offset(100, 0));
|
||||
await tester.pump();
|
||||
|
||||
// The selection position is now moved with the drag.
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 23),
|
||||
);
|
||||
// Still no toolbar.
|
||||
expect(find.byType(CupertinoButton), findsNothing);
|
||||
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The selection isn't affected by the gesture lift.
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 23),
|
||||
);
|
||||
// The toolbar now shows up.
|
||||
expect(
|
||||
find.byType(CupertinoButton),
|
||||
isContextMenuProvidedByPlatform ? findsNothing : findsNWidgets(3),
|
||||
);
|
||||
},
|
||||
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
|
||||
);
|
||||
|
||||
testWidgets('long press drag can edge scroll on non-Apple platforms', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges',
|
||||
@ -11069,7 +11191,7 @@ void main() {
|
||||
expect(firstCharEndpoint[0].point.dx, moreOrLessEquals(-257.0, epsilon: 1));
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows }));
|
||||
|
||||
testWidgets('long press drag can edge scroll on Apple platforms', (WidgetTester tester) async {
|
||||
testWidgets('long press drag can edge scroll on Apple platforms - unfocused TextField', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges',
|
||||
);
|
||||
@ -11098,6 +11220,98 @@ void main() {
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
|
||||
|
||||
final TestGesture gesture =
|
||||
await tester.startGesture(textfieldStart);
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 7, affinity: TextAffinity.upstream),
|
||||
);
|
||||
expect(find.byType(CupertinoButton), findsNothing);
|
||||
|
||||
await gesture.moveBy(const Offset(900, 5));
|
||||
// To the edge of the screen basically.
|
||||
await tester.pump();
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 59),
|
||||
);
|
||||
// Keep moving out.
|
||||
await gesture.moveBy(const Offset(1, 0));
|
||||
await tester.pump();
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 66),
|
||||
);
|
||||
await gesture.moveBy(const Offset(1, 0));
|
||||
await tester.pump();
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 66, affinity: TextAffinity.upstream),
|
||||
); // We're at the edge now.
|
||||
expect(find.byType(CupertinoButton), findsNothing);
|
||||
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The selection isn't affected by the gesture lift.
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection(baseOffset: 0, extentOffset: 66, affinity: TextAffinity.upstream),
|
||||
);
|
||||
// The toolbar now shows up.
|
||||
expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : findsNWidgets(3));
|
||||
|
||||
lastCharEndpoint = renderEditable.getEndpointsForSelection(
|
||||
const TextSelection.collapsed(offset: 66), // Last character's position.
|
||||
);
|
||||
|
||||
expect(lastCharEndpoint.length, 1);
|
||||
// The last character is now on screen near the right edge.
|
||||
expect(lastCharEndpoint[0].point.dx, moreOrLessEquals(798, epsilon: 1));
|
||||
|
||||
final List<TextSelectionPoint> firstCharEndpoint = renderEditable.getEndpointsForSelection(
|
||||
const TextSelection.collapsed(offset: 0), // First character's position.
|
||||
);
|
||||
expect(firstCharEndpoint.length, 1);
|
||||
// The first character is now offscreen to the left.
|
||||
expect(firstCharEndpoint[0].point.dx, moreOrLessEquals(-257.0, epsilon: 1));
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('long press drag can edge scroll on Apple platforms - focused TextField', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propogate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
final RenderEditable renderEditable = findRenderEditable(tester);
|
||||
|
||||
List<TextSelectionPoint> lastCharEndpoint = renderEditable.getEndpointsForSelection(
|
||||
const TextSelection.collapsed(offset: 66), // Last character's position.
|
||||
);
|
||||
|
||||
expect(lastCharEndpoint.length, 1);
|
||||
// Just testing the test and making sure that the last character is off
|
||||
// the right side of the screen.
|
||||
expect(lastCharEndpoint[0].point.dx, 1056);
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
|
||||
|
||||
final TestGesture gesture =
|
||||
await tester.startGesture(textfieldStart + const Offset(300, 5));
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
@ -11309,6 +11523,7 @@ void main() {
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
autofocus: true,
|
||||
maxLines: 2,
|
||||
controller: controller,
|
||||
),
|
||||
@ -11317,6 +11532,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propogate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
// Just testing the test and making sure that the last character is outside
|
||||
// the bottom of the field.
|
||||
final int textLength = controller.text.length;
|
||||
@ -11595,6 +11813,7 @@ void main() {
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
autofocus: true,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
@ -11602,6 +11821,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// This extra pump is so autofocus can propogate to renderEditable.
|
||||
await tester.pump();
|
||||
|
||||
// The second tap is slightly higher to avoid tapping the context menu on
|
||||
// desktop.
|
||||
final Offset pPos = textOffsetToPosition(tester, 9) + const Offset(0.0, -20.0); // Index of 'P|eel'
|
||||
|
||||
@ -460,8 +460,12 @@ void main() {
|
||||
expect(dragEndCount, 1);
|
||||
});
|
||||
|
||||
testWidgets('test TextSelectionGestureDetectorBuilder long press on Apple Platforms', (WidgetTester tester) async {
|
||||
testWidgets('test TextSelectionGestureDetectorBuilder long press on Apple Platforms - focused renderEditable', (WidgetTester tester) async {
|
||||
await pumpTextSelectionGestureDetectorBuilder(tester);
|
||||
final FakeEditableTextState state = tester.state(find.byType(FakeEditableText));
|
||||
final FakeRenderEditable renderEditable = tester.renderObject(find.byType(FakeEditable));
|
||||
renderEditable.hasFocus = true;
|
||||
|
||||
final TestGesture gesture = await tester.startGesture(
|
||||
const Offset(200.0, 200.0),
|
||||
pointer: 0,
|
||||
@ -470,13 +474,29 @@ void main() {
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final FakeEditableTextState state = tester.state(find.byType(FakeEditableText));
|
||||
final FakeRenderEditable renderEditable = tester.renderObject(find.byType(FakeEditable));
|
||||
expect(state.showToolbarCalled, isTrue);
|
||||
expect(renderEditable.selectPositionAtCalled, isTrue);
|
||||
expect(renderEditable.lastCause, SelectionChangedCause.longPress);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('test TextSelectionGestureDetectorBuilder long press on iOS - renderEditable not focused', (WidgetTester tester) async {
|
||||
await pumpTextSelectionGestureDetectorBuilder(tester);
|
||||
final FakeEditableTextState state = tester.state(find.byType(FakeEditableText));
|
||||
final FakeRenderEditable renderEditable = tester.renderObject(find.byType(FakeEditable));
|
||||
|
||||
final TestGesture gesture = await tester.startGesture(
|
||||
const Offset(200.0, 200.0),
|
||||
pointer: 0,
|
||||
);
|
||||
await tester.pump(const Duration(seconds: 2));
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(state.showToolbarCalled, isTrue);
|
||||
expect(renderEditable.selectWordCalled, isTrue);
|
||||
expect(renderEditable.lastCause, SelectionChangedCause.longPress);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));
|
||||
|
||||
testWidgets('test TextSelectionGestureDetectorBuilder long press on non-Apple Platforms', (WidgetTester tester) async {
|
||||
await pumpTextSelectionGestureDetectorBuilder(tester);
|
||||
final TestGesture gesture = await tester.startGesture(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user