various minor fixes
This commit is contained in:
parent
154ceecae0
commit
3ef5cde4da
7 changed files with 73 additions and 52 deletions
|
@ -4,11 +4,13 @@ class XMP {
|
|||
|
||||
// cf https://exiftool.org/TagNames/XMP.html
|
||||
static const Map<String, String> namespaces = {
|
||||
'aux': 'Auxiliary Exif',
|
||||
'aux': 'Exif Aux',
|
||||
'Camera': 'Camera',
|
||||
'crs': 'Camera Raw Settings',
|
||||
'dc': 'Dublin Core',
|
||||
'exif': 'Exif',
|
||||
'exifEX': 'Exif Ex',
|
||||
'GettyImagesGIFT': 'Getty Images',
|
||||
'GIMP': 'GIMP',
|
||||
'illustrator': 'Illustrator',
|
||||
'Iptc4xmpCore': 'IPTC Core',
|
||||
|
@ -19,6 +21,7 @@ class XMP {
|
|||
'pdfx': 'PDF/X',
|
||||
'photomechanic': 'Photo Mechanic',
|
||||
'photoshop': 'Photoshop',
|
||||
'plus': 'PLUS',
|
||||
'tiff': 'TIFF',
|
||||
'xmp': 'Basic',
|
||||
'xmpBJ': 'Basic Job Ticket',
|
||||
|
|
|
@ -87,6 +87,7 @@ class _LicensesState extends State<Licenses> {
|
|||
|
||||
Widget _buildHeader() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.only(start: 8),
|
||||
|
|
|
@ -3,7 +3,6 @@ import 'dart:math';
|
|||
import 'package:aves/model/image_entry.dart';
|
||||
import 'package:aves/model/source/collection_lens.dart';
|
||||
import 'package:aves/widgets/collection/grid/header_generic.dart';
|
||||
import 'package:aves/widgets/collection/thumbnail_collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
@ -15,14 +14,14 @@ class SectionedListLayoutProvider extends StatelessWidget {
|
|||
final Widget Function(ImageEntry entry) thumbnailBuilder;
|
||||
final Widget child;
|
||||
|
||||
SectionedListLayoutProvider({
|
||||
const SectionedListLayoutProvider({
|
||||
@required this.collection,
|
||||
@required this.scrollableWidth,
|
||||
@required this.tileExtent,
|
||||
@required this.columnCount,
|
||||
@required this.thumbnailBuilder,
|
||||
@required this.child,
|
||||
}) : assert(scrollableWidth != 0),
|
||||
columnCount = max((scrollableWidth / tileExtent).round(), ThumbnailCollection.columnCountMin);
|
||||
}) : assert(scrollableWidth != 0);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -31,9 +31,9 @@ class ThumbnailCollection extends StatelessWidget {
|
|||
final ValueNotifier<bool> _isScrollingNotifier = ValueNotifier(false);
|
||||
final GlobalKey _scrollableKey = GlobalKey();
|
||||
|
||||
static const columnCountMin = 2;
|
||||
static const columnCountDefault = 4;
|
||||
static const extentMin = 46.0;
|
||||
static const spacing = 0.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -47,11 +47,10 @@ class ThumbnailCollection extends StatelessWidget {
|
|||
|
||||
final tileExtentManager = TileExtentManager(
|
||||
settingsRouteKey: context.currentRouteName,
|
||||
columnCountMin: columnCountMin,
|
||||
extentNotifier: _tileExtentNotifier,
|
||||
columnCountDefault: columnCountDefault,
|
||||
extentMin: extentMin,
|
||||
extentNotifier: _tileExtentNotifier,
|
||||
spacing: 0,
|
||||
spacing: spacing,
|
||||
)..applyTileExtent(viewportSize: viewportSize);
|
||||
final cacheExtent = tileExtentManager.getEffectiveExtentMax(viewportSize) * 2;
|
||||
|
||||
|
@ -77,7 +76,18 @@ class ThumbnailCollection extends StatelessWidget {
|
|||
scrollableKey: _scrollableKey,
|
||||
appBarHeightNotifier: _appBarHeightNotifier,
|
||||
viewportSize: viewportSize,
|
||||
showScaledGrid: true,
|
||||
gridBuilder: (center, extent, child) => CustomPaint(
|
||||
// painting the thumbnail half-border on top of the grid yields artifacts,
|
||||
// so we use a `foregroundPainter` to cover them instead
|
||||
foregroundPainter: GridPainter(
|
||||
center: center,
|
||||
extent: extent,
|
||||
spacing: tileExtentManager.spacing,
|
||||
strokeWidth: DecoratedThumbnail.borderWidth * 2,
|
||||
color: DecoratedThumbnail.borderColor,
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
scaledBuilder: (entry, extent) => DecoratedThumbnail(
|
||||
entry: entry,
|
||||
extent: extent,
|
||||
|
@ -98,6 +108,7 @@ class ThumbnailCollection extends StatelessWidget {
|
|||
collection: collection,
|
||||
scrollableWidth: viewportSize.width,
|
||||
tileExtent: tileExtent,
|
||||
columnCount: tileExtentManager.getEffectiveColumnCountForExtent(viewportSize, tileExtent),
|
||||
thumbnailBuilder: (entry) => GridThumbnail(
|
||||
key: ValueKey(entry.contentId),
|
||||
collection: collection,
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:math';
|
|||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/widgets/collection/thumbnail/decorated.dart';
|
||||
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||
import 'package:aves/widgets/common/tile_extent_manager.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -20,7 +19,7 @@ class GridScaleGestureDetector<T> extends StatefulWidget {
|
|||
final GlobalKey scrollableKey;
|
||||
final ValueNotifier<double> appBarHeightNotifier;
|
||||
final Size viewportSize;
|
||||
final bool showScaledGrid;
|
||||
final Widget Function(Offset center, double extent, Widget child) gridBuilder;
|
||||
final Widget Function(T item, double extent) scaledBuilder;
|
||||
final Rect Function(BuildContext context, T item) getScaledItemTileRect;
|
||||
final void Function(T item) onScaled;
|
||||
|
@ -31,7 +30,7 @@ class GridScaleGestureDetector<T> extends StatefulWidget {
|
|||
@required this.scrollableKey,
|
||||
@required this.appBarHeightNotifier,
|
||||
@required this.viewportSize,
|
||||
@required this.showScaledGrid,
|
||||
this.gridBuilder,
|
||||
@required this.scaledBuilder,
|
||||
@required this.getScaledItemTileRect,
|
||||
@required this.onScaled,
|
||||
|
@ -56,10 +55,6 @@ class _GridScaleGestureDetectorState<T> extends State<GridScaleGestureDetector<T
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onHorizontalDragStart: (details) {
|
||||
// if `onHorizontalDragStart` callback is not defined,
|
||||
// horizontal drag gestures are interpreted as scaling
|
||||
},
|
||||
onScaleStart: (details) {
|
||||
// the gesture detector wrongly detects a new scaling gesture
|
||||
// when scaling ends and we apply the new extent, so we prevent this
|
||||
|
@ -91,10 +86,9 @@ class _GridScaleGestureDetectorState<T> extends State<GridScaleGestureDetector<T
|
|||
builder: (context) => ScaleOverlay(
|
||||
builder: (extent) => widget.scaledBuilder(_metadata.item, extent),
|
||||
center: thumbnailCenter,
|
||||
gridWidth: gridWidth,
|
||||
spacing: tileExtentManager.spacing,
|
||||
viewportWidth: gridWidth,
|
||||
gridBuilder: widget.gridBuilder,
|
||||
scaledExtentNotifier: _scaledExtentNotifier,
|
||||
showScaledGrid: widget.showScaledGrid,
|
||||
),
|
||||
);
|
||||
Overlay.of(scrollableContext).insert(_overlayEntry);
|
||||
|
@ -133,7 +127,16 @@ class _GridScaleGestureDetectorState<T> extends State<GridScaleGestureDetector<T
|
|||
});
|
||||
}
|
||||
},
|
||||
child: widget.child,
|
||||
child: GestureDetector(
|
||||
// Horizontal/vertical drag gestures are interpreted as scaling
|
||||
// if they are not handled by `onHorizontalDragStart`/`onVerticalDragStart`
|
||||
// at the scaling `GestureDetector` level, or handled beforehand down the widget tree.
|
||||
// Setting `onHorizontalDragStart`, `onVerticalDragStart`, and `onScaleStart`
|
||||
// all at once is not allowed, so we use another `GestureDetector` for that.
|
||||
onVerticalDragStart: (details) {},
|
||||
onHorizontalDragStart: (details) {},
|
||||
child: widget.child,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -157,18 +160,16 @@ class _GridScaleGestureDetectorState<T> extends State<GridScaleGestureDetector<T
|
|||
class ScaleOverlay extends StatefulWidget {
|
||||
final Widget Function(double extent) builder;
|
||||
final Offset center;
|
||||
final double gridWidth;
|
||||
final double spacing;
|
||||
final double viewportWidth;
|
||||
final ValueNotifier<double> scaledExtentNotifier;
|
||||
final bool showScaledGrid;
|
||||
final Widget Function(Offset center, double extent, Widget child) gridBuilder;
|
||||
|
||||
const ScaleOverlay({
|
||||
@required this.builder,
|
||||
@required this.center,
|
||||
@required this.gridWidth,
|
||||
@required this.spacing,
|
||||
@required this.viewportWidth,
|
||||
@required this.scaledExtentNotifier,
|
||||
@required this.showScaledGrid,
|
||||
this.gridBuilder,
|
||||
});
|
||||
|
||||
@override
|
||||
|
@ -180,7 +181,7 @@ class _ScaleOverlayState extends State<ScaleOverlay> {
|
|||
|
||||
Offset get center => widget.center;
|
||||
|
||||
double get gridWidth => widget.gridWidth;
|
||||
double get gridWidth => widget.viewportWidth;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -241,16 +242,7 @@ class _ScaleOverlayState extends State<ScaleOverlay> {
|
|||
),
|
||||
],
|
||||
);
|
||||
if (widget.showScaledGrid) {
|
||||
child = CustomPaint(
|
||||
painter: GridPainter(
|
||||
center: clampedCenter,
|
||||
extent: extent,
|
||||
spacing: widget.spacing,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
child = widget.gridBuilder?.call(clampedCenter, extent, child) ?? child;
|
||||
return child;
|
||||
},
|
||||
),
|
||||
|
@ -263,31 +255,36 @@ class _ScaleOverlayState extends State<ScaleOverlay> {
|
|||
class GridPainter extends CustomPainter {
|
||||
final Offset center;
|
||||
final double extent, spacing;
|
||||
final double strokeWidth;
|
||||
final Color color;
|
||||
|
||||
const GridPainter({
|
||||
@required this.center,
|
||||
@required this.extent,
|
||||
@required this.spacing,
|
||||
this.spacing = 0.0,
|
||||
this.strokeWidth = 1.0,
|
||||
@required this.color,
|
||||
});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final radius = extent * 3;
|
||||
final paint = Paint()
|
||||
..strokeWidth = DecoratedThumbnail.borderWidth
|
||||
..strokeWidth = strokeWidth
|
||||
..shader = ui.Gradient.radial(
|
||||
center,
|
||||
size.width * .7,
|
||||
radius,
|
||||
[
|
||||
DecoratedThumbnail.borderColor,
|
||||
color,
|
||||
Colors.transparent,
|
||||
],
|
||||
[
|
||||
min(.5, 2 * extent / size.width),
|
||||
extent / radius,
|
||||
1,
|
||||
],
|
||||
);
|
||||
void draw(Offset topLeft) {
|
||||
for (var i = -2; i <= 3; i++) {
|
||||
for (var i = -1; i <= 2; i++) {
|
||||
final ref = (extent + spacing) * i;
|
||||
canvas.drawLine(Offset(0, topLeft.dy + ref), Offset(size.width, topLeft.dy + ref), paint);
|
||||
canvas.drawLine(Offset(topLeft.dx + ref, 0), Offset(topLeft.dx + ref, size.height), paint);
|
||||
|
|
|
@ -6,15 +6,16 @@ import 'package:flutter/widgets.dart';
|
|||
class TileExtentManager {
|
||||
final String settingsRouteKey;
|
||||
final int columnCountMin, columnCountDefault;
|
||||
final double spacing, extentMin;
|
||||
final double spacing, extentMin, extentMax;
|
||||
final ValueNotifier<double> extentNotifier;
|
||||
|
||||
const TileExtentManager({
|
||||
@required this.settingsRouteKey,
|
||||
@required this.columnCountMin,
|
||||
@required this.extentNotifier,
|
||||
this.columnCountMin = 2,
|
||||
@required this.columnCountDefault,
|
||||
@required this.extentMin,
|
||||
@required this.extentNotifier,
|
||||
this.extentMax = 300,
|
||||
@required this.spacing,
|
||||
});
|
||||
|
||||
|
@ -46,7 +47,7 @@ class TileExtentManager {
|
|||
return newExtent;
|
||||
}
|
||||
|
||||
double _extentMax(Size viewportSize) => (viewportSize.shortestSide - spacing * (columnCountMin - 1)) / columnCountMin;
|
||||
double _extentMax(Size viewportSize) => min(extentMax, (viewportSize.shortestSide - spacing * (columnCountMin - 1)) / columnCountMin);
|
||||
|
||||
double _columnCountForExtent(Size viewportSize, double extent) => (viewportSize.width + spacing) / (extent + spacing);
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
|
|||
final ValueNotifier<double> _tileExtentNotifier = ValueNotifier(0);
|
||||
final GlobalKey _scrollableKey = GlobalKey();
|
||||
|
||||
static const columnCountDefault = 2;
|
||||
static const extentMin = 60.0;
|
||||
static const spacing = 8.0;
|
||||
|
||||
FilterGridPage({
|
||||
|
@ -71,10 +73,9 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
|
|||
|
||||
final tileExtentManager = TileExtentManager(
|
||||
settingsRouteKey: settingsRouteKey ?? context.currentRouteName,
|
||||
columnCountMin: 2,
|
||||
columnCountDefault: 2,
|
||||
extentMin: 60,
|
||||
extentNotifier: _tileExtentNotifier,
|
||||
columnCountDefault: columnCountDefault,
|
||||
extentMin: extentMin,
|
||||
spacing: spacing,
|
||||
)..applyTileExtent(viewportSize: viewportSize);
|
||||
|
||||
|
@ -98,7 +99,15 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
|
|||
scrollableKey: _scrollableKey,
|
||||
appBarHeightNotifier: _appBarHeightNotifier,
|
||||
viewportSize: viewportSize,
|
||||
showScaledGrid: true,
|
||||
gridBuilder: (center, extent, child) => CustomPaint(
|
||||
painter: GridPainter(
|
||||
center: center,
|
||||
extent: extent,
|
||||
spacing: tileExtentManager.spacing,
|
||||
color: Colors.grey.shade700,
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
scaledBuilder: (item, extent) {
|
||||
final filter = item.filter;
|
||||
return SizedBox(
|
||||
|
|
Loading…
Reference in a new issue