Skip to content

Commit

Permalink
Use custom gesture detector
Browse files Browse the repository at this point in the history
  • Loading branch information
lifegpc committed Dec 26, 2023
1 parent 7b7dae2 commit f57c276
Showing 1 changed file with 81 additions and 3 deletions.
84 changes: 81 additions & 3 deletions lib/viewer/single.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:ui';
import 'package:dio/dio.dart';
import 'package:dio_image_provider/dio_image_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
Expand All @@ -16,6 +18,12 @@ import '../globals.dart';

final _log = Logger("SinglePageViewer");

enum DoubleTapScaleMode {
fitScreen,
orignal,
twice,
}

class SinglePageViewerExtra {
const SinglePageViewerExtra({this.data, this.files});
final GalleryData? data;
Expand Down Expand Up @@ -44,6 +52,8 @@ class _SinglePageViewer extends State<SinglePageViewer>
late List<ExtendedPMeta>? _pages;
late EhFiles? _files;
late String _back;
late PhotoViewController _photoViewController;
late DoubleTapScaleMode _doubleTapScaleMode;
CancelToken? _cancel;
bool _isLoading = false;
bool _pageChanged = false;
Expand All @@ -69,13 +79,16 @@ class _SinglePageViewer extends State<SinglePageViewer>
_updatePages();
_files = widget.files;
_back = "/gallery/${widget.gid}";
_photoViewController = PhotoViewController();
_doubleTapScaleMode = DoubleTapScaleMode.fitScreen;
super.initState();
}

@override
void dispose() {
_cancel?.cancel();
_pageController.dispose();
_photoViewController.dispose();
super.dispose();
}

Expand Down Expand Up @@ -124,6 +137,10 @@ class _SinglePageViewer extends State<SinglePageViewer>
builder: (BuildContext context, int index) {
final data = _pages![index];
final f = _files!.files[data.token]!.first;
if (_index != index) {
_photoViewController.reset();
_doubleTapScaleMode = DoubleTapScaleMode.fitScreen;
}
return PhotoViewGalleryPageOptions(
imageProvider: DioImage.string(
api.getFileUrl(f.id),
Expand All @@ -135,6 +152,8 @@ class _SinglePageViewer extends State<SinglePageViewer>
transitionOnUserGestures: true,
),
filterQuality: FilterQuality.high,
controller: _photoViewController,
disableGestures: true,
);
},
onPageChanged: (index) {
Expand Down Expand Up @@ -179,14 +198,73 @@ class _SinglePageViewer extends State<SinglePageViewer>
_showMenu = !_showMenu;
});
},
onDoubleTap: () {
setState(() {
switch (_doubleTapScaleMode) {
case DoubleTapScaleMode.fitScreen:
_doubleTapScaleMode = DoubleTapScaleMode.orignal;
_photoViewController.scale = 1.0;
break;
case DoubleTapScaleMode.orignal:
_doubleTapScaleMode = DoubleTapScaleMode.twice;
_photoViewController.scale = 2.0;
break;
case DoubleTapScaleMode.twice:
_doubleTapScaleMode = DoubleTapScaleMode.fitScreen;
_photoViewController.scale = null;
break;
}
});
},
child: child,
);
}

Widget _buildWithDragSupport(BuildContext context, {required Widget child}) {
return RawGestureDetector(
gestures: {
PanGestureRecognizer:
GestureRecognizerFactoryWithHandlers<PanGestureRecognizer>(
() => PanGestureRecognizer(
allowedButtonsFilter: (buttons) => buttons == kPrimaryMouseButton,
),
(instance) {
instance.onUpdate = (details) {
final position = _photoViewController.position;
_photoViewController.position = Offset(
position.dx + details.delta.dx,
position.dy + details.delta.dy);
setState(() {});
};
},
),
},
child: child,
);
}

Widget _buildWithScrollSupport(BuildContext context,
{required Widget child}) {
return Listener(
onPointerSignal: (event) {
if (event is PointerScrollEvent &&
event.kind == PointerDeviceKind.mouse) {
if (_photoViewController.scale != null) {
_photoViewController.scale = _photoViewController.scale! *
(1 - event.scrollDelta.dy / MediaQuery.of(context).size.height);
}
}
},
child: child,
);
}

Widget _buildViewer(BuildContext context) {
return _buildWithTap(context,
child:
_buildWithKeyboardSupport(context, child: _buildGallery(context)));
return _buildWithDragSupport(context,
child: _buildWithScrollSupport(context,
child: _buildWithTap(context,
child: _buildWithKeyboardSupport(context,
child: _buildGallery(context)))));
}

Widget _buildTopAppBar(BuildContext context) {
Expand Down

0 comments on commit f57c276

Please sign in to comment.