collection: modify tile extent, not column count
This commit is contained in:
parent
2b2e7e31bd
commit
75143cf56b
6 changed files with 130 additions and 63 deletions
|
@ -17,6 +17,7 @@ class Settings {
|
||||||
// preferences
|
// preferences
|
||||||
static const collectionGroupFactorKey = 'collection_group_factor';
|
static const collectionGroupFactorKey = 'collection_group_factor';
|
||||||
static const collectionSortFactorKey = 'collection_sort_factor';
|
static const collectionSortFactorKey = 'collection_sort_factor';
|
||||||
|
static const collectionTileExtentKey = 'collection_tile_extent';
|
||||||
static const infoMapZoomKey = 'info_map_zoom';
|
static const infoMapZoomKey = 'info_map_zoom';
|
||||||
static const catalogTimeZoneKey = 'catalog_time_zone';
|
static const catalogTimeZoneKey = 'catalog_time_zone';
|
||||||
|
|
||||||
|
@ -64,6 +65,10 @@ class Settings {
|
||||||
|
|
||||||
set collectionSortFactor(SortFactor newValue) => setAndNotify(collectionSortFactorKey, newValue.toString());
|
set collectionSortFactor(SortFactor newValue) => setAndNotify(collectionSortFactorKey, newValue.toString());
|
||||||
|
|
||||||
|
double get collectionTileExtent => _prefs.getDouble(collectionTileExtentKey) ?? 0;
|
||||||
|
|
||||||
|
set collectionTileExtent(double newValue) => setAndNotify(collectionTileExtentKey, newValue);
|
||||||
|
|
||||||
// convenience methods
|
// convenience methods
|
||||||
|
|
||||||
bool getBoolOrDefault(String key, bool defaultValue) => _prefs.getKeys().contains(key) ? _prefs.getBool(key) : defaultValue;
|
bool getBoolOrDefault(String key, bool defaultValue) => _prefs.getKeys().contains(key) ? _prefs.getBool(key) : defaultValue;
|
||||||
|
|
|
@ -4,19 +4,25 @@ import 'dart:ui' as ui;
|
||||||
import 'package:aves/model/image_entry.dart';
|
import 'package:aves/model/image_entry.dart';
|
||||||
import 'package:aves/widgets/album/collection_section.dart';
|
import 'package:aves/widgets/album/collection_section.dart';
|
||||||
import 'package:aves/widgets/album/thumbnail.dart';
|
import 'package:aves/widgets/album/thumbnail.dart';
|
||||||
|
import 'package:aves/widgets/album/tile_extent_manager.dart';
|
||||||
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
|
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class GridScaleGestureDetector extends StatefulWidget {
|
class GridScaleGestureDetector extends StatefulWidget {
|
||||||
final GlobalKey scrollableKey;
|
final GlobalKey scrollableKey;
|
||||||
final ValueNotifier<int> columnCountNotifier;
|
final ValueNotifier<double> extentNotifier;
|
||||||
|
final Size mqSize;
|
||||||
|
final EdgeInsets mqPadding;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
const GridScaleGestureDetector({
|
const GridScaleGestureDetector({
|
||||||
this.scrollableKey,
|
this.scrollableKey,
|
||||||
@required this.columnCountNotifier,
|
@required this.extentNotifier,
|
||||||
|
@required this.mqSize,
|
||||||
|
@required this.mqPadding,
|
||||||
@required this.child,
|
@required this.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -25,17 +31,21 @@ class GridScaleGestureDetector extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
||||||
int _start;
|
Tuple2<double, double> _extentMinMax;
|
||||||
ValueNotifier<double> _scaledCountNotifier;
|
double _startExtent;
|
||||||
|
ValueNotifier<double> _scaledExtentNotifier;
|
||||||
OverlayEntry _overlayEntry;
|
OverlayEntry _overlayEntry;
|
||||||
ThumbnailMetadata _metadata;
|
ThumbnailMetadata _metadata;
|
||||||
RenderSliver _renderSliver;
|
RenderSliver _renderSliver;
|
||||||
RenderViewport _renderViewport;
|
RenderViewport _renderViewport;
|
||||||
|
|
||||||
ValueNotifier<int> get countNotifier => widget.columnCountNotifier;
|
ValueNotifier<double> get tileExtentNotifier => widget.extentNotifier;
|
||||||
|
|
||||||
static const columnCountMin = 2.0;
|
@override
|
||||||
static const columnCountMax = 8.0;
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_extentMinMax = TileExtentManager.extentBoundsForSize(widget.mqSize);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -54,11 +64,12 @@ class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
||||||
_renderSliver = firstOf<RenderSliverStickyHeader>(result) ?? firstOf<RenderSliverGrid>(result);
|
_renderSliver = firstOf<RenderSliverStickyHeader>(result) ?? firstOf<RenderSliverGrid>(result);
|
||||||
_renderViewport = firstOf<RenderViewport>(result);
|
_renderViewport = firstOf<RenderViewport>(result);
|
||||||
_metadata = renderMetaData.metaData;
|
_metadata = renderMetaData.metaData;
|
||||||
_start = countNotifier.value;
|
_startExtent = tileExtentNotifier.value;
|
||||||
_scaledCountNotifier = ValueNotifier(_start.toDouble());
|
_scaledExtentNotifier = ValueNotifier(_startExtent);
|
||||||
|
|
||||||
|
// not the same as `MediaQuery.size.width`, because of screen insets/padding
|
||||||
final gridWidth = scrollableBox.size.width;
|
final gridWidth = scrollableBox.size.width;
|
||||||
final halfExtent = gridWidth / _start / 2;
|
final halfExtent = _startExtent / 2;
|
||||||
final thumbnailCenter = renderMetaData.localToGlobal(Offset(halfExtent, halfExtent));
|
final thumbnailCenter = renderMetaData.localToGlobal(Offset(halfExtent, halfExtent));
|
||||||
_overlayEntry = OverlayEntry(
|
_overlayEntry = OverlayEntry(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
@ -66,30 +77,34 @@ class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
||||||
imageEntry: _metadata.entry,
|
imageEntry: _metadata.entry,
|
||||||
center: thumbnailCenter,
|
center: thumbnailCenter,
|
||||||
gridWidth: gridWidth,
|
gridWidth: gridWidth,
|
||||||
scaledCountNotifier: _scaledCountNotifier,
|
scaledExtentNotifier: _scaledExtentNotifier,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Overlay.of(scrollableContext).insert(_overlayEntry);
|
Overlay.of(scrollableContext).insert(_overlayEntry);
|
||||||
},
|
},
|
||||||
onScaleUpdate: (details) {
|
onScaleUpdate: (details) {
|
||||||
if (_scaledCountNotifier == null) return;
|
if (_scaledExtentNotifier == null) return;
|
||||||
final s = details.scale;
|
final s = details.scale;
|
||||||
_scaledCountNotifier.value = (_start / s).clamp(columnCountMin, columnCountMax);
|
_scaledExtentNotifier.value = (_startExtent * s).clamp(_extentMinMax.item1, _extentMinMax.item2);
|
||||||
},
|
},
|
||||||
onScaleEnd: (details) {
|
onScaleEnd: (details) {
|
||||||
if (_overlayEntry != null) {
|
if (_overlayEntry != null) {
|
||||||
_overlayEntry.remove();
|
_overlayEntry.remove();
|
||||||
_overlayEntry = null;
|
_overlayEntry = null;
|
||||||
}
|
}
|
||||||
if (_scaledCountNotifier == null) return;
|
if (_scaledExtentNotifier == null) return;
|
||||||
|
|
||||||
final newColumnCount = _scaledCountNotifier.value.round();
|
final oldExtent = tileExtentNotifier.value;
|
||||||
_scaledCountNotifier = null;
|
// sanitize and update grid layout if necessary
|
||||||
if (newColumnCount == countNotifier.value) return;
|
final newExtent = TileExtentManager.applyTileExtent(
|
||||||
|
widget.mqSize,
|
||||||
// update grid layout
|
widget.mqPadding,
|
||||||
countNotifier.value = newColumnCount;
|
tileExtentNotifier,
|
||||||
|
newExtent: _scaledExtentNotifier.value,
|
||||||
|
);
|
||||||
|
_scaledExtentNotifier = null;
|
||||||
|
if (newExtent == oldExtent) return;
|
||||||
|
|
||||||
// scroll to show the focal point thumbnail at its new position
|
// scroll to show the focal point thumbnail at its new position
|
||||||
final sliverClosure = _renderSliver;
|
final sliverClosure = _renderSliver;
|
||||||
|
@ -98,7 +113,7 @@ class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
final scrollableContext = widget.scrollableKey.currentContext;
|
final scrollableContext = widget.scrollableKey.currentContext;
|
||||||
final gridSize = (scrollableContext.findRenderObject() as RenderBox).size;
|
final gridSize = (scrollableContext.findRenderObject() as RenderBox).size;
|
||||||
final newExtent = gridSize.width / newColumnCount;
|
final newColumnCount = gridSize.width / newExtent;
|
||||||
final row = index ~/ newColumnCount;
|
final row = index ~/ newColumnCount;
|
||||||
// `Scrollable.ensureVisible` only works on already rendered objects
|
// `Scrollable.ensureVisible` only works on already rendered objects
|
||||||
// `RenderViewport.showOnScreen` can find any `RenderSliver`, but not always a `RenderMetadata`
|
// `RenderViewport.showOnScreen` can find any `RenderSliver`, but not always a `RenderMetadata`
|
||||||
|
@ -115,13 +130,13 @@ class ScaleOverlay extends StatefulWidget {
|
||||||
final ImageEntry imageEntry;
|
final ImageEntry imageEntry;
|
||||||
final Offset center;
|
final Offset center;
|
||||||
final double gridWidth;
|
final double gridWidth;
|
||||||
final ValueNotifier<double> scaledCountNotifier;
|
final ValueNotifier<double> scaledExtentNotifier;
|
||||||
|
|
||||||
const ScaleOverlay({
|
const ScaleOverlay({
|
||||||
@required this.imageEntry,
|
@required this.imageEntry,
|
||||||
@required this.center,
|
@required this.center,
|
||||||
@required this.gridWidth,
|
@required this.gridWidth,
|
||||||
@required this.scaledCountNotifier,
|
@required this.scaledExtentNotifier,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -168,16 +183,16 @@ class _ScaleOverlayState extends State<ScaleOverlay> {
|
||||||
),
|
),
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
child: ValueListenableBuilder<double>(
|
child: ValueListenableBuilder<double>(
|
||||||
valueListenable: widget.scaledCountNotifier,
|
valueListenable: widget.scaledExtentNotifier,
|
||||||
builder: (context, columnCount, child) {
|
builder: (context, extent, child) {
|
||||||
final extent = gridWidth / columnCount;
|
|
||||||
|
|
||||||
// keep scaled thumbnail within the screen
|
// keep scaled thumbnail within the screen
|
||||||
|
final xMin = MediaQuery.of(context).padding.left;
|
||||||
|
final xMax = xMin + gridWidth;
|
||||||
var dx = .0;
|
var dx = .0;
|
||||||
if (center.dx - extent / 2 < 0) {
|
if (center.dx - extent / 2 < xMin) {
|
||||||
dx = extent / 2 - center.dx;
|
dx = xMin - (center.dx - extent / 2);
|
||||||
} else if (center.dx + extent / 2 > gridWidth) {
|
} else if (center.dx + extent / 2 > xMax) {
|
||||||
dx = gridWidth - (center.dx + extent / 2);
|
dx = xMax - (center.dx + extent / 2);
|
||||||
}
|
}
|
||||||
final clampedCenter = center.translate(dx, 0);
|
final clampedCenter = center.translate(dx, 0);
|
||||||
|
|
||||||
|
|
|
@ -8,19 +8,18 @@ import 'package:aves/widgets/common/icons.dart';
|
||||||
import 'package:aves/widgets/fullscreen/fullscreen_page.dart';
|
import 'package:aves/widgets/fullscreen/fullscreen_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
|
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class SectionSliver extends StatelessWidget {
|
class SectionSliver extends StatelessWidget {
|
||||||
final CollectionLens collection;
|
final CollectionLens collection;
|
||||||
final dynamic sectionKey;
|
final dynamic sectionKey;
|
||||||
final int columnCount;
|
final double tileExtent;
|
||||||
final bool showHeader;
|
final bool showHeader;
|
||||||
|
|
||||||
const SectionSliver({
|
const SectionSliver({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.collection,
|
@required this.collection,
|
||||||
@required this.sectionKey,
|
@required this.sectionKey,
|
||||||
@required this.columnCount,
|
@required this.tileExtent,
|
||||||
@required this.showHeader,
|
@required this.showHeader,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@ -40,14 +39,14 @@ class SectionSliver extends StatelessWidget {
|
||||||
collection: collection,
|
collection: collection,
|
||||||
index: index,
|
index: index,
|
||||||
entry: sectionEntries[index],
|
entry: sectionEntries[index],
|
||||||
columnCount: columnCount,
|
tileExtent: tileExtent,
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
childCount: childCount,
|
childCount: childCount,
|
||||||
addAutomaticKeepAlives: false,
|
addAutomaticKeepAlives: false,
|
||||||
),
|
),
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
crossAxisCount: columnCount,
|
maxCrossAxisExtent: tileExtent,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -69,7 +68,7 @@ class GridThumbnail extends StatelessWidget {
|
||||||
final CollectionLens collection;
|
final CollectionLens collection;
|
||||||
final int index;
|
final int index;
|
||||||
final ImageEntry entry;
|
final ImageEntry entry;
|
||||||
final int columnCount;
|
final double tileExtent;
|
||||||
final GestureTapCallback onTap;
|
final GestureTapCallback onTap;
|
||||||
|
|
||||||
const GridThumbnail({
|
const GridThumbnail({
|
||||||
|
@ -77,7 +76,7 @@ class GridThumbnail extends StatelessWidget {
|
||||||
this.collection,
|
this.collection,
|
||||||
this.index,
|
this.index,
|
||||||
this.entry,
|
this.entry,
|
||||||
this.columnCount,
|
this.tileExtent,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@ -88,15 +87,10 @@ class GridThumbnail extends StatelessWidget {
|
||||||
onTap: () => _goToFullscreen(context),
|
onTap: () => _goToFullscreen(context),
|
||||||
child: MetaData(
|
child: MetaData(
|
||||||
metaData: ThumbnailMetadata(index, entry),
|
metaData: ThumbnailMetadata(index, entry),
|
||||||
child: Selector<MediaQueryData, double>(
|
child: Thumbnail(
|
||||||
selector: (c, mq) => mq.size.width,
|
|
||||||
builder: (c, mqWidth, child) {
|
|
||||||
return Thumbnail(
|
|
||||||
entry: entry,
|
entry: entry,
|
||||||
extent: mqWidth / columnCount,
|
extent: tileExtent,
|
||||||
heroTag: collection.heroTag(entry),
|
heroTag: collection.heroTag(entry),
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,17 +7,19 @@ import 'package:aves/widgets/album/collection_page.dart';
|
||||||
import 'package:aves/widgets/album/collection_scaling.dart';
|
import 'package:aves/widgets/album/collection_scaling.dart';
|
||||||
import 'package:aves/widgets/album/collection_section.dart';
|
import 'package:aves/widgets/album/collection_section.dart';
|
||||||
import 'package:aves/widgets/album/empty.dart';
|
import 'package:aves/widgets/album/empty.dart';
|
||||||
|
import 'package:aves/widgets/album/tile_extent_manager.dart';
|
||||||
import 'package:aves/widgets/common/scroll_thumb.dart';
|
import 'package:aves/widgets/common/scroll_thumb.dart';
|
||||||
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
|
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:outline_material_icons/outline_material_icons.dart';
|
import 'package:outline_material_icons/outline_material_icons.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class ThumbnailCollection extends StatelessWidget {
|
class ThumbnailCollection extends StatelessWidget {
|
||||||
final ValueNotifier<PageState> stateNotifier;
|
final ValueNotifier<PageState> stateNotifier;
|
||||||
|
|
||||||
final ValueNotifier<double> _appBarHeightNotifier = ValueNotifier(0);
|
final ValueNotifier<double> _appBarHeightNotifier = ValueNotifier(0);
|
||||||
final ValueNotifier<int> _columnCountNotifier = ValueNotifier(4);
|
final ValueNotifier<double> _tileExtentNotifier = ValueNotifier(0);
|
||||||
final GlobalKey _scrollableKey = GlobalKey();
|
final GlobalKey _scrollableKey = GlobalKey();
|
||||||
|
|
||||||
ThumbnailCollection({
|
ThumbnailCollection({
|
||||||
|
@ -28,9 +30,13 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Selector<MediaQueryData, double>(
|
child: Selector<MediaQueryData, Tuple3<Size, EdgeInsets, double>>(
|
||||||
selector: (c, mq) => mq.viewInsets.bottom,
|
selector: (c, mq) => Tuple3(mq.size, mq.padding, mq.viewInsets.bottom),
|
||||||
builder: (c, mqViewInsetsBottom, child) {
|
builder: (c, mq, child) {
|
||||||
|
final mqSize = mq.item1;
|
||||||
|
final mqPadding = mq.item2;
|
||||||
|
final mqViewInsetsBottom = mq.item3;
|
||||||
|
TileExtentManager.applyTileExtent(mqSize, mqPadding, _tileExtentNotifier);
|
||||||
return Consumer<CollectionLens>(
|
return Consumer<CollectionLens>(
|
||||||
builder: (context, collection, child) {
|
builder: (context, collection, child) {
|
||||||
// debugPrint('$runtimeType collection builder entries=${collection.entryCount}');
|
// debugPrint('$runtimeType collection builder entries=${collection.entryCount}');
|
||||||
|
@ -38,11 +44,13 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
final showHeaders = collection.showHeaders;
|
final showHeaders = collection.showHeaders;
|
||||||
return GridScaleGestureDetector(
|
return GridScaleGestureDetector(
|
||||||
scrollableKey: _scrollableKey,
|
scrollableKey: _scrollableKey,
|
||||||
columnCountNotifier: _columnCountNotifier,
|
extentNotifier: _tileExtentNotifier,
|
||||||
child: ValueListenableBuilder<int>(
|
mqSize: mqSize,
|
||||||
valueListenable: _columnCountNotifier,
|
mqPadding: mqPadding,
|
||||||
builder: (context, columnCount, child) {
|
child: ValueListenableBuilder<double>(
|
||||||
debugPrint('$runtimeType columnCount builder entries=${collection.entryCount} columnCount=$columnCount');
|
valueListenable: _tileExtentNotifier,
|
||||||
|
builder: (context, tileExtent, child) {
|
||||||
|
debugPrint('$runtimeType tileExtent builder entries=${collection.entryCount} tileExtent=$tileExtent');
|
||||||
final scrollView = CustomScrollView(
|
final scrollView = CustomScrollView(
|
||||||
key: _scrollableKey,
|
key: _scrollableKey,
|
||||||
primary: true,
|
primary: true,
|
||||||
|
@ -63,7 +71,7 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
...sectionKeys.map((sectionKey) => SectionSliver(
|
...sectionKeys.map((sectionKey) => SectionSliver(
|
||||||
collection: collection,
|
collection: collection,
|
||||||
sectionKey: sectionKey,
|
sectionKey: sectionKey,
|
||||||
columnCount: columnCount,
|
tileExtent: tileExtent,
|
||||||
showHeader: showHeaders,
|
showHeader: showHeaders,
|
||||||
)),
|
)),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
|
|
39
lib/widgets/album/tile_extent_manager.dart
Normal file
39
lib/widgets/album/tile_extent_manager.dart
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import 'package:aves/model/settings.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
class TileExtentManager {
|
||||||
|
static const columnCountMin = 2;
|
||||||
|
static const columnCountDefault = 4;
|
||||||
|
static const columnCountMax = 8;
|
||||||
|
|
||||||
|
static double applyTileExtent(Size mqSize, EdgeInsets mqPadding, ValueNotifier<double> extentNotifier, {double newExtent}) {
|
||||||
|
final availableWidth = mqSize.width - mqPadding.horizontal;
|
||||||
|
var numColumns;
|
||||||
|
if ((newExtent ?? 0) == 0) {
|
||||||
|
newExtent = extentNotifier.value;
|
||||||
|
}
|
||||||
|
if ((newExtent ?? 0) == 0) {
|
||||||
|
newExtent = settings.collectionTileExtent;
|
||||||
|
}
|
||||||
|
if ((newExtent ?? 0) == 0) {
|
||||||
|
numColumns = columnCountDefault;
|
||||||
|
} else {
|
||||||
|
final minMax = extentBoundsForSize(mqSize);
|
||||||
|
newExtent = newExtent.clamp(minMax.item1, minMax.item2);
|
||||||
|
numColumns = (availableWidth / newExtent).round().clamp(columnCountMin, columnCountMax);
|
||||||
|
}
|
||||||
|
newExtent = availableWidth / numColumns;
|
||||||
|
if (extentNotifier.value != newExtent) {
|
||||||
|
settings.collectionTileExtent = newExtent;
|
||||||
|
extentNotifier.value = newExtent;
|
||||||
|
}
|
||||||
|
return newExtent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Tuple2<double, double> extentBoundsForSize(Size mqSize) {
|
||||||
|
final min = mqSize.shortestSide / columnCountMax;
|
||||||
|
final max = mqSize.shortestSide / columnCountMin;
|
||||||
|
return Tuple2(min, max);
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,14 +47,20 @@ class DebugPageState extends State<DebugPage> {
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
children: [
|
children: [
|
||||||
const Text('Settings'),
|
const Text('Settings'),
|
||||||
|
const Spacer(),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
onPressed: () => settings.reset().then((_) => setState(() {})),
|
onPressed: () => settings.reset().then((_) => setState(() {})),
|
||||||
child: const Text('Reset settings'),
|
child: const Text('Reset'),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Text('collectionGroupFactor: ${settings.collectionGroupFactor}'),
|
Text('collectionGroupFactor: ${settings.collectionGroupFactor}'),
|
||||||
Text('collectionSortFactor: ${settings.collectionSortFactor}'),
|
Text('collectionSortFactor: ${settings.collectionSortFactor}'),
|
||||||
|
Text('collectionTileExtent: ${settings.collectionTileExtent}'),
|
||||||
Text('infoMapZoom: ${settings.infoMapZoom}'),
|
Text('infoMapZoom: ${settings.infoMapZoom}'),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
Text('Entries: ${entries.length}'),
|
Text('Entries: ${entries.length}'),
|
||||||
|
@ -73,7 +79,7 @@ class DebugPageState extends State<DebugPage> {
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
onPressed: () => metadataDb.reset().then((_) => _startDbReport()),
|
onPressed: () => metadataDb.reset().then((_) => _startDbReport()),
|
||||||
child: const Text('Reset DB'),
|
child: const Text('Reset'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue