in lib/studies/shrine/supplemental/balanced_layout.dart [75:155]
void _iterateUntilBalanced(
List<Set<_TaggedHeightData>> columnObjects,
List<double> columnHeights,
) {
var failedMoves = 0;
final columnCount = columnObjects.length;
// No need to rearrange a 1-column layout.
if (columnCount == 1) {
return;
}
while (true) {
// Loop through all possible 2-combinations of columns.
for (var source = 0; source < columnCount; ++source) {
for (var target = source + 1; target < columnCount; ++target) {
// Tries to find an object A from source column
// and an object B from target column, such that switching them
// causes the height of the two columns to be closer.
// A or B can be empty; in this case, moving an object from one
// column to the other is the best choice.
var success = false;
final bestHeight = (columnHeights[source] + columnHeights[target]) / 2;
final scoreLimit = (columnHeights[source] - bestHeight).abs();
final sourceObjects = toListAndAddEmpty(columnObjects[source]);
final targetObjects = toListAndAddEmpty(columnObjects[target]);
_TaggedHeightData bestA, bestB;
double bestScore;
for (final a in sourceObjects) {
for (final b in targetObjects) {
if (a.index == _emptyElement && b.index == _emptyElement) {
continue;
} else {
final score =
(columnHeights[source] - a.height + b.height - bestHeight)
.abs();
if (score < scoreLimit - _deviationImprovementThreshold) {
success = true;
if (bestScore == null || score < bestScore) {
bestScore = score;
bestA = a;
bestB = b;
}
}
}
}
}
if (!success) {
++failedMoves;
} else {
failedMoves = 0;
// Switch A and B.
if (bestA.index != _emptyElement) {
columnObjects[source].remove(bestA);
columnObjects[target].add(bestA);
}
if (bestB.index != _emptyElement) {
columnObjects[target].remove(bestB);
columnObjects[source].add(bestB);
}
columnHeights[source] += bestB.height - bestA.height;
columnHeights[target] += bestA.height - bestB.height;
}
// If no two columns' heights can be made closer by switching
// elements, the layout is sufficiently balanced.
if (failedMoves >= columnCount * (columnCount - 1) ~/ 2) {
return;
}
}
}
}
}