Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 32 additions & 38 deletions lib/src/resizable_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -369,53 +369,47 @@ class ResizableController with ChangeNotifier {
required double delta,
required List<double> sizes,
}) {
final indices = List.generate(_children.length, (i) => i);
final changeableIndices = _getChangeableIndices(delta < 0 ? -1 : 1, sizes);

if (changeableIndices.isEmpty) {
return List.filled(sizes.length, 0.0);
}
final changes = List<double>.filled(sizes.length, 0.0);
final workingSizes = List<double>.of(sizes);
var remainingDelta = delta;

final changePerItem = delta / changeableIndices.length;
// Iterative water-filling: each pass distributes `remainingDelta` equally
// amongst changeable children, capping each at its allowable change. A
// child capped below the equal share is saturated and drops out of the
// next pass, so the loop terminates in at most 2n iterations (the
// expand-priority set, then the fallback set).
while (remainingDelta != 0.0) {
final changeableIndices = _getChangeableIndices(
remainingDelta < 0 ? -1 : 1,
workingSizes,
);

final maximums = indices.map((i) {
if (changeableIndices.contains(i)) {
return _getAllowableChange(delta: delta, index: i, sizes: sizes);
if (changeableIndices.isEmpty) {
break;
}

return 0.0;
}).toList();

final changes = indices.map((index) {
if (!changeableIndices.contains(index)) {
return 0.0;
}
final changePerItem = remainingDelta / changeableIndices.length;
var allocated = 0.0;

final max = maximums[index];
for (final index in changeableIndices) {
final allowable = _getAllowableChange(
delta: remainingDelta,
index: index,
sizes: workingSizes,
);
final change =
allowable.abs() < changePerItem.abs() ? allowable : changePerItem;

if (max.abs() < changePerItem.abs()) {
return max;
changes[index] += change;
workingSizes[index] += change;
allocated += change;
}

return changePerItem;
}).toList();

final changesSum = changes.sum();
final remainingChange = delta - changesSum;

if (remainingChange.abs() > 0) {
final adjustedSizes = indices.map(
(index) => sizes[index] + changes[index],
);

final redistributed = _distributeAvailableSpaceDelta(
delta: remainingChange,
sizes: adjustedSizes.toList(),
);

for (var i = 0; i < changes.length; i++) {
changes[i] += redistributed[i];
if (allocated == 0.0) {
break;
}

remainingDelta -= allocated;
}

return changes;
Expand Down
Loading