layout method

  1. @override
PwBox layout(
  1. Context context,
  2. BoxConstraints constraints
)
override

layout API.

Implementation

@override
PwBox layout(Context context, BoxConstraints constraints) {
  final double maxW = constraints.hasBoundedWidth ? constraints.maxWidth : 400;
  final List<List<(PwBox, double)>> runs = <List<(PwBox, double)>>[];
  var run = <(PwBox, double)>[];
  var x = 0.0;
  var rowH = 0.0;
  void pushRun() {
    if (run.isEmpty) {
      return;
    }
    runs.add(run);
    run = <(PwBox, double)>[];
    x = 0;
    rowH = 0;
  }

  for (final Widget child in children) {
    final PwBox box = child.layout(
      context,
      BoxConstraints(maxWidth: maxW, maxHeight: constraints.maxHeight),
    );
    if (x > 0 && x + box.size.width > maxW) {
      pushRun();
    }
    run.add((box, x));
    x += box.size.width + spacing;
    if (box.size.height > rowH) {
      rowH = box.size.height;
    }
  }
  pushRun();

  final List<(PwBox, PwOffset)> placed = <(PwBox, PwOffset)>[];
  var y = 0.0;
  var maxUsedW = 0.0;
  for (int r = 0; r < runs.length; r++) {
    final List<(PwBox, double)> line = runs[r];
    var lineW = 0.0;
    var lineH = 0.0;
    for (final (PwBox box, double _) in line) {
      lineW += box.size.width;
      if (box.size.height > lineH) {
        lineH = box.size.height;
      }
    }
    if (line.length > 1) {
      lineW += spacing * (line.length - 1);
    }
    final double slack = (maxW - lineW).clamp(0, double.infinity);
    final double shift = switch (alignment) {
      WrapAlignment.end => slack,
      WrapAlignment.center => slack / 2,
      WrapAlignment.start => 0,
    };
    for (final (PwBox box, double localX) in line) {
      placed.add((box, PwOffset(localX + shift, y)));
    }
    if (lineW + shift > maxUsedW) {
      maxUsedW = lineW + shift;
    }
    y += lineH;
    if (r < runs.length - 1) {
      y += runSpacing;
    }
  }
  return GroupBox(
    constraints.constrain(PwSize(maxUsedW.clamp(0, maxW), y)),
    placed,
  );
}