77 lines
2.4 KiB
Dart
77 lines
2.4 KiB
Dart
/// Grid shape and per-cell channel assignments.
|
|
///
|
|
/// Cell numbering is 1..N in row-major order. A cell may be unassigned
|
|
/// (channel = null), in which case it renders as empty.
|
|
class GridConfig {
|
|
GridConfig({
|
|
required this.rows,
|
|
required this.cols,
|
|
List<int?>? cellChannels,
|
|
}) : cellChannels =
|
|
cellChannels ?? List<int?>.filled(rows * cols, null);
|
|
|
|
int rows;
|
|
int cols;
|
|
/// Length = rows * cols. Element is the proto channel index (1..16) or null.
|
|
List<int?> cellChannels;
|
|
|
|
int get cellCount => rows * cols;
|
|
|
|
/// 1-based cell number → channel, or null if unassigned.
|
|
int? channelForCell(int cellNumber) {
|
|
if (cellNumber < 1 || cellNumber > cellCount) return null;
|
|
return cellChannels[cellNumber - 1];
|
|
}
|
|
|
|
/// Set the channel assigned to a 1-based cell. If [channel] is already
|
|
/// assigned to a different cell, that cell is cleared (auto-swap).
|
|
void assign(int cellNumber, int? channel) {
|
|
if (cellNumber < 1 || cellNumber > cellCount) return;
|
|
if (channel != null) {
|
|
for (var i = 0; i < cellChannels.length; i++) {
|
|
if (cellChannels[i] == channel) cellChannels[i] = null;
|
|
}
|
|
}
|
|
cellChannels[cellNumber - 1] = channel;
|
|
}
|
|
|
|
/// Resize the grid. Channel assignments to cells beyond the new range
|
|
/// are dropped.
|
|
void resize(int newRows, int newCols) {
|
|
final newCells = List<int?>.filled(newRows * newCols, null);
|
|
final keep = newCells.length < cellChannels.length
|
|
? newCells.length
|
|
: cellChannels.length;
|
|
for (var i = 0; i < keep; i++) {
|
|
newCells[i] = cellChannels[i];
|
|
}
|
|
rows = newRows;
|
|
cols = newCols;
|
|
cellChannels = newCells;
|
|
}
|
|
|
|
/// Auto-assign: fill cells with the lowest-numbered enabled channels.
|
|
void autoAssign(List<int> enabledChannels) {
|
|
cellChannels = List<int?>.filled(cellCount, null);
|
|
final n = enabledChannels.length < cellCount
|
|
? enabledChannels.length
|
|
: cellCount;
|
|
for (var i = 0; i < n; i++) {
|
|
cellChannels[i] = enabledChannels[i];
|
|
}
|
|
}
|
|
|
|
Map<String, dynamic> toJson() => {
|
|
'rows': rows,
|
|
'cols': cols,
|
|
'cellChannels': cellChannels,
|
|
};
|
|
|
|
static GridConfig fromJson(Map<String, dynamic> j) => GridConfig(
|
|
rows: j['rows'] as int,
|
|
cols: j['cols'] as int,
|
|
cellChannels: (j['cellChannels'] as List)
|
|
.map((e) => e as int?)
|
|
.toList(),
|
|
);
|
|
} |