RTL caret position (#60009)

This commit is contained in:
Justin McCandless 2020-06-22 18:58:03 -07:00 committed by GitHub
parent fc64e75a32
commit c105708426
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 4 deletions

View file

@ -563,6 +563,9 @@ class TextPainter {
}
_lastMinWidth = minWidth;
_lastMaxWidth = maxWidth;
// A change in layout invalidates the cached caret metrics as well.
_previousCaretPosition = null;
_previousCaretPrototype = null;
_paragraph.layout(ui.ParagraphConstraints(width: maxWidth));
if (minWidth != maxWidth) {
final double newWidth = maxIntrinsicWidth.clamp(minWidth, maxWidth) as double;

View file

@ -143,6 +143,8 @@ void main() {
const String kMoreThanFourLines =
kThreeLines +
"\nFourth line won't display and ends at";
// Gap between caret and edge of input, defined in editable.dart.
const int kCaretGap = 1;
setUp(() async {
debugResetSemanticsIdCounter();
@ -754,10 +756,7 @@ void main() {
const TextPosition(offset: testValueSpaces.length),
).bottomRight;
// Gap between caret and edge of input, defined in editable.dart.
const int _kCaretGap = 1;
expect(cursorOffsetSpaces.dx, inputWidth - _kCaretGap);
expect(cursorOffsetSpaces.dx, inputWidth - kCaretGap);
});
testWidgets('mobile obscureText control test', (WidgetTester tester) async {
@ -8011,4 +8010,63 @@ void main() {
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
await gesture.moveTo(center);
});
testWidgets('Caret rtl with changing width', (WidgetTester tester) async {
StateSetter setState;
bool isWide = false;
const double wideWidth = 300.0;
const double narrowWidth = 200.0;
final TextEditingController controller = TextEditingController();
await tester.pumpWidget(
boilerplate(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setter) {
setState = setter;
return Container(
width: isWide ? wideWidth : narrowWidth,
child: TextField(
key: textFieldKey,
controller: controller,
textDirection: TextDirection.rtl,
),
);
}
),
),
);
// The cursor is on the right of the input because it's RTL.
RenderEditable editable = findRenderEditable(tester);
double cursorRight = editable.getLocalRectForCaret(
TextPosition(offset: controller.value.text.length),
).topRight.dx;
double inputWidth = editable.size.width;
expect(inputWidth, narrowWidth);
expect(cursorRight, inputWidth - kCaretGap);
// After entering some text, the cursor remains on the right of the input.
await tester.enterText(find.byType(TextField), '12345');
await tester.pump();
editable = findRenderEditable(tester);
cursorRight = editable.getLocalRectForCaret(
TextPosition(offset: controller.value.text.length),
).topRight.dx;
inputWidth = editable.size.width;
expect(cursorRight, inputWidth - kCaretGap);
// Since increasing the width of the input moves its right edge further to
// the right, the cursor has followed this change and still appears on the
// right of the input.
setState(() {
isWide = true;
});
await tester.pump();
editable = findRenderEditable(tester);
cursorRight = editable.getLocalRectForCaret(
TextPosition(offset: controller.value.text.length),
).topRight.dx;
inputWidth = editable.size.width;
expect(inputWidth, wideWidth);
expect(cursorRight, inputWidth - kCaretGap);
});
}