mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix text selection when user is dragging in the opposite direction (#29395)
This commit is contained in:
parent
28290f90de
commit
5787fc3ae2
@ -1377,10 +1377,18 @@ class RenderEditable extends RenderBox {
|
||||
final TextPosition toPosition = to == null
|
||||
? null
|
||||
: _textPainter.getPositionForOffset(globalToLocal(to - _paintOffset));
|
||||
|
||||
int baseOffset = fromPosition.offset;
|
||||
int extentOffset = fromPosition.offset;
|
||||
if (toPosition != null) {
|
||||
baseOffset = math.min(fromPosition.offset, toPosition.offset);
|
||||
extentOffset = math.max(fromPosition.offset, toPosition.offset);
|
||||
}
|
||||
|
||||
onSelectionChanged(
|
||||
TextSelection(
|
||||
baseOffset: fromPosition.offset,
|
||||
extentOffset: toPosition?.offset ?? fromPosition.offset,
|
||||
baseOffset: baseOffset,
|
||||
extentOffset: extentOffset,
|
||||
affinity: fromPosition.affinity,
|
||||
),
|
||||
this,
|
||||
|
@ -645,6 +645,38 @@ void main() {
|
||||
expect(controller.selection.extentOffset, testValue.indexOf('g'));
|
||||
});
|
||||
|
||||
testWidgets('Dragging in opposite direction also works', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: TextField(
|
||||
dragStartBehavior: DragStartBehavior.down,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const String testValue = 'abc def ghi';
|
||||
await tester.enterText(find.byType(TextField), testValue);
|
||||
await skipPastScrollingAnimation(tester);
|
||||
|
||||
final Offset ePos = textOffsetToPosition(tester, testValue.indexOf('e'));
|
||||
final Offset gPos = textOffsetToPosition(tester, testValue.indexOf('g'));
|
||||
|
||||
final TestGesture gesture = await tester.startGesture(gPos, kind: PointerDeviceKind.mouse);
|
||||
await tester.pump();
|
||||
await gesture.moveTo(ePos);
|
||||
await tester.pump();
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(controller.selection.baseOffset, testValue.indexOf('e'));
|
||||
expect(controller.selection.extentOffset, testValue.indexOf('g'));
|
||||
});
|
||||
|
||||
testWidgets('Slow mouse dragging also selects text', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController();
|
||||
|
||||
|
@ -335,4 +335,36 @@ void main() {
|
||||
expect(currentSelection.baseOffset, 5);
|
||||
expect(currentSelection.extentOffset, 9);
|
||||
});
|
||||
|
||||
test('selects correct place when offsets are flipped', () {
|
||||
final TextSelectionDelegate delegate = FakeEditableTextState();
|
||||
final ViewportOffset viewportOffset = ViewportOffset.zero();
|
||||
TextSelection currentSelection;
|
||||
final RenderEditable editable = RenderEditable(
|
||||
backgroundCursorColor: Colors.grey,
|
||||
selectionColor: Colors.black,
|
||||
textDirection: TextDirection.ltr,
|
||||
cursorColor: Colors.red,
|
||||
offset: viewportOffset,
|
||||
textSelectionDelegate: delegate,
|
||||
onSelectionChanged: (TextSelection selection, RenderEditable renderObject, SelectionChangedCause cause) {
|
||||
currentSelection = selection;
|
||||
},
|
||||
text: const TextSpan(
|
||||
text: 'abc def ghi',
|
||||
style: TextStyle(
|
||||
height: 1.0, fontSize: 10.0, fontFamily: 'Ahem',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
layout(editable);
|
||||
|
||||
editable.selectPositionAt(from: const Offset(30, 2), to: const Offset(10, 2), cause: SelectionChangedCause.drag);
|
||||
pumpFrame();
|
||||
|
||||
expect(currentSelection.isCollapsed, isFalse);
|
||||
expect(currentSelection.baseOffset, 1);
|
||||
expect(currentSelection.extentOffset, 3);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user