From 5a5e8d6728352616dd99a6debb13b1100f4f4547 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Fri, 25 Mar 2022 17:46:24 +0900 Subject: [PATCH] grid padding --- lib/widgets/collection/collection_grid.dart | 12 +++++-- .../collection/grid/section_layout.dart | 2 ++ lib/widgets/common/grid/scaling.dart | 36 ++++++++++++------- lib/widgets/common/grid/section_layout.dart | 29 +++++++++------ .../common/tile_extent_controller.dart | 11 +++--- .../filter_grids/common/filter_grid_page.dart | 12 +++++-- .../filter_grids/common/section_layout.dart | 2 ++ 7 files changed, 69 insertions(+), 35 deletions(-) diff --git a/lib/widgets/collection/collection_grid.dart b/lib/widgets/collection/collection_grid.dart index 629b52c27..64cd0cb8e 100644 --- a/lib/widgets/collection/collection_grid.dart +++ b/lib/widgets/collection/collection_grid.dart @@ -70,6 +70,7 @@ class _CollectionGridState extends State { extentMin: CollectionGrid.extentMin, extentMax: CollectionGrid.extentMax, spacing: CollectionGrid.spacing, + horizontalPadding: 2, ); return TileExtentControllerProvider( controller: _tileExtentController!, @@ -90,12 +91,13 @@ class _CollectionGridContent extends StatelessWidget { final sectionedListLayoutProvider = ValueListenableBuilder( valueListenable: context.select>((controller) => controller.extentNotifier), builder: (context, thumbnailExtent, child) { - return Selector>( - selector: (context, c) => Tuple3(c.viewportSize.width, c.columnCount, c.spacing), + return Selector>( + selector: (context, c) => Tuple4(c.viewportSize.width, c.columnCount, c.spacing, c.horizontalPadding), builder: (context, c, child) { final scrollableWidth = c.item1; final columnCount = c.item2; final tileSpacing = c.item3; + final horizontalPadding = c.item4; return GridTheme( extent: thumbnailExtent, child: EntryListDetailsTheme( @@ -117,6 +119,7 @@ class _CollectionGridContent extends StatelessWidget { tileLayout: tileLayout, columnCount: columnCount, spacing: tileSpacing, + horizontalPadding: horizontalPadding, tileExtent: thumbnailExtent, tileBuilder: (entry) => AnimatedBuilder( animation: favourites, @@ -242,7 +245,9 @@ class _CollectionScaler extends StatelessWidget { @override Widget build(BuildContext context) { - final tileSpacing = context.select((controller) => controller.spacing); + final metrics = context.select>((v) => Tuple2(v.spacing, v.horizontalPadding)); + final tileSpacing = metrics.item1; + final horizontalPadding = metrics.item2; return GridScaleGestureDetector( scrollableKey: scrollableKey, tileLayout: tileLayout, @@ -253,6 +258,7 @@ class _CollectionScaler extends StatelessWidget { tileCenter: center, tileSize: tileSize, spacing: tileSpacing, + horizontalPadding: horizontalPadding, borderWidth: DecoratedThumbnail.borderWidth, borderRadius: Radius.zero, color: DecoratedThumbnail.borderColor, diff --git a/lib/widgets/collection/grid/section_layout.dart b/lib/widgets/collection/grid/section_layout.dart index 528dce550..56f055c43 100644 --- a/lib/widgets/collection/grid/section_layout.dart +++ b/lib/widgets/collection/grid/section_layout.dart @@ -16,6 +16,7 @@ class SectionedEntryListLayoutProvider extends SectionedListLayoutProvider extends State _ScaleOverlay( builder: (scaledTileSize) { late final double themeExtent; - switch (widget.tileLayout) { + switch (tileLayout) { case TileLayout.grid: themeExtent = scaledTileSize.width; break; @@ -136,9 +143,10 @@ class _GridScaleGestureDetectorState extends State scaledSizeNotifier; final Widget Function(Offset center, Size tileSize, Widget child) gridBuilder; @@ -229,7 +237,8 @@ class _ScaleOverlay extends StatefulWidget { required this.builder, required this.tileLayout, required this.center, - required this.viewportWidth, + required this.xMin, + required this.xMax, required this.scaledSizeNotifier, required this.gridBuilder, }) : super(key: key); @@ -243,7 +252,9 @@ class _ScaleOverlayState extends State<_ScaleOverlay> { Offset get center => widget.center; - double get gridWidth => widget.viewportWidth; + double get xMin => widget.xMin; + + double get xMax => widget.xMax; // `Color(0x00FFFFFF)` is different from `Color(0x00000000)` (or `Colors.transparent`) // when used in gradients or lerping to it @@ -269,8 +280,6 @@ class _ScaleOverlayState extends State<_ScaleOverlay> { final width = scaledSize.width; final height = scaledSize.height; // keep scaled thumbnail within the screen - final xMin = context.select((mq) => mq.padding.left); - final xMax = xMin + gridWidth; var dx = .0; if (center.dx - width / 2 < xMin) { dx = xMin - (center.dx - width / 2); @@ -309,7 +318,7 @@ class _ScaleOverlayState extends State<_ScaleOverlay> { gradientCenter = center; break; case TileLayout.list: - gradientCenter = Offset(context.isRtl ? gridWidth : 0, center.dy); + gradientCenter = Offset(context.isRtl ? xMax : xMin, center.dy); break; } @@ -351,7 +360,7 @@ class GridPainter extends CustomPainter { final TileLayout tileLayout; final Offset tileCenter; final Size tileSize; - final double spacing, borderWidth; + final double spacing, horizontalPadding, borderWidth; final Radius borderRadius; final Color color; final TextDirection textDirection; @@ -361,6 +370,7 @@ class GridPainter extends CustomPainter { required this.tileCenter, required this.tileSize, required this.spacing, + required this.horizontalPadding, required this.borderWidth, required this.borderRadius, required this.color, @@ -394,7 +404,7 @@ class GridPainter extends CustomPainter { case TileLayout.list: chipSize = Size.square(tileSize.shortestSide); final chipCenterToEdge = chipSize.width / 2; - chipCenter = Offset(textDirection == TextDirection.rtl ? size.width - chipCenterToEdge : chipCenterToEdge, tileCenter.dy); + chipCenter = Offset(textDirection == TextDirection.rtl ? size.width - (chipCenterToEdge + horizontalPadding) : chipCenterToEdge + horizontalPadding, tileCenter.dy); deltaColumn = 0; strokeShader = ui.Gradient.linear( tileCenter - Offset(0, chipSize.shortestSide * 3), diff --git a/lib/widgets/common/grid/section_layout.dart b/lib/widgets/common/grid/section_layout.dart index c30ac4c7d..42f2dd021 100644 --- a/lib/widgets/common/grid/section_layout.dart +++ b/lib/widgets/common/grid/section_layout.dart @@ -15,7 +15,7 @@ abstract class SectionedListLayoutProvider extends StatelessWidget { final double scrollableWidth; final TileLayout tileLayout; final int columnCount; - final double spacing, tileWidth, tileHeight; + final double spacing, horizontalPadding, tileWidth, tileHeight; final Widget Function(T item) tileBuilder; final Duration tileAnimationDelay; final Widget child; @@ -26,6 +26,7 @@ abstract class SectionedListLayoutProvider extends StatelessWidget { required this.tileLayout, required int columnCount, required this.spacing, + required this.horizontalPadding, required double tileWidth, required this.tileHeight, required this.tileBuilder, @@ -33,7 +34,7 @@ abstract class SectionedListLayoutProvider extends StatelessWidget { required this.child, }) : assert(scrollableWidth != 0), columnCount = tileLayout == TileLayout.list ? 1 : columnCount, - tileWidth = tileLayout == TileLayout.list ? scrollableWidth : tileWidth, + tileWidth = tileLayout == TileLayout.list ? scrollableWidth - (horizontalPadding * 2) : tileWidth, super(key: key); @override @@ -98,6 +99,7 @@ abstract class SectionedListLayoutProvider extends StatelessWidget { tileWidth: tileWidth, tileHeight: tileHeight, spacing: spacing, + horizontalPadding: horizontalPadding, sectionLayouts: sectionLayouts, ); } @@ -129,12 +131,15 @@ abstract class SectionedListLayoutProvider extends StatelessWidget { ); children.add(animate ? _buildAnimation(context, itemGridIndex, item) : item); } - return _GridRow( - width: tileWidth, - height: tileHeight, - spacing: spacing, - textDirection: Directionality.of(context), - children: children, + return Padding( + padding: EdgeInsets.symmetric(horizontal: horizontalPadding), + child: _GridRow( + width: tileWidth, + height: tileHeight, + spacing: spacing, + textDirection: Directionality.of(context), + children: children, + ), ); } @@ -168,6 +173,7 @@ abstract class SectionedListLayoutProvider extends StatelessWidget { properties.add(DoubleProperty('scrollableWidth', scrollableWidth)); properties.add(IntProperty('columnCount', columnCount)); properties.add(DoubleProperty('spacing', spacing)); + properties.add(DoubleProperty('horizontalPadding', horizontalPadding)); properties.add(DoubleProperty('tileWidth', tileWidth)); properties.add(DoubleProperty('tileHeight', tileHeight)); properties.add(DiagnosticsProperty('showHeaders', showHeaders)); @@ -178,7 +184,7 @@ class SectionedListLayout { final Map> sections; final bool showHeaders; final int columnCount; - final double tileWidth, tileHeight, spacing; + final double tileWidth, tileHeight, spacing, horizontalPadding; final List sectionLayouts; const SectionedListLayout({ @@ -188,6 +194,7 @@ class SectionedListLayout { required this.tileWidth, required this.tileHeight, required this.spacing, + required this.horizontalPadding, required this.sectionLayouts, }); @@ -205,7 +212,7 @@ class SectionedListLayout { final row = (sectionItemIndex / columnCount).floor(); final listIndex = sectionLayout.firstIndex + 1 + row; - final left = tileWidth * column + spacing * (column - 1); + final left = horizontalPadding + tileWidth * column + spacing * (column - 1); final top = sectionLayout.indexToLayoutOffset(listIndex); return Rect.fromLTWH(left, top, tileWidth, tileHeight); } @@ -225,7 +232,7 @@ class SectionedListLayout { if (dy < 0) return null; final row = dy ~/ (tileHeight + spacing); - final column = position.dx ~/ (tileWidth + spacing); + final column = max(0, position.dx - horizontalPadding) ~/ (tileWidth + spacing); final index = row * columnCount + column; if (index >= section.length) return null; diff --git a/lib/widgets/common/tile_extent_controller.dart b/lib/widgets/common/tile_extent_controller.dart index 5a055a2ed..99178e549 100644 --- a/lib/widgets/common/tile_extent_controller.dart +++ b/lib/widgets/common/tile_extent_controller.dart @@ -7,7 +7,7 @@ import 'package:flutter/widgets.dart'; class TileExtentController { final String settingsRouteKey; final int columnCountMin, columnCountDefault; - final double spacing, extentMin, extentMax; + final double extentMin, extentMax, spacing, horizontalPadding; final ValueNotifier extentNotifier = ValueNotifier(0); late double userPreferredExtent; @@ -22,6 +22,7 @@ class TileExtentController { required this.extentMin, required this.extentMax, required this.spacing, + required this.horizontalPadding, }) { userPreferredExtent = settings.getTileExtent(settingsRouteKey); settings.addListener(_onSettingsChanged); @@ -68,11 +69,11 @@ class TileExtentController { return newExtent; } - double _extentMax() => min(extentMax, (viewportSize.shortestSide - spacing * (columnCountMin - 1)) / columnCountMin); + double _extentMax() => min(extentMax, (viewportSize.shortestSide - (horizontalPadding * 2) - spacing * (columnCountMin - 1)) / columnCountMin); - double _columnCountForExtent(double extent) => (viewportSize.width + spacing) / (extent + spacing); + double _columnCountForExtent(double extent) => (viewportSize.width - (horizontalPadding * 2) + spacing) / (extent + spacing); - double _extentForColumnCount(int columnCount) => (viewportSize.width - spacing * (columnCount - 1)) / columnCount; + double _extentForColumnCount(int columnCount) => (viewportSize.width - (horizontalPadding * 2) - spacing * (columnCount - 1)) / columnCount; int _effectiveColumnCountMin() => _columnCountForExtent(_extentMax()).ceil(); @@ -94,7 +95,7 @@ class TileExtentController { Duration getTileAnimationDelay(Duration pageTarget) { final extent = extentNotifier.value; - final columnCount = ((viewportSize.width + spacing) / (extent + spacing)).round(); + final columnCount = ((viewportSize.width - (horizontalPadding * 2) + spacing) / (extent + spacing)).round(); final rowCount = (viewportSize.height + spacing) ~/ (extent + spacing); return pageTarget ~/ (columnCount + rowCount) * timeDilation; } diff --git a/lib/widgets/filter_grids/common/filter_grid_page.dart b/lib/widgets/filter_grids/common/filter_grid_page.dart index fcf4526b7..4710d47f5 100644 --- a/lib/widgets/filter_grids/common/filter_grid_page.dart +++ b/lib/widgets/filter_grids/common/filter_grid_page.dart @@ -164,6 +164,7 @@ class _FilterGridState extends State> extentMin: 60, extentMax: 300, spacing: 8, + horizontalPadding: 2, ); return TileExtentControllerProvider( controller: _tileExtentController!, @@ -237,12 +238,13 @@ class _FilterGridContent extends StatelessWidget { final sectionedListLayoutProvider = ValueListenableBuilder( valueListenable: context.select>((controller) => controller.extentNotifier), builder: (context, thumbnailExtent, child) { - return Selector>( - selector: (context, c) => Tuple3(c.viewportSize.width, c.columnCount, c.spacing), + return Selector>( + selector: (context, c) => Tuple4(c.viewportSize.width, c.columnCount, c.spacing, c.horizontalPadding), builder: (context, c, child) { final scrollableWidth = c.item1; final columnCount = c.item2; final tileSpacing = c.item3; + final horizontalPadding = c.item4; // do not listen for animation delay change final target = context.read().staggeredAnimationPageTarget; final tileAnimationDelay = context.read().getTileAnimationDelay(target); @@ -265,6 +267,7 @@ class _FilterGridContent extends StatelessWidget { scrollableWidth: scrollableWidth, columnCount: columnCount, spacing: tileSpacing, + horizontalPadding: horizontalPadding, tileWidth: thumbnailExtent, tileHeight: tileHeight, tileBuilder: (gridItem) { @@ -430,8 +433,10 @@ class _FilterScaler extends StatelessWidget { @override Widget build(BuildContext context) { - final tileSpacing = context.select((controller) => controller.spacing); final textScaleFactor = context.select((mq) => mq.textScaleFactor); + final metrics = context.select>((v) => Tuple2(v.spacing, v.horizontalPadding)); + final tileSpacing = metrics.item1; + final horizontalPadding = metrics.item2; return GridScaleGestureDetector>( scrollableKey: scrollableKey, tileLayout: tileLayout, @@ -442,6 +447,7 @@ class _FilterScaler extends StatelessWidget { tileCenter: center, tileSize: tileSize, spacing: tileSpacing, + horizontalPadding: horizontalPadding, borderWidth: AvesFilterChip.outlineWidth, borderRadius: CoveredFilterChip.radius(tileSize.shortestSide), color: Colors.grey.shade700, diff --git a/lib/widgets/filter_grids/common/section_layout.dart b/lib/widgets/filter_grids/common/section_layout.dart index 7055bac26..3e12913b5 100644 --- a/lib/widgets/filter_grids/common/section_layout.dart +++ b/lib/widgets/filter_grids/common/section_layout.dart @@ -15,6 +15,7 @@ class SectionedFilterListLayoutProvider extends Sect required TileLayout tileLayout, required int columnCount, required double spacing, + required double horizontalPadding, required double tileWidth, required double tileHeight, required Widget Function(FilterGridItem gridItem) tileBuilder, @@ -26,6 +27,7 @@ class SectionedFilterListLayoutProvider extends Sect tileLayout: tileLayout, columnCount: columnCount, spacing: spacing, + horizontalPadding: horizontalPadding, tileWidth: tileWidth, tileHeight: tileHeight, tileBuilder: tileBuilder,