planScrollables function
Pure planner — see ScrollPlan.
Implementation
ScrollPlan planScrollables(UiSnapshot snap) {
final all = snap.nodes
.where((n) => n.scrollable && n.visible)
.toList(growable: false);
if (all.isEmpty) return const ScrollPlan(vertical: [], horizontal: []);
var topLayer = 0;
for (final n in all) {
if (n.layer > topLayer) topLayer = n.layer;
}
final onTop = all.where((n) => n.layer == topLayer);
final vertical = <UiNode>[];
final horizontal = <UiNode>[];
final vpH = snap.viewportSize.height;
for (final n in onTop) {
if (!scrollsHorizontally(n)) {
vertical.add(n);
continue;
}
// Degenerate viewport ⇒ the strip test is unanswerable; skipping it beats
// filtering every candidate to nothing.
if (vpH > 0 && n.bounds.height > vpH * kMaxCarouselHeightFraction) {
continue; // a pager
}
horizontal.add(n);
}
double area(UiNode n) => n.bounds.width * n.bounds.height;
vertical.sort((a, b) => area(b).compareTo(area(a)));
horizontal.sort((a, b) {
final dy = a.bounds.top.compareTo(b.bounds.top);
return dy != 0 ? dy : a.bounds.left.compareTo(b.bounds.left);
});
return ScrollPlan(vertical: vertical, horizontal: horizontal);
}