mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
Improve the long press to zoom feature.
This commit is contained in:
@@ -115,6 +115,10 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
|
|
||||||
var imageStates = <State<ComicImage>>{};
|
var imageStates = <State<ComicImage>>{};
|
||||||
|
|
||||||
|
bool isLongPressing = false;
|
||||||
|
|
||||||
|
int fingers = 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
reader = context.reader;
|
reader = context.reader;
|
||||||
@@ -144,81 +148,103 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return PhotoViewGallery.builder(
|
return Listener(
|
||||||
backgroundDecoration: BoxDecoration(
|
onPointerDown: (event) {
|
||||||
color: context.colorScheme.surface,
|
fingers++;
|
||||||
),
|
},
|
||||||
reverse: reader.mode == ReaderMode.galleryRightToLeft,
|
onPointerUp: (event) {
|
||||||
scrollDirection: reader.mode == ReaderMode.galleryTopToBottom
|
fingers--;
|
||||||
? Axis.vertical
|
},
|
||||||
: Axis.horizontal,
|
onPointerCancel: (event) {
|
||||||
itemCount: totalPages + 2,
|
fingers--;
|
||||||
builder: (BuildContext context, int index) {
|
},
|
||||||
if (index == 0 || index == totalPages + 1) {
|
onPointerMove: (event) {
|
||||||
return PhotoViewGalleryPageOptions.customChild(
|
if (isLongPressing) {
|
||||||
child: const SizedBox(),
|
var controller = photoViewControllers[reader.page]!;
|
||||||
);
|
Offset value = event.delta;
|
||||||
} else {
|
if (isLongPressing) {
|
||||||
int pageIndex = index - 1;
|
controller.updateMultiple(
|
||||||
int startIndex = pageIndex * reader.imagesPerPage;
|
position: controller.position + value,
|
||||||
int endIndex = math.min(
|
|
||||||
startIndex + reader.imagesPerPage, reader.images!.length);
|
|
||||||
List<String> pageImages =
|
|
||||||
reader.images!.sublist(startIndex, endIndex);
|
|
||||||
|
|
||||||
cached[index] = true;
|
|
||||||
cache(index);
|
|
||||||
|
|
||||||
photoViewControllers[index] ??= PhotoViewController();
|
|
||||||
|
|
||||||
if (reader.imagesPerPage == 1) {
|
|
||||||
return PhotoViewGalleryPageOptions(
|
|
||||||
filterQuality: FilterQuality.medium,
|
|
||||||
controller: photoViewControllers[index],
|
|
||||||
imageProvider:
|
|
||||||
_createImageProviderFromKey(pageImages[0], context),
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
errorBuilder: (_, error, s, retry) {
|
|
||||||
return NetworkError(message: error.toString(), retry: retry);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PhotoViewGalleryPageOptions.customChild(
|
|
||||||
controller: photoViewControllers[index],
|
|
||||||
minScale: PhotoViewComputedScale.contained * 1.0,
|
|
||||||
maxScale: PhotoViewComputedScale.covered * 10.0,
|
|
||||||
child: buildPageImages(pageImages),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pageController: controller,
|
child: PhotoViewGallery.builder(
|
||||||
loadingBuilder: (context, event) => Center(
|
backgroundDecoration: BoxDecoration(
|
||||||
child: SizedBox(
|
color: context.colorScheme.surface,
|
||||||
width: 20.0,
|
),
|
||||||
height: 20.0,
|
reverse: reader.mode == ReaderMode.galleryRightToLeft,
|
||||||
child: CircularProgressIndicator(
|
scrollDirection: reader.mode == ReaderMode.galleryTopToBottom
|
||||||
backgroundColor: context.colorScheme.surfaceContainerHigh,
|
? Axis.vertical
|
||||||
value: event == null || event.expectedTotalBytes == null
|
: Axis.horizontal,
|
||||||
? null
|
itemCount: totalPages + 2,
|
||||||
: event.cumulativeBytesLoaded / event.expectedTotalBytes!,
|
builder: (BuildContext context, int index) {
|
||||||
|
if (index == 0 || index == totalPages + 1) {
|
||||||
|
return PhotoViewGalleryPageOptions.customChild(
|
||||||
|
child: const SizedBox(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
int pageIndex = index - 1;
|
||||||
|
int startIndex = pageIndex * reader.imagesPerPage;
|
||||||
|
int endIndex = math.min(
|
||||||
|
startIndex + reader.imagesPerPage, reader.images!.length);
|
||||||
|
List<String> pageImages =
|
||||||
|
reader.images!.sublist(startIndex, endIndex);
|
||||||
|
|
||||||
|
cached[index] = true;
|
||||||
|
cache(index);
|
||||||
|
|
||||||
|
photoViewControllers[index] ??= PhotoViewController();
|
||||||
|
|
||||||
|
if (reader.imagesPerPage == 1) {
|
||||||
|
return PhotoViewGalleryPageOptions(
|
||||||
|
filterQuality: FilterQuality.medium,
|
||||||
|
controller: photoViewControllers[index],
|
||||||
|
imageProvider:
|
||||||
|
_createImageProviderFromKey(pageImages[0], context),
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
errorBuilder: (_, error, s, retry) {
|
||||||
|
return NetworkError(message: error.toString(), retry: retry);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PhotoViewGalleryPageOptions.customChild(
|
||||||
|
controller: photoViewControllers[index],
|
||||||
|
minScale: PhotoViewComputedScale.contained * 1.0,
|
||||||
|
maxScale: PhotoViewComputedScale.covered * 10.0,
|
||||||
|
child: buildPageImages(pageImages),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pageController: controller,
|
||||||
|
loadingBuilder: (context, event) => Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 20.0,
|
||||||
|
height: 20.0,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
backgroundColor: context.colorScheme.surfaceContainerHigh,
|
||||||
|
value: event == null || event.expectedTotalBytes == null
|
||||||
|
? null
|
||||||
|
: event.cumulativeBytesLoaded / event.expectedTotalBytes!,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
onPageChanged: (i) {
|
||||||
|
if (i == 0) {
|
||||||
|
if (reader.isFirstChapterOfGroup || !reader.toPrevChapter()) {
|
||||||
|
reader.toPage(1);
|
||||||
|
}
|
||||||
|
} else if (i == totalPages + 1) {
|
||||||
|
if (reader.isLastChapterOfGroup || !reader.toNextChapter()) {
|
||||||
|
reader.toPage(totalPages);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reader.setPage(i);
|
||||||
|
context.readerScaffold.update();
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
onPageChanged: (i) {
|
|
||||||
if (i == 0) {
|
|
||||||
if (reader.isFirstChapterOfGroup || !reader.toPrevChapter()) {
|
|
||||||
reader.toPage(1);
|
|
||||||
}
|
|
||||||
} else if (i == totalPages + 1) {
|
|
||||||
if (reader.isLastChapterOfGroup || !reader.toNextChapter()) {
|
|
||||||
reader.toPage(totalPages);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reader.setPage(i);
|
|
||||||
context.readerScaffold.update();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +292,7 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
} else {
|
} else {
|
||||||
imageWidgets = images.map((imageKey) {
|
imageWidgets = images.map((imageKey) {
|
||||||
ImageProvider imageProvider =
|
ImageProvider imageProvider =
|
||||||
_createImageProviderFromKey(imageKey, context);
|
_createImageProviderFromKey(imageKey, context);
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: ComicImage(
|
child: ComicImage(
|
||||||
image: imageProvider,
|
image: imageProvider,
|
||||||
@@ -312,7 +338,7 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleLongPressDown(Offset location) {
|
void handleLongPressDown(Offset location) {
|
||||||
if (!appdata.settings['enableLongPressToZoom']) {
|
if (!appdata.settings['enableLongPressToZoom'] || fingers != 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var photoViewController = photoViewControllers[reader.page]!;
|
var photoViewController = photoViewControllers[reader.page]!;
|
||||||
@@ -322,16 +348,18 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
target,
|
target,
|
||||||
Offset(size.width / 2 - location.dx, size.height / 2 - location.dy),
|
Offset(size.width / 2 - location.dx, size.height / 2 - location.dy),
|
||||||
);
|
);
|
||||||
|
isLongPressing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleLongPressUp(Offset location) {
|
void handleLongPressUp(Offset location) {
|
||||||
if (!appdata.settings['enableLongPressToZoom']) {
|
if (!appdata.settings['enableLongPressToZoom'] || !isLongPressing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var photoViewController = photoViewControllers[reader.page]!;
|
var photoViewController = photoViewControllers[reader.page]!;
|
||||||
double target = photoViewController.getInitialScale!.call()!;
|
double target = photoViewController.getInitialScale!.call()!;
|
||||||
photoViewController.animateScale?.call(target);
|
photoViewController.animateScale?.call(target);
|
||||||
|
isLongPressing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer? keyRepeatTimer;
|
Timer? keyRepeatTimer;
|
||||||
|
Reference in New Issue
Block a user