Make sure the selection is still painted under the text (#27970)
This commit is contained in:
parent
d1371cd269
commit
22f8880909
@ -1544,19 +1544,28 @@ class RenderEditable extends RenderBox {
|
|||||||
assert(_textLayoutLastWidth == constraints.maxWidth);
|
assert(_textLayoutLastWidth == constraints.maxWidth);
|
||||||
final Offset effectiveOffset = offset + _paintOffset;
|
final Offset effectiveOffset = offset + _paintOffset;
|
||||||
|
|
||||||
|
bool showSelection = false;
|
||||||
|
bool showCaret = false;
|
||||||
|
|
||||||
|
if (_selection != null && !_floatingCursorOn) {
|
||||||
|
if (_selection.isCollapsed && _showCursor.value && cursorColor != null)
|
||||||
|
showCaret = true;
|
||||||
|
else if (!_selection.isCollapsed && _selectionColor != null)
|
||||||
|
showSelection = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSelection) {
|
||||||
|
_selectionRects ??= _textPainter.getBoxesForSelection(_selection);
|
||||||
|
_paintSelection(context.canvas, effectiveOffset);
|
||||||
|
}
|
||||||
|
|
||||||
// On iOS, the cursor is painted over the text, on Android, it's painted
|
// On iOS, the cursor is painted over the text, on Android, it's painted
|
||||||
// under it.
|
// under it.
|
||||||
if (paintCursorAboveText)
|
if (paintCursorAboveText)
|
||||||
_textPainter.paint(context.canvas, effectiveOffset);
|
_textPainter.paint(context.canvas, effectiveOffset);
|
||||||
|
|
||||||
if (_selection != null && !_floatingCursorOn) {
|
if (showCaret)
|
||||||
if (_selection.isCollapsed && _showCursor.value && cursorColor != null) {
|
_paintCaret(context.canvas, effectiveOffset, _selection.extent);
|
||||||
_paintCaret(context.canvas, effectiveOffset, _selection.extent);
|
|
||||||
} else if (!_selection.isCollapsed && _selectionColor != null) {
|
|
||||||
_selectionRects ??= _textPainter.getBoxesForSelection(_selection);
|
|
||||||
_paintSelection(context.canvas, effectiveOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!paintCursorAboveText)
|
if (!paintCursorAboveText)
|
||||||
_textPainter.paint(context.canvas, effectiveOffset);
|
_textPainter.paint(context.canvas, effectiveOffset);
|
||||||
|
@ -168,4 +168,89 @@ void main() {
|
|||||||
|
|
||||||
expect(editable, paintsExactlyCountTimes(#drawRRect, 0));
|
expect(editable, paintsExactlyCountTimes(#drawRRect, 0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('text is painted above selection', () {
|
||||||
|
final TextSelectionDelegate delegate = FakeEditableTextState();
|
||||||
|
final RenderEditable editable = RenderEditable(
|
||||||
|
backgroundCursorColor: Colors.grey,
|
||||||
|
selectionColor: Colors.black,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
cursorColor: const Color.fromARGB(0xFF, 0xFF, 0x00, 0x00),
|
||||||
|
offset: ViewportOffset.zero(),
|
||||||
|
textSelectionDelegate: delegate,
|
||||||
|
text: const TextSpan(
|
||||||
|
text: 'test',
|
||||||
|
style: TextStyle(
|
||||||
|
height: 1.0, fontSize: 10.0, fontFamily: 'Ahem',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
selection: const TextSelection(
|
||||||
|
baseOffset: 0,
|
||||||
|
extentOffset: 3,
|
||||||
|
affinity: TextAffinity.upstream,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
layout(editable);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
editable,
|
||||||
|
paints
|
||||||
|
// This is a big selection rectangle, not the cursor.
|
||||||
|
..rect(color: Colors.black, rect: Rect.fromLTWH(0, 0, 30, 10))
|
||||||
|
..paragraph(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// There is exactly one rect paint (1 selection, 0 cursor).
|
||||||
|
expect(editable, paintsExactlyCountTimes(#drawRect, 1));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('cursor can paint above or below the text', () {
|
||||||
|
final TextSelectionDelegate delegate = FakeEditableTextState();
|
||||||
|
final ValueNotifier<bool> showCursor = ValueNotifier<bool>(true);
|
||||||
|
final RenderEditable editable = RenderEditable(
|
||||||
|
backgroundCursorColor: Colors.grey,
|
||||||
|
selectionColor: Colors.black,
|
||||||
|
paintCursorAboveText: true,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
cursorColor: Colors.red,
|
||||||
|
showCursor: showCursor,
|
||||||
|
offset: ViewportOffset.zero(),
|
||||||
|
textSelectionDelegate: delegate,
|
||||||
|
text: const TextSpan(
|
||||||
|
text: 'test',
|
||||||
|
style: TextStyle(
|
||||||
|
height: 1.0, fontSize: 10.0, fontFamily: 'Ahem',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
selection: const TextSelection.collapsed(
|
||||||
|
offset: 2,
|
||||||
|
affinity: TextAffinity.upstream,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
layout(editable);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
editable,
|
||||||
|
paints
|
||||||
|
..paragraph()
|
||||||
|
..rect(color: Colors.red[500], rect: Rect.fromLTWH(20, 2, 1, 6)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// There is exactly one rect paint (0 selection, 1 cursor).
|
||||||
|
expect(editable, paintsExactlyCountTimes(#drawRect, 1));
|
||||||
|
|
||||||
|
editable.paintCursorAboveText = false;
|
||||||
|
pumpFrame();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
editable,
|
||||||
|
// The paint order is now flipped.
|
||||||
|
paints
|
||||||
|
..rect(color: Colors.red[500], rect: Rect.fromLTWH(20, 2, 1, 6))
|
||||||
|
..paragraph(),
|
||||||
|
);
|
||||||
|
expect(editable, paintsExactlyCountTimes(#drawRect, 1));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user