paint method
Default paint implementation.
RenderBox paints no self-content; it forwards painting to its RenderBox children. Subclasses override to draw their own content.
Implementation
@override
void paint(PaintingContext context, Offset offset) {
final originX = offset.dx + x;
final originY = offset.dy + y;
final canvas = context.canvas;
if (_backgroundColor != null) {
canvas.fillRect(
Rect.fromLTWH(originX, originY, width, height),
_backgroundColor!,
);
}
final isEmpty = _lines.length == 1 && _lines[0].isEmpty;
if (isEmpty && _placeholder != null && !_focused) {
// Render placeholder dimmed on first row only, cell-aware.
final dim = Color(
_color.r * 0.5,
_color.g * 0.5,
_color.b * 0.5,
_color.a,
);
final ph = _placeholder!;
var col = 0;
for (final cluster in ph.characters) {
final cw = terminalCellWidth(cluster);
if (col + cw > width) break;
canvas.setCell(
Offset(originX + col, originY),
cluster,
dim,
_backgroundColor ?? Color.transparent,
0,
);
col += cw;
}
} else {
for (var row = 0; row < height; row++) {
final lineIdx = _scrollLine + row;
if (lineIdx >= _lines.length) break;
final line = _lines[lineIdx];
var cellAccum = 0;
var paintedCol = 0;
for (final cluster in line.characters) {
final cw = terminalCellWidth(cluster);
if (cellAccum + cw <= _scrollCell) {
cellAccum += cw;
continue;
}
// The cluster crosses or starts past the scroll boundary. If it
// straddles the left edge (wide cluster at the boundary), drop it.
if (cellAccum < _scrollCell) {
cellAccum += cw;
continue;
}
if (paintedCol + cw > width) break;
canvas.setCell(
Offset(originX + paintedCol, originY + row),
cluster,
_color,
_backgroundColor ?? Color.transparent,
0,
);
paintedCol += cw;
cellAccum += cw;
}
}
}
if (_focused) {
final cursorRow = _cursorLine - _scrollLine;
final line = _lines[_cursorLine.clamp(0, _lines.length - 1)];
final cursorAbsoluteCell = graphemeIndexToCell(line, _cursorColumn);
final cursorCol = cursorAbsoluteCell - _scrollCell;
if (cursorRow >= 0 &&
cursorRow < height &&
cursorCol >= 0 &&
cursorCol < width) {
_cursorController.showCursor(
this,
originX + cursorCol,
originY + cursorRow,
style: _cursorStyle,
color: _cursorColor,
);
} else {
_cursorController.hideCursorFor(this);
}
} else {
_cursorController.hideCursorFor(this);
}
}