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()
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke
..isAntiAlias = true;
double gapTotalLength =
gapSpaces?.reduce((a, b) => a + b) ?? (pinLength - 1) * gapSpace;
List<double> actualGapSpaces =
gapSpaces ?? List.filled(pinLength - 1, gapSpace);
/// Calculate the width of each underline.
double singleWidth =
(size.width - strokeWidth * 2 * pinLength - gapTotalLength) / pinLength;
var startX = strokeWidth / 2;
var startY = mainHeight - strokeWidth / 2;
/// Assign paint if [bgColorBuilder] is not null
Paint? insidePaint;
if (bgColorBuilder != null) {
insidePaint = Paint()
..style = PaintingStyle.fill
..isAntiAlias = true;
}
/// Draw the each rect of pin.
for (int i = 0; i < pinLength; i++) {
if (errorText != null && errorText!.isNotEmpty) {
/// only draw error-color as border-color or solid-color
/// if errorText is not null
borderPaint.color =
errorTextStyle?.color ?? strokeColorBuilder.indexProperty(i);
} else {
borderPaint.color = strokeColorBuilder.indexProperty(i);
}
RRect rRect = RRect.fromRectAndRadius(
Rect.fromLTRB(
startX,
strokeWidth / 2,
startX + singleWidth + strokeWidth,
startY,
),
radius);
canvas.drawRRect(rRect, borderPaint);
if (insidePaint != null) {
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTRB(
startX + strokeWidth / 2,
strokeWidth,
startX + singleWidth + strokeWidth / 2,
startY - strokeWidth / 2,
),
getInnerRadius(radius, strokeWidth)),
insidePaint..color = bgColorBuilder!.indexProperty(i));
}
startX += singleWidth +
strokeWidth * 2 +
(i == pinLength - 1 ? 0 : actualGapSpaces[i]);
}
/// The char index of the [text]
var index = 0;
startY = 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 = singleWidth * index +
singleWidth / 2 -
textPainter.width / 2 +
actualGapSpaces.take(index).sumList() +
strokeWidth * index * 2 +
strokeWidth;
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 = singleWidth * index +
singleWidth / 2 -
textPainter.width / 2 +
actualGapSpaces.take(index).sumList() +
strokeWidth * index * 2 +
strokeWidth;
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 +
actualGapSpaces.take(cursorIndex).sumList() +
strokeWidth * (cursorIndex * 2 + 1),
0,
singleWidth,
size.height,
),
cursor,
cursorOffset,
textDirection,
);
}
}