forked from firka/flutter
Correct text selection pivot points (#71756)
This commit is contained in:
committed by
GitHub
parent
a42aa04826
commit
fb3dba74b7
@@ -678,6 +678,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
||||
newSelection = newSelection.copyWith(extentOffset: textSelection.extentOffset);
|
||||
}
|
||||
} else {
|
||||
// The directional arrows move the TextSelection.extentOffset, while the
|
||||
// base remains fixed.
|
||||
if (rightArrow && newSelection.extentOffset < _plainText.length) {
|
||||
int nextExtent;
|
||||
if (!shift && !wordModifier && !lineModifier && newSelection.start != newSelection.end) {
|
||||
@@ -1849,6 +1851,9 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
||||
}
|
||||
|
||||
/// Select text between the global positions [from] and [to].
|
||||
///
|
||||
/// [from] corresponds to the [TextSelection.baseOffset], and [to] corresponds
|
||||
/// to the [TextSelection.extentOffset].
|
||||
void selectPositionAt({ required Offset from, Offset? to, required SelectionChangedCause cause }) {
|
||||
assert(cause != null);
|
||||
assert(from != null);
|
||||
@@ -1861,12 +1866,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
||||
? 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);
|
||||
}
|
||||
final int baseOffset = fromPosition.offset;
|
||||
final int extentOffset = toPosition?.offset ?? fromPosition.offset;
|
||||
|
||||
final TextSelection newSelection = TextSelection(
|
||||
baseOffset: baseOffset,
|
||||
|
||||
@@ -1458,8 +1458,8 @@ void main() {
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(controller.selection.baseOffset, testValue.indexOf('e'));
|
||||
expect(controller.selection.extentOffset, testValue.indexOf('g'));
|
||||
expect(controller.selection.baseOffset, testValue.indexOf('g'));
|
||||
expect(controller.selection.extentOffset, testValue.indexOf('e'));
|
||||
});
|
||||
|
||||
testWidgets('Slow mouse dragging also selects text', (WidgetTester tester) async {
|
||||
|
||||
@@ -570,8 +570,8 @@ void main() {
|
||||
pumpFrame();
|
||||
|
||||
expect(currentSelection.isCollapsed, isFalse);
|
||||
expect(currentSelection.baseOffset, 1);
|
||||
expect(currentSelection.extentOffset, 3);
|
||||
expect(currentSelection.baseOffset, 3);
|
||||
expect(currentSelection.extentOffset, 1);
|
||||
});
|
||||
|
||||
test('selection does not flicker as user is dragging', () {
|
||||
@@ -1006,7 +1006,79 @@ void main() {
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
|
||||
expect(currentSelection.isCollapsed, true);
|
||||
expect(currentSelection.baseOffset, 2);
|
||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/58068
|
||||
|
||||
test('arrow keys with selection text and shift', () async {
|
||||
final TextSelectionDelegate delegate = FakeEditableTextState();
|
||||
final ViewportOffset viewportOffset = ViewportOffset.zero();
|
||||
late 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;
|
||||
},
|
||||
startHandleLayerLink: LayerLink(),
|
||||
endHandleLayerLink: LayerLink(),
|
||||
text: const TextSpan(
|
||||
text: '012345', // Thumbs up
|
||||
style: TextStyle(height: 1.0, fontSize: 10.0, fontFamily: 'Ahem'),
|
||||
),
|
||||
selection: const TextSelection.collapsed(
|
||||
offset: 0,
|
||||
),
|
||||
);
|
||||
|
||||
layout(editable);
|
||||
editable.hasFocus = true;
|
||||
|
||||
editable.selection = const TextSelection(baseOffset: 2, extentOffset: 4);
|
||||
pumpFrame();
|
||||
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight);
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.arrowRight);
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
|
||||
expect(currentSelection.isCollapsed, false);
|
||||
expect(currentSelection.baseOffset, 2);
|
||||
expect(currentSelection.extentOffset, 5);
|
||||
|
||||
editable.selection = const TextSelection(baseOffset: 4, extentOffset: 2);
|
||||
pumpFrame();
|
||||
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight);
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.arrowRight);
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
|
||||
expect(currentSelection.isCollapsed, false);
|
||||
expect(currentSelection.baseOffset, 4);
|
||||
expect(currentSelection.extentOffset, 3);
|
||||
|
||||
editable.selection = const TextSelection(baseOffset: 2, extentOffset: 4);
|
||||
pumpFrame();
|
||||
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
|
||||
expect(currentSelection.isCollapsed, false);
|
||||
expect(currentSelection.baseOffset, 2);
|
||||
expect(currentSelection.extentOffset, 3);
|
||||
|
||||
editable.selection = const TextSelection(baseOffset: 4, extentOffset: 2);
|
||||
pumpFrame();
|
||||
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
|
||||
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
|
||||
expect(currentSelection.isCollapsed, false);
|
||||
expect(currentSelection.baseOffset, 4);
|
||||
expect(currentSelection.extentOffset, 1);
|
||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/58068
|
||||
|
||||
group('delete', () {
|
||||
|
||||
@@ -765,8 +765,8 @@ void main() {
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(controller.selection.baseOffset, 5);
|
||||
expect(controller.selection.extentOffset, 8);
|
||||
expect(controller.selection.baseOffset, 8);
|
||||
expect(controller.selection.extentOffset, 5);
|
||||
});
|
||||
|
||||
testWidgets('Slow mouse dragging also selects text', (WidgetTester tester) async {
|
||||
|
||||
Reference in New Issue
Block a user