onDraw method
Override to react during the draw phase each frame.
Called after all registered listenOnDraw listeners.
Implementation
@override
void onDraw(double dt) => onTransform((t) {
final colors = FTextInputTheme.resolveStyle<T>(inputStyle).resolveState(this);
final RectangleD rect = .rect(t.position.x, t.position.y, size.x, size.y);
final disp = _displayText;
const roundness = 0.2;
// background
backend.render.drawRectangleRounded(rect, roundness, 8, colors.bg);
// ── scissor to inner area so text doesn't bleed out ──────────────────
backend.render.beginScissorMode(
t.position.x, t.position.y,
size.x, size.y,
);
final textY = t.position.y + (size.y - fontSize) / 2;
final baseX = t.position.x + _paddingX - _scrollOffsetX;
if (disp.isEmpty && placeholder.isNotEmpty) {
// placeholder
backend.render.drawTextEx(
app.defaultFont, placeholder,
.vec2(t.position.x + _paddingX, textY),
fontSize, fontSpacing, colors.placeholder,
);
} else {
// selection highlight
if (_hasSelection) {
final (lo, hi) = _selectionRange;
final selStartX = t.position.x + _rawXOfCharIndex(lo) - _scrollOffsetX;
final selEndX = t.position.x + _rawXOfCharIndex(hi) - _scrollOffsetX;
backend.render.drawRectangleRec(
.rect(selStartX, textY, selEndX - selStartX, fontSize),
colors.selection,
);
}
// text
backend.render.drawTextEx(
app.defaultFont, disp,
.vec2(baseX, textY),
fontSize, fontSpacing, colors.fg,
);
}
// cursor
if (isFocused && _cursorVisible) {
final cursorX = t.position.x + _rawXOfCharIndex(_cursorIndex) - _scrollOffsetX;
backend.render.drawRectangleRec(
.rect(cursorX, textY, 2, fontSize),
colors.cursor,
);
}
backend.render.endScissorMode();
// border (drawn after scissor so it's always fully visible)
backend.render.drawRectangleRoundedLinesEx(rect, roundness, 8, 2, borderOverride ?? colors.border);
});