drawPin method
void
drawPin()
override
Implementation
@override
void drawPin(
Canvas canvas,
Size size,
String text,
int pinLength,
Cursor? cursor,
TextDirection textDirection,
) {
/// Calculate the height of paint area for drawing the pin field.
/// it should honor the error text (if any) drawn by
/// the actual texfield behind.
/// but, since we can access the drawn textfield behind from here,
/// we use a simple logic to calculate it.
double mainHeight;
if (errorText != null && errorText!.isNotEmpty) {
mainHeight = size.height - (errorTextStyle?.fontSize ?? 0 + 8.0);
} else {
mainHeight = size.height;
}
Paint borderPaint = Paint()
..color = strokeColor
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke
..isAntiAlias = true;
/// Assign paint if [solidColor] is not null
Paint? insidePaint;
if (bgColorBuilder != null) {
insidePaint = Paint()
..strokeWidth = strokeWidth
..style = PaintingStyle.fill
..isAntiAlias = true;
}
Rect rect = Rect.fromLTRB(
strokeWidth / 2,
strokeWidth / 2,
size.width - strokeWidth / 2,
mainHeight - strokeWidth / 2,
);
/// Draw the whole rect.
canvas.drawRRect(RRect.fromRectAndRadius(rect, radius), borderPaint);
/// Calculate the width of each underline.
double singleWidth =
(size.width - strokeWidth * (pinLength + 1)) / pinLength;
for (int i = 0; i < pinLength; i++) {
if (insidePaint != null) {
var corners = _getCorner(i, pinLength);
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(
singleWidth * i + strokeWidth * (i + 1),
strokeWidth,
singleWidth,
mainHeight - strokeWidth * 2,
),
topLeft: corners[0],
topRight: corners[1],
bottomRight: corners[2],
bottomLeft: corners[3],
),
insidePaint..color = bgColorBuilder!.indexProperty(i),
);
}
if (i == 0) continue;
double offsetX = singleWidth +
strokeWidth * i +
strokeWidth / 2 +
singleWidth * (i - 1);
canvas.drawLine(Offset(offsetX, strokeWidth),
Offset(offsetX, mainHeight - strokeWidth), borderPaint);
}
/// The char index of the [text]
var index = 0;
var startY = 0.0;
var startX = 0.0;
/// Determine whether display obscureText.
bool obscureOn = obscureStyle != null && obscureStyle!.isTextObscure;
TextPainter textPainter;
for (var rune in text.runes) {
String code;
if (obscureOn) {
code = obscureStyle!.obscureText;
} else {
code = String.fromCharCode(rune);
}
textPainter = TextPainter(
text: TextSpan(
style: textStyle,
text: code,
),
textAlign: TextAlign.center,
textDirection: textDirection,
);
/// Layout the text.
textPainter.layout();
/// No need to compute again
if (startY == 0.0) {
startY = mainHeight / 2 - textPainter.height / 2;
}
startX = strokeWidth * (index + 1) +
singleWidth * index +
singleWidth / 2 -
textPainter.width / 2;
textPainter.paint(canvas, Offset(startX, startY));
index++;
}
/// Setup the cursor.
final int cursorIndex = index;
Offset? cursorOffset;
/// Fill the remaining space with hint text.
if (hintText != null) {
hintText!.substring(index).runes.forEach((rune) {
String code = String.fromCharCode(rune);
textPainter = TextPainter(
text: TextSpan(
style: hintTextStyle,
text: code,
),
textAlign: TextAlign.center,
textDirection: textDirection,
);
/// Layout the text.
textPainter.layout();
/// Save the size of the first hint text to offset the cursor.
if (index == cursorIndex) {
cursorOffset = Offset(textPainter.size.width / 2, 0);
}
startY = mainHeight / 2 - textPainter.height / 2;
startX = strokeWidth * (index + 1) +
singleWidth * index +
singleWidth / 2 -
textPainter.width / 2;
textPainter.paint(canvas, Offset(startX, startY));
index++;
});
}
/// Draw the cursor if provided.
if (cursor != null && cursor.enabled && cursorIndex < pinLength) {
drawCursor(
canvas,
size,
Rect.fromLTWH(
singleWidth * cursorIndex + strokeWidth * cursorIndex,
0,
singleWidth,
size.height,
),
cursor,
cursorOffset,
textDirection,
);
}
}