Skip to content

Instantly share code, notes, and snippets.

@suragch
Created February 4, 2021 06:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suragch/a0a92ea4b8791202ea09ac9274a70670 to your computer and use it in GitHub Desktop.
Save suragch/a0a92ea4b8791202ea09ac9274a70670 to your computer and use it in GitHub Desktop.
Text affinity
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: HomeWidget(),
backgroundColor: Colors.white,
),
);
}
}
class HomeWidget extends StatefulWidget {
@override
_HomeWidgetState createState() => _HomeWidgetState();
}
class _HomeWidgetState extends State<HomeWidget> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(100.0),
child: CustomPaint(
size: Size(300, 300),
painter: LineWrappingAffinity(),
// painter: BidirectionalAffinity(), // <-- try this too
),
);
}
}
class LineWrappingAffinity extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// text
const text = '0123456789';
final textSpan = const TextSpan(
text: text,
style: TextStyle(fontSize: 50, color: Colors.black),
);
// draw text
final TextPainter textPainter = TextPainter()
..textDirection = TextDirection.ltr
..text = textSpan
..layout(maxWidth: 280);
textPainter.paint(canvas, Offset(0, 0));
// draw cursor
final cursorPaint = Paint()
..color = Colors.red
..style = PaintingStyle.fill
..strokeWidth = 1;
var caretOffset = textPainter.getOffsetForCaret(
TextPosition(offset: 9, affinity: TextAffinity.upstream),
Rect.zero,
);
final dx = caretOffset.dx;
final dy = caretOffset.dy;
final rect = Rect.fromLTRB(dx, dy, dx + 3, dy + textPainter.height / 2);
canvas.drawRect(rect, cursorPaint);
}
@override
bool shouldRepaint(CustomPainter old) {
return false;
}
}
class BidirectionalAffinity extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// text
const text = 'Helloשלום';
final textSpan = const TextSpan(
text: text,
style: TextStyle(fontSize: 50, color: Colors.black),
);
// painters
final TextPainter textPainter = TextPainter()
..textDirection = TextDirection.ltr
..text = textSpan
..layout();
final cursorPaint = Paint()
..color = Colors.red
..style = PaintingStyle.fill
..strokeWidth = 1;
// loop through each caret offset
var dy = 0.0;
for (var offset = 0; offset <= text.length; offset++) {
// draw text
textPainter.paint(canvas, Offset(0, dy));
// draw cursor
var caretOffset = textPainter.getOffsetForCaret(
TextPosition(offset: offset, affinity: TextAffinity.upstream),
Rect.zero,
);
final dx = caretOffset.dx;
final rect = Rect.fromLTRB(dx, dy, dx + 3, dy + textPainter.height);
canvas.drawRect(rect, cursorPaint);
dy += textPainter.height;
}
}
@override
bool shouldRepaint(CustomPainter old) {
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment