buildTreeTableRows<T> function
List<TreeTableRow<T> >
buildTreeTableRows<T>({
- required List<
TreeTableNode< roots,T> > - required List<
DataTableColumn> columns, - Set<
Object> expandedKeys = const <Object>{}, - String? treeColumnId,
- TreeTableCellBuilder<
T> ? cellBuilder, - TreeTableFilterDescriptor? filter,
- TreeTableSearchIndex<
T> ? searchIndex,
Builds visible rows for a TreeTable.
Without a filter, only descendants of expanded nodes are returned. With a filter, matching rows and their ancestors are returned regardless of current expansion so collapsed matches remain discoverable.
Implementation
List<TreeTableRow<T>> buildTreeTableRows<T>({
required List<TreeTableNode<T>> roots,
required List<DataTableColumn> columns,
Set<Object> expandedKeys = const <Object>{},
String? treeColumnId,
TreeTableCellBuilder<T>? cellBuilder,
TreeTableFilterDescriptor? filter,
TreeTableSearchIndex<T>? searchIndex,
}) {
final effectiveTreeColumnId = treeColumnId ?? _firstColumnId(columns);
final effectiveFilter = filter ?? const TreeTableFilterDescriptor();
if (effectiveFilter.isEmpty) {
final rows = <TreeTableRow<T>>[];
void visit(
TreeTableNode<T> node,
int depth,
String path,
Object? parentKey,
) {
rows.add(
TreeTableRow<T>(
node: node,
depth: depth,
path: path,
parentKey: parentKey,
),
);
if (!expandedKeys.contains(node.key)) return;
for (var i = 0; i < node.children.length; i++) {
visit(node.children[i], depth + 1, '$path.$i', node.key);
}
}
for (var i = 0; i < roots.length; i++) {
visit(roots[i], 0, '$i', null);
}
return List<TreeTableRow<T>>.unmodifiable(rows);
}
if (searchIndex != null) {
return searchIndex.filter(effectiveFilter);
}
final query = effectiveFilter.caseSensitive
? _sanitizeTreeTableText(effectiveFilter.query.trim())
: _sanitizeTreeTableText(effectiveFilter.query.trim()).toLowerCase();
final rows = <TreeTableRow<T>>[];
bool visitFiltered(
TreeTableNode<T> node,
int depth,
String path,
Object? parentKey,
) {
final row = TreeTableRow<T>(
node: node,
depth: depth,
path: path,
parentKey: parentKey,
);
final childRows = <TreeTableRow<T>>[];
var childMatched = false;
for (var i = 0; i < node.children.length; i++) {
final before = rows.length;
if (visitFiltered(node.children[i], depth + 1, '$path.$i', node.key)) {
childMatched = true;
childRows.addAll(rows.sublist(before));
}
rows.removeRange(before, rows.length);
}
final matched = _rowMatchesFilter(
row,
columns,
effectiveTreeColumnId,
cellBuilder,
effectiveFilter,
query,
);
if (!matched && !childMatched) return false;
rows.add(row);
rows.addAll(childRows);
return true;
}
for (var i = 0; i < roots.length; i++) {
visitFiltered(roots[i], 0, '$i', null);
}
return List<TreeTableRow<T>>.unmodifiable(rows);
}