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,
),
),
)
];
}
}