performPaint method
Hook for subclasses to implement actual painting.
Implementation
@override
void performPaint(Buffer buffer, Offset offset) {
final table = widget as Table;
final w = size.width;
final h = size.height;
if (table.headers.isEmpty ||
table.columnWidths.isEmpty ||
h <= 2 ||
w <= 0) {
return;
}
// 1. Render Headers
final headerSb = StringBuffer();
for (var i = 0; i < table.headers.length; i++) {
final width = resolvedColumnWidths[i];
final text = table.headers[i];
final padded = padOrTruncate(text, width);
headerSb.write(padded);
if (i < table.headers.length - 1) headerSb.write(' ');
}
final int columnsTotalWidth =
resolvedColumnWidths.fold<int>(0, (prev, val) => prev + val) +
(table.headers.isNotEmpty ? table.headers.length - 1 : 0);
String headerStr;
if (columnsTotalWidth <= w) {
if (columnsTotalWidth < w) {
headerSb.write(' ' * (w - columnsTotalWidth));
}
headerStr = headerSb.toString();
} else {
headerStr = padOrTruncate(headerSb.toString(), w);
}
buffer.writeString(offset.dx, offset.dy, headerStr, table.headerStyle);
// 2. Render Header Divider Line
final dividerChar = '─';
final divider = dividerChar * w;
buffer.writeString(offset.dx, offset.dy + 1, divider, table.borderStyle);
// 3. Render Rows
final usableHeight = h - 2;
for (var r = 0; r < usableHeight; r++) {
final rowIdx = table.scrollOffset + r;
if (rowIdx >= table.rows.length) break;
final rowData = table.rows[rowIdx];
final isSelected = rowIdx == table.selectedRowIndex;
final currentStyle = isSelected ? table.selectedRowStyle : table.rowStyle;
int startX = 0;
for (var c = 0; c < table.headers.length; c++) {
final colWidth = resolvedColumnWidths[c];
final cellData = c < rowData.length ? rowData[c] : '';
final cellStartX = columnXOffsets[c];
final cellRect = Rect(
offset.dx + cellStartX,
offset.dy + 2 + r,
colWidth,
1,
);
final vp = Viewport(buffer, cellRect);
if (cellData is Widget) {
vp.fillAttributes(
char: ' ',
fg: currentStyle.foreground?.argb ?? 0,
bg: currentStyle.background?.argb ?? 0,
modifiers: currentStyle.modifiers,
);
final cellEl = cellElements[rowIdx][c];
if (cellEl != null) {
cellEl.paint(vp, Offset.zero);
}
} else {
final cellText = cellData.toString();
final padded = padOrTruncate(cellText, colWidth);
vp.writeString(0, 0, padded, currentStyle);
}
if (c < table.headers.length - 1) {
final sepX = cellStartX + colWidth;
if (sepX < w) {
buffer.writeString(
offset.dx + sepX,
offset.dy + 2 + r,
' ',
currentStyle,
);
}
}
startX += colWidth + 1;
}
if (startX < w) {
final remainder = w - startX;
buffer.writeString(
offset.dx + startX,
offset.dy + 2 + r,
' ' * remainder,
currentStyle,
);
}
}
}