diff --git a/packages/two_dimensional_scrollables/CHANGELOG.md b/packages/two_dimensional_scrollables/CHANGELOG.md index e2a6474c31e2..6b04d1bf63c3 100644 --- a/packages/two_dimensional_scrollables/CHANGELOG.md +++ b/packages/two_dimensional_scrollables/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.6 + +* Fixes an error in TableSpanDecoration when one or both axes are reversed. + ## 0.0.5+2 * Fixes must_call_super lint warning from pending framework change. diff --git a/packages/two_dimensional_scrollables/lib/src/table_view/table.dart b/packages/two_dimensional_scrollables/lib/src/table_view/table.dart index a2452c71ab17..a8d9a0cc99d3 100644 --- a/packages/two_dimensional_scrollables/lib/src/table_view/table.dart +++ b/packages/two_dimensional_scrollables/lib/src/table_view/table.dart @@ -861,31 +861,41 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { )!; Rect getColumnRect(bool consumePadding) { + final ({double leading, double trailing}) offsetCorrection = + axisDirectionIsReversed(verticalAxisDirection) + ? ( + leading: leadingCell.size.height, + trailing: trailingCell.size.height, + ) + : (leading: 0.0, trailing: 0.0); + return Rect.fromPoints( parentDataOf(leadingCell).paintOffset! + offset - Offset( consumePadding ? columnSpan.padding.leading : 0.0, - rowSpan.padding.leading, + rowSpan.padding.leading - offsetCorrection.leading, ), parentDataOf(trailingCell).paintOffset! + offset + Offset(trailingCell.size.width, trailingCell.size.height) + Offset( consumePadding ? columnSpan.padding.trailing : 0.0, - rowSpan.padding.trailing, + rowSpan.padding.trailing - offsetCorrection.trailing, ), ); } if (columnSpan.backgroundDecoration != null) { final Rect rect = getColumnRect( - columnSpan.backgroundDecoration!.consumeSpanPadding); + columnSpan.backgroundDecoration!.consumeSpanPadding, + ); backgroundColumns[rect] = columnSpan.backgroundDecoration!; } if (columnSpan.foregroundDecoration != null) { final Rect rect = getColumnRect( - columnSpan.foregroundDecoration!.consumeSpanPadding); + columnSpan.foregroundDecoration!.consumeSpanPadding, + ); foregroundColumns[rect] = columnSpan.foregroundDecoration!; } } @@ -910,18 +920,25 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { )!; Rect getRowRect(bool consumePadding) { + final ({double leading, double trailing}) offsetCorrection = + axisDirectionIsReversed(horizontalAxisDirection) + ? ( + leading: leadingCell.size.width, + trailing: trailingCell.size.width, + ) + : (leading: 0.0, trailing: 0.0); return Rect.fromPoints( parentDataOf(leadingCell).paintOffset! + offset - Offset( - columnSpan.padding.leading, + columnSpan.padding.leading - offsetCorrection.leading, consumePadding ? rowSpan.padding.leading : 0.0, ), parentDataOf(trailingCell).paintOffset! + offset + Offset(trailingCell.size.width, trailingCell.size.height) + Offset( - columnSpan.padding.leading, + columnSpan.padding.leading - offsetCorrection.trailing, consumePadding ? rowSpan.padding.trailing : 0.0, ), ); diff --git a/packages/two_dimensional_scrollables/pubspec.yaml b/packages/two_dimensional_scrollables/pubspec.yaml index d8a9f9615282..5d1ede3d73f5 100644 --- a/packages/two_dimensional_scrollables/pubspec.yaml +++ b/packages/two_dimensional_scrollables/pubspec.yaml @@ -1,6 +1,6 @@ name: two_dimensional_scrollables description: Widgets that scroll using the two dimensional scrolling foundation. -version: 0.0.5+2 +version: 0.0.6 repository: https://github.com/flutter/packages/tree/main/packages/two_dimensional_scrollables issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+two_dimensional_scrollables%22+ diff --git a/packages/two_dimensional_scrollables/test/table_view/table_span_test.dart b/packages/two_dimensional_scrollables/test/table_view/table_span_test.dart index fea0d26e9a1d..b6b0db398e26 100644 --- a/packages/two_dimensional_scrollables/test/table_view/table_span_test.dart +++ b/packages/two_dimensional_scrollables/test/table_view/table_span_test.dart @@ -177,6 +177,675 @@ void main() { expect(border.details, details); expect(border.radius, radius); }); + + group('Decoration rects account for reversed axes', () { + late ScrollController verticalController; + late ScrollController horizontalController; + + setUp(() { + verticalController = ScrollController(); + horizontalController = ScrollController(); + }); + + tearDown(() { + verticalController.dispose(); + horizontalController.dispose(); + }); + + Widget buildCell(BuildContext context, TableVicinity vicinity) { + return const SizedBox.shrink(); + } + + TableSpan buildSpan(bool isColumn) { + return TableSpan( + extent: const FixedTableSpanExtent(100), + foregroundDecoration: TableSpanDecoration( + color: isColumn ? const Color(0xFFE1BEE7) : const Color(0xFFBBDEFB), + ), + ); + } + + testWidgets('Vertical main axis, vertical reversed', + (WidgetTester tester) async { + final TableView table = TableView.builder( + verticalDetails: ScrollableDetails.vertical( + controller: verticalController, + reverse: true, + ), + horizontalDetails: ScrollableDetails.horizontal( + controller: horizontalController, + ), + rowCount: 10, + columnCount: 10, + rowBuilder: (_) => buildSpan(false), + columnBuilder: (_) => buildSpan(true), + cellBuilder: buildCell, + ); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: table, + )); + await tester.pumpAndSettle(); + + expect( + find.byType(TableViewport), + paints + // Rows first, bottom to top for reversed axis + ..rect( + rect: const Rect.fromLTRB(0.0, 500.0, 1000.0, 600.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 400.0, 1000.0, 500.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 300.0, 1000.0, 400.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 200.0, 1000.0, 300.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 100.0, 1000.0, 200.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 0.0, 1000.0, 100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, -100.0, 1000.0, 0.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, -200.0, 1000.0, -100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, -300.0, 1000.0, -200.0), + color: const Color(0xffbbdefb), + ) + // Columns next + ..rect( + rect: const Rect.fromLTRB(0.0, -300.0, 100.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(100.0, -300.0, 200.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(200.0, -300.0, 300.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(300.0, -300.0, 400.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(400.0, -300.0, 500.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(500.0, -300.0, 600.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(600.0, -300.0, 700.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(700.0, -300.0, 800.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(800.0, -300.0, 900.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(900.0, -300.0, 1000.0, 600.0), + color: const Color(0xffe1bee7), + ), + ); + }); + + testWidgets('Vertical main axis, horizontal reversed', + (WidgetTester tester) async { + final TableView table = TableView.builder( + verticalDetails: ScrollableDetails.vertical( + controller: verticalController, + ), + horizontalDetails: ScrollableDetails.horizontal( + controller: horizontalController, + reverse: true, + ), + rowCount: 10, + columnCount: 10, + rowBuilder: (_) => buildSpan(false), + columnBuilder: (_) => buildSpan(true), + cellBuilder: buildCell, + ); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: table, + )); + await tester.pumpAndSettle(); + + expect( + find.byType(TableViewport), + paints + // Rows first + ..rect( + rect: const Rect.fromLTRB(-200.0, 0.0, 800.0, 100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 100.0, 800.0, 200.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 200.0, 800.0, 300.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 300.0, 800.0, 400.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 400.0, 800.0, 500.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 500.0, 800.0, 600.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 600.0, 800.0, 700.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 700.0, 800.0, 800.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 800.0, 800.0, 900.0), + color: const Color(0xffbbdefb), + ) + // Columns next, right to left for reversed axis + ..rect( + rect: const Rect.fromLTRB(700.0, 0.0, 800.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(600.0, 0.0, 700.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(500.0, 0.0, 600.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(400.0, 0.0, 500.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(300.0, 0.0, 400.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(200.0, 0.0, 300.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(100.0, 0.0, 200.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 0.0, 100.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(-100.0, 0.0, 0.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 0.0, -100.0, 900.0), + color: const Color(0xffe1bee7), + ), + ); + }); + + testWidgets('Vertical main axis, both reversed', + (WidgetTester tester) async { + final TableView table = TableView.builder( + verticalDetails: ScrollableDetails.vertical( + controller: verticalController, + reverse: true, + ), + horizontalDetails: ScrollableDetails.horizontal( + controller: horizontalController, + reverse: true, + ), + rowCount: 10, + columnCount: 10, + rowBuilder: (_) => buildSpan(false), + columnBuilder: (_) => buildSpan(true), + cellBuilder: buildCell, + ); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: table, + )); + await tester.pumpAndSettle(); + + expect( + find.byType(TableViewport), + paints + // Rows first, bottom to top for reversed axis + ..rect( + rect: const Rect.fromLTRB(-200.0, 500.0, 800.0, 600.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 400.0, 800.0, 500.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 300.0, 800.0, 400.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 200.0, 800.0, 300.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 100.0, 800.0, 200.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 0.0, 800.0, 100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, -100.0, 800.0, 0.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, -200.0, 800.0, -100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, -300.0, 800.0, -200.0), + color: const Color(0xffbbdefb), + ) + // Columns next, right to left for reversed axis + ..rect( + rect: const Rect.fromLTRB(700.0, -300.0, 800.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(600.0, -300.0, 700.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(500.0, -300.0, 600.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(400.0, -300.0, 500.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(300.0, -300.0, 400.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(200.0, -300.0, 300.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(100.0, -300.0, 200.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, -300.0, 100.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(-100.0, -300.0, 0.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, -300.0, -100.0, 600.0), + color: const Color(0xffe1bee7), + ), + ); + }); + + testWidgets('Horizontal main axis, vertical reversed', + (WidgetTester tester) async { + final TableView table = TableView.builder( + mainAxis: Axis.horizontal, + verticalDetails: ScrollableDetails.vertical( + controller: verticalController, + reverse: true, + ), + horizontalDetails: ScrollableDetails.horizontal( + controller: horizontalController, + ), + rowCount: 10, + columnCount: 10, + rowBuilder: (_) => buildSpan(false), + columnBuilder: (_) => buildSpan(true), + cellBuilder: buildCell, + ); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: table, + )); + await tester.pumpAndSettle(); + + expect( + find.byType(TableViewport), + paints + // Columns first + ..rect( + rect: const Rect.fromLTRB(0.0, -300.0, 100.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(100.0, -300.0, 200.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(200.0, -300.0, 300.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(300.0, -300.0, 400.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(400.0, -300.0, 500.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(500.0, -300.0, 600.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(600.0, -300.0, 700.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(700.0, -300.0, 800.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(800.0, -300.0, 900.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(900.0, -300.0, 1000.0, 600.0), + color: const Color(0xffe1bee7), + ) + // Rows next, bottom to top for reversed axis + ..rect( + rect: const Rect.fromLTRB(0.0, 500.0, 1000.0, 600.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 400.0, 1000.0, 500.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 300.0, 1000.0, 400.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 200.0, 1000.0, 300.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 100.0, 1000.0, 200.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 0.0, 1000.0, 100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, -100.0, 1000.0, 0.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, -200.0, 1000.0, -100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, -300.0, 1000.0, -200.0), + color: const Color(0xffbbdefb), + ), + ); + }); + + testWidgets('Horizontal main axis, horizontal reversed', + (WidgetTester tester) async { + final TableView table = TableView.builder( + mainAxis: Axis.horizontal, + verticalDetails: ScrollableDetails.vertical( + controller: verticalController, + ), + horizontalDetails: ScrollableDetails.horizontal( + controller: horizontalController, + reverse: true, + ), + rowCount: 10, + columnCount: 10, + rowBuilder: (_) => buildSpan(false), + columnBuilder: (_) => buildSpan(true), + cellBuilder: buildCell, + ); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: table, + )); + await tester.pumpAndSettle(); + + expect( + find.byType(TableViewport), + paints + // Columns first, right to left for reversed axis + ..rect( + rect: const Rect.fromLTRB(700.0, 0.0, 800.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(600.0, 0.0, 700.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(500.0, 0.0, 600.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(400.0, 0.0, 500.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(300.0, 0.0, 400.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(200.0, 0.0, 300.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(100.0, 0.0, 200.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, 0.0, 100.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(-100.0, 0.0, 0.0, 900.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 0.0, -100.0, 900.0), + color: const Color(0xffe1bee7), + ) + // Rows next + ..rect( + rect: const Rect.fromLTRB(-200.0, 0.0, 800.0, 100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 100.0, 800.0, 200.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 200.0, 800.0, 300.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 300.0, 800.0, 400.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 400.0, 800.0, 500.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 500.0, 800.0, 600.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 600.0, 800.0, 700.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 700.0, 800.0, 800.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 800.0, 800.0, 900.0), + color: const Color(0xffbbdefb), + ), + ); + }); + + testWidgets('Horizontal main axis, both reversed', + (WidgetTester tester) async { + final TableView table = TableView.builder( + mainAxis: Axis.horizontal, + verticalDetails: ScrollableDetails.vertical( + controller: verticalController, + reverse: true, + ), + horizontalDetails: ScrollableDetails.horizontal( + controller: horizontalController, + reverse: true, + ), + rowCount: 10, + columnCount: 10, + rowBuilder: (_) => buildSpan(false), + columnBuilder: (_) => buildSpan(true), + cellBuilder: buildCell, + ); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: table, + )); + await tester.pumpAndSettle(); + + expect( + find.byType(TableViewport), + paints + // Columns first, right to left for reversed axis + ..rect( + rect: const Rect.fromLTRB(700.0, -300.0, 800.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(600.0, -300.0, 700.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(500.0, -300.0, 600.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(400.0, -300.0, 500.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(300.0, -300.0, 400.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(200.0, -300.0, 300.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(100.0, -300.0, 200.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(0.0, -300.0, 100.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(-100.0, -300.0, 0.0, 600.0), + color: const Color(0xffe1bee7), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, -300.0, -100.0, 600.0), + color: const Color(0xffe1bee7), + ) + // Rows next, bottom to top for reversed axis + ..rect( + rect: const Rect.fromLTRB(-200.0, 500.0, 800.0, 600.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 400.0, 800.0, 500.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 300.0, 800.0, 400.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 200.0, 800.0, 300.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 100.0, 800.0, 200.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, 0.0, 800.0, 100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, -100.0, 800.0, 0.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, -200.0, 800.0, -100.0), + color: const Color(0xffbbdefb), + ) + ..rect( + rect: const Rect.fromLTRB(-200.0, -300.0, 800.0, -200.0), + color: const Color(0xffbbdefb), + ), + ); + }); + }); } class TestCanvas implements Canvas {