mosaic fixes
This commit is contained in:
parent
ebd6f1c84c
commit
5019cc2065
10 changed files with 66 additions and 36 deletions
|
@ -141,19 +141,22 @@ class _CollectionGridContent extends StatelessWidget {
|
|||
spacing: tileSpacing,
|
||||
horizontalPadding: horizontalPadding,
|
||||
tileExtent: thumbnailExtent,
|
||||
tileBuilder: (entry) => AnimatedBuilder(
|
||||
tileBuilder: (entry, tileSize) {
|
||||
final extent = tileSize.shortestSide;
|
||||
return AnimatedBuilder(
|
||||
animation: favourites,
|
||||
builder: (context, child) {
|
||||
return InteractiveTile(
|
||||
key: ValueKey(entry.id),
|
||||
collection: collection,
|
||||
entry: entry,
|
||||
thumbnailExtent: thumbnailExtent,
|
||||
thumbnailExtent: extent,
|
||||
tileLayout: tileLayout,
|
||||
isScrollingNotifier: _isScrollingNotifier,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
tileAnimationDelay: tileAnimationDelay,
|
||||
child: child!,
|
||||
);
|
||||
|
|
|
@ -11,8 +11,9 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class TransitionImage extends StatefulWidget {
|
||||
final ImageProvider image;
|
||||
final double? width, height;
|
||||
final ValueListenable<double> animation;
|
||||
final BoxFit thumbnailFit, viewerFit;
|
||||
final double? width, height;
|
||||
final bool gaplessPlayback = false;
|
||||
final Color? background;
|
||||
|
||||
|
@ -20,6 +21,8 @@ class TransitionImage extends StatefulWidget {
|
|||
super.key,
|
||||
required this.image,
|
||||
required this.animation,
|
||||
required this.thumbnailFit,
|
||||
required this.viewerFit,
|
||||
this.width,
|
||||
this.height,
|
||||
this.background,
|
||||
|
@ -157,6 +160,8 @@ class _TransitionImageState extends State<TransitionImage> {
|
|||
image: _imageInfo?.image,
|
||||
scale: _imageInfo?.scale ?? 1.0,
|
||||
t: t,
|
||||
thumbnailFit: widget.thumbnailFit,
|
||||
viewerFit: widget.viewerFit,
|
||||
background: widget.background,
|
||||
),
|
||||
),
|
||||
|
@ -166,15 +171,17 @@ class _TransitionImageState extends State<TransitionImage> {
|
|||
|
||||
class _TransitionImagePainter extends CustomPainter {
|
||||
final ui.Image? image;
|
||||
final double scale;
|
||||
final double t;
|
||||
final double scale, t;
|
||||
final Color? background;
|
||||
final BoxFit thumbnailFit, viewerFit;
|
||||
|
||||
const _TransitionImagePainter({
|
||||
required this.image,
|
||||
required this.scale,
|
||||
required this.t,
|
||||
this.background,
|
||||
required this.thumbnailFit,
|
||||
required this.viewerFit,
|
||||
required this.background,
|
||||
});
|
||||
|
||||
@override
|
||||
|
@ -190,10 +197,10 @@ class _TransitionImagePainter extends CustomPainter {
|
|||
final inputSize = Size(image!.width.toDouble(), image!.height.toDouble());
|
||||
final outputSize = rect.size;
|
||||
|
||||
final coverSizes = applyBoxFit(BoxFit.cover, inputSize / scale, size);
|
||||
final containSizes = applyBoxFit(BoxFit.contain, inputSize / scale, size);
|
||||
final sourceSize = Size.lerp(coverSizes.source, containSizes.source, t)! * scale;
|
||||
final destinationSize = Size.lerp(coverSizes.destination, containSizes.destination, t)!;
|
||||
final thumbnailSizes = applyBoxFit(thumbnailFit, inputSize / scale, size);
|
||||
final viewerSizes = applyBoxFit(viewerFit, inputSize / scale, size);
|
||||
final sourceSize = Size.lerp(thumbnailSizes.source, viewerSizes.source, t)! * scale;
|
||||
final destinationSize = Size.lerp(thumbnailSizes.destination, viewerSizes.destination, t)!;
|
||||
|
||||
final halfWidthDelta = (outputSize.width - destinationSize.width) / 2.0;
|
||||
final halfHeightDelta = (outputSize.height - destinationSize.height) / 2.0;
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:aves/model/source/enums/enums.dart';
|
|||
import 'package:aves/widgets/common/behaviour/eager_scale_gesture_recognizer.dart';
|
||||
import 'package:aves/widgets/common/grid/sections/fixed/scale_overlay.dart';
|
||||
import 'package:aves/widgets/common/grid/sections/mosaic/scale_overlay.dart';
|
||||
import 'package:aves/widgets/common/grid/sections/section_layout_builder.dart';
|
||||
import 'package:aves/widgets/common/grid/theme.dart';
|
||||
import 'package:aves/widgets/common/tile_extent_controller.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
@ -23,7 +24,7 @@ class GridScaleGestureDetector<T> extends StatefulWidget {
|
|||
final TileLayout tileLayout;
|
||||
final double Function(double width) heightForWidth;
|
||||
final Widget Function(Offset center, Size tileSize, Widget child) gridBuilder;
|
||||
final Widget Function(T item, Size tileSize) scaledItemBuilder;
|
||||
final TileBuilder<T> scaledItemBuilder;
|
||||
final MosaicItemBuilder mosaicItemBuilder;
|
||||
final Object Function(T item)? highlightItem;
|
||||
final Widget child;
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:tuple/tuple.dart';
|
|||
class FixedExtentSectionLayoutBuilder<T> extends SectionLayoutBuilder<T> {
|
||||
int _currentIndex = 0;
|
||||
double _currentOffset = 0;
|
||||
List<Size> _itemSizes;
|
||||
|
||||
FixedExtentSectionLayoutBuilder({
|
||||
required super.sections,
|
||||
|
@ -26,7 +27,7 @@ class FixedExtentSectionLayoutBuilder<T> extends SectionLayoutBuilder<T> {
|
|||
required super.tileHeight,
|
||||
required super.tileBuilder,
|
||||
required super.tileAnimationDelay,
|
||||
});
|
||||
}) : _itemSizes = List.generate(columnCount, (index) => Size(tileWidth, tileHeight));
|
||||
|
||||
@override
|
||||
SectionedListLayout<T> updateLayouts(BuildContext context) {
|
||||
|
@ -93,6 +94,7 @@ class FixedExtentSectionLayoutBuilder<T> extends SectionLayoutBuilder<T> {
|
|||
),
|
||||
sectionKey: sectionKey,
|
||||
headerExtent: headerExtent,
|
||||
itemSizes: _itemSizes,
|
||||
animate: animate,
|
||||
buildGridRow: (children) => FixedExtentGridRow(
|
||||
width: tileWidth,
|
||||
|
|
|
@ -113,6 +113,7 @@ class MosaicSectionLayoutBuilder<T> extends SectionLayoutBuilder<T> {
|
|||
itemIndexRange: () => isHeader ? const Tuple2(0, 0) : Tuple2(row.firstIndex, row.lastIndex + 1),
|
||||
sectionKey: sectionKey,
|
||||
headerExtent: headerExtent,
|
||||
itemSizes: row.itemWidths.map((v) => Size(v, row.height)).toList(),
|
||||
animate: animate,
|
||||
buildGridRow: (children) {
|
||||
return isHeader
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:aves/model/source/section_keys.dart';
|
|||
import 'package:aves/widgets/common/grid/sections/fixed/section_layout_builder.dart';
|
||||
import 'package:aves/widgets/common/grid/sections/list_layout.dart';
|
||||
import 'package:aves/widgets/common/grid/sections/mosaic/section_layout_builder.dart';
|
||||
import 'package:aves/widgets/common/grid/sections/section_layout_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -14,7 +15,7 @@ abstract class SectionedListLayoutProvider<T> extends StatelessWidget {
|
|||
final TileLayout tileLayout;
|
||||
final int columnCount;
|
||||
final double spacing, horizontalPadding, tileWidth, tileHeight;
|
||||
final Widget Function(T item) tileBuilder;
|
||||
final TileBuilder<T> tileBuilder;
|
||||
final Duration tileAnimationDelay;
|
||||
final CoverRatioResolver<T> coverRatioResolver;
|
||||
final Widget child;
|
||||
|
|
|
@ -8,6 +8,8 @@ import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
typedef TileBuilder<T> = Widget Function(T item, Size tileSize);
|
||||
|
||||
abstract class SectionLayoutBuilder<T> {
|
||||
final Map<SectionKey, List<T>> sections;
|
||||
final bool showHeaders;
|
||||
|
@ -17,7 +19,7 @@ abstract class SectionLayoutBuilder<T> {
|
|||
final TileLayout tileLayout;
|
||||
final int columnCount;
|
||||
final double spacing, horizontalPadding, tileWidth, tileHeight, bottom;
|
||||
final Widget Function(T item) tileBuilder;
|
||||
final TileBuilder<T> tileBuilder;
|
||||
final Duration tileAnimationDelay;
|
||||
final bool animate;
|
||||
|
||||
|
@ -55,6 +57,7 @@ abstract class SectionLayoutBuilder<T> {
|
|||
required Tuple2<int, int> Function() itemIndexRange,
|
||||
required SectionKey sectionKey,
|
||||
required double headerExtent,
|
||||
required List<Size> itemSizes,
|
||||
required bool animate,
|
||||
required Widget Function(List<Widget> children) buildGridRow,
|
||||
}) {
|
||||
|
@ -67,13 +70,17 @@ abstract class SectionLayoutBuilder<T> {
|
|||
final itemMinMax = itemIndexRange();
|
||||
final minItemIndex = itemMinMax.item1.clamp(0, sectionItemCount);
|
||||
final maxItemIndex = itemMinMax.item2.clamp(0, sectionItemCount);
|
||||
final childrenCount = maxItemIndex - minItemIndex;
|
||||
final children = <Widget>[];
|
||||
for (var i = minItemIndex; i < maxItemIndex; i++) {
|
||||
final itemGridIndex = sectionGridIndex + i - minItemIndex;
|
||||
for (var i = 0; i < childrenCount; i++) {
|
||||
final item = RepaintBoundary(
|
||||
child: tileBuilder(section[i]),
|
||||
child: tileBuilder(section[minItemIndex + i], itemSizes[i]),
|
||||
);
|
||||
children.add(animate ? _buildAnimation(context, itemGridIndex, item) : item);
|
||||
if (animate) {
|
||||
children.add(_buildAnimation(context, sectionGridIndex + i, item));
|
||||
} else {
|
||||
children.add(item);
|
||||
}
|
||||
}
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: horizontalPadding),
|
||||
|
|
|
@ -281,10 +281,15 @@ class OverlayIcon extends StatelessWidget {
|
|||
children: [
|
||||
iconChild,
|
||||
const SizedBox(width: 2),
|
||||
Text(
|
||||
Flexible(
|
||||
child: Text(
|
||||
text!,
|
||||
// consistent with the color used for the icon next to it
|
||||
style: TextStyle(color: IconTheme.of(context).color),
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -272,6 +272,8 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
|
|||
return TransitionImage(
|
||||
image: entry.bestCachedThumbnail,
|
||||
animation: animation,
|
||||
thumbnailFit: isMosaic ? BoxFit.contain : BoxFit.cover,
|
||||
viewerFit: BoxFit.contain,
|
||||
background: backgroundColor,
|
||||
);
|
||||
},
|
||||
|
|
|
@ -306,11 +306,12 @@ class _FilterGridContent<T extends CollectionFilter> extends StatelessWidget {
|
|||
horizontalPadding: horizontalPadding,
|
||||
tileWidth: thumbnailExtent,
|
||||
tileHeight: tileHeight,
|
||||
tileBuilder: (gridItem) {
|
||||
tileBuilder: (gridItem, tileSize) {
|
||||
final extent = tileSize.shortestSide;
|
||||
return InteractiveFilterTile(
|
||||
gridItem: gridItem,
|
||||
chipExtent: thumbnailExtent,
|
||||
thumbnailExtent: thumbnailExtent,
|
||||
chipExtent: extent,
|
||||
thumbnailExtent: extent,
|
||||
tileLayout: tileLayout,
|
||||
banner: _getFilterBanner(context, gridItem.filter),
|
||||
heroType: heroType,
|
||||
|
|
Loading…
Reference in a new issue