row method
columns
- List of column text content (can contain \n for multi-line)
widths
- List of width percentages (must sum to 100)
aligns
- Optional list of column alignments
fontSize
- Font size for the entire row
lineSpacing
- Additional spacing between multi-lines (default: 0)
Enhanced row function with better multi-line control
Allows different handling for each column's multi-line behavior
Implementation
PrintBuilder row(
List<String> columns,
List<int> widths, {
List<ColumnAlign>? aligns,
FontSize fontSize = FontSize.normal,
List<bool>? wrapColumns, // Which columns should wrap text vs truncate
int lineSpacing = 0,
}) {
// Validation checks
if (columns.length != widths.length) {
throw ArgumentError('Columns and widths must have the same length');
}
int totalWidth = widths.fold(0, (sum, width) => sum + width);
if (totalWidth != 100) {
throw ArgumentError('Total width must equal 100%');
}
List<ColumnAlign> columnAligns = aligns ?? List.filled(columns.length, ColumnAlign.left);
List<bool> shouldWrap = wrapColumns ?? List.filled(columns.length, true);
if (columnAligns.length != columns.length || shouldWrap.length != columns.length) {
throw ArgumentError('All parameter lists must match columns length');
}
int maxChars = paperSize.getMaxChars(fontSize);
// Process columns - wrap text if needed or split by existing newlines
List<List<String>> columnLines = [];
int maxLines = 0;
for (int i = 0; i < columns.length; i++) {
int colWidth = (maxChars * widths[i] / 100).floor();
List<String> lines;
if (shouldWrap[i]) {
// Split by existing newlines first, then wrap long lines
List<String> initialSplit = columns[i].split('\n');
lines = [];
for (String line in initialSplit) {
if (line.length <= colWidth) {
lines.add(line);
} else {
// Wrap long lines
for (int start = 0; start < line.length; start += colWidth) {
int end = (start + colWidth < line.length) ? start + colWidth : line.length;
lines.add(line.substring(start, end));
}
}
}
} else {
// Just split by newlines, truncate long lines
lines = columns[i].split('\n').map((line) {
if (line.length > colWidth && colWidth > 2) {
return '${line.substring(0, colWidth - 2)}..';
}
return line.length > colWidth ? line.substring(0, colWidth) : line;
}).toList();
}
columnLines.add(lines);
maxLines = maxLines > lines.length ? maxLines : lines.length;
}
// Generate each line
for (int lineIndex = 0; lineIndex < maxLines; lineIndex++) {
String line = '';
for (int colIndex = 0; colIndex < columns.length; colIndex++) {
int colWidth = (maxChars * widths[colIndex] / 100).floor();
String columnText = '';
if (lineIndex < columnLines[colIndex].length) {
columnText = columnLines[colIndex][lineIndex];
}
// Apply alignment
String formattedColumn;
switch (columnAligns[colIndex]) {
case ColumnAlign.left:
formattedColumn = columnText.padRight(colWidth);
break;
case ColumnAlign.center:
int totalPadding = colWidth - columnText.length;
int leftPadding = totalPadding ~/ 2;
int rightPadding = totalPadding - leftPadding;
formattedColumn = '${' ' * leftPadding}$columnText${' ' * rightPadding}';
break;
case ColumnAlign.right:
formattedColumn = columnText.padLeft(colWidth);
break;
}
line += formattedColumn;
}
_bytes.addAll(utf8.encode(line));
_bytes.add(0x0A);
if (lineSpacing > 0 && lineIndex < maxLines - 1) {
for (int i = 0; i < lineSpacing; i++) {
_bytes.add(0x0A);
}
}
}
return this;
}