List _buildColumns()

in lib/studies/shrine/supplemental/asymmetric_view.dart [31:115]


  List<SizedBox> _buildColumns(
    BuildContext context,
    BoxConstraints constraints,
  ) {
    if (products == null || products.isEmpty) {
      return const [];
    }

    // Decide whether the page size and text size allow 2-column products.

    final cardHeight = (constraints.biggest.height -
            _topPadding -
            _bottomPadding -
            TwoProductCardColumn.spacerHeight) /
        2;

    final imageWidth = _cardToScreenWidthRatio * constraints.biggest.width -
        TwoProductCardColumn.horizontalPadding;

    final imageHeight = cardHeight -
        MobileProductCard.defaultTextBoxHeight *
            GalleryOptions.of(context).textScaleFactor(context);

    final shouldUseAlternatingLayout =
        imageHeight > 0 && imageWidth / imageHeight < 49 / 33;

    if (shouldUseAlternatingLayout) {
      // Alternating layout: a layout of alternating 2-product
      // and 1-product columns.
      //
      // This will return a list of columns. It will oscillate between the two
      // kinds of columns. Even cases of the index (0, 2, 4, etc) will be
      // TwoProductCardColumn and the odd cases will be OneProductCardColumn.
      //
      // Each pair of columns will advance us 3 products forward (2 + 1). That's
      // some kinda awkward math so we use _evenCasesIndex and _oddCasesIndex as
      // helpers for creating the index of the product list that will correspond
      // to the index of the list of columns.

      return List<SizedBox>.generate(_listItemCount(products.length), (index) {
        var width = _cardToScreenWidthRatio * MediaQuery.of(context).size.width;
        Widget column;
        if (index % 2 == 0) {
          /// Even cases
          final bottom = _evenCasesIndex(index);
          column = TwoProductCardColumn(
            bottom: products[bottom],
            top:
                products.length - 1 >= bottom + 1 ? products[bottom + 1] : null,
            imageAspectRatio: imageWidth / imageHeight,
          );
          width += 32;
        } else {
          /// Odd cases
          column = OneProductCardColumn(
            product: products[_oddCasesIndex(index)],
            reverse: true,
          );
        }
        return SizedBox(
          width: width,
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: column,
          ),
        );
      }).toList();
    } else {
      // Alternating layout: a layout of 1-product columns.

      return [
        for (final product in products)
          SizedBox(
            width: _cardToScreenWidthRatio * MediaQuery.of(context).size.width,
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: OneProductCardColumn(
                product: product,
                reverse: false,
              ),
            ),
          )
      ];
    }
  }