Add mouse-wheel support to previousNextNavigation

This commit is contained in:
Shawn 2023-12-05 10:59:49 -07:00
parent e34479ccd8
commit cc6e1649d1

View File

@ -1,9 +1,10 @@
import 'package:flutter/gestures.dart';
import 'package:wonders/common_libs.dart'; import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/common/platform_info.dart'; import 'package:wonders/logic/common/platform_info.dart';
import 'package:wonders/ui/common/app_icons.dart'; import 'package:wonders/ui/common/app_icons.dart';
import 'package:wonders/ui/common/fullscreen_keyboard_listener.dart'; import 'package:wonders/ui/common/fullscreen_keyboard_listener.dart';
class PreviousNextNavigation extends StatelessWidget { class PreviousNextNavigation extends StatefulWidget {
const PreviousNextNavigation( const PreviousNextNavigation(
{super.key, {super.key,
required this.onPreviousPressed, required this.onPreviousPressed,
@ -11,61 +12,89 @@ class PreviousNextNavigation extends StatelessWidget {
required this.child, required this.child,
this.maxWidth = 1000, this.maxWidth = 1000,
this.nextBtnColor, this.nextBtnColor,
this.previousBtnColor}); this.previousBtnColor,
this.listenToMouseWheel = true});
final VoidCallback? onPreviousPressed; final VoidCallback? onPreviousPressed;
final VoidCallback? onNextPressed; final VoidCallback? onNextPressed;
final Color? nextBtnColor; final Color? nextBtnColor;
final Color? previousBtnColor; final Color? previousBtnColor;
final Widget child; final Widget child;
final double? maxWidth; final double? maxWidth;
final bool listenToMouseWheel;
@override
State<PreviousNextNavigation> createState() => _PreviousNextNavigationState();
}
class _PreviousNextNavigationState extends State<PreviousNextNavigation> {
DateTime _lastMouseScrollTime = DateTime.now();
final int _scrollCooldownMs = 300;
bool _handleKeyDown(KeyDownEvent event) { bool _handleKeyDown(KeyDownEvent event) {
if (event.logicalKey == LogicalKeyboardKey.arrowLeft && onPreviousPressed != null) { if (event.logicalKey == LogicalKeyboardKey.arrowLeft && widget.onPreviousPressed != null) {
onPreviousPressed?.call(); widget.onPreviousPressed?.call();
return true; return true;
} }
if (event.logicalKey == LogicalKeyboardKey.arrowRight && onNextPressed != null) { if (event.logicalKey == LogicalKeyboardKey.arrowRight && widget.onNextPressed != null) {
onNextPressed?.call(); widget.onNextPressed?.call();
return true; return true;
} }
return false; return false;
} }
void _handleMouseScroll(event) {
if (event is PointerScrollEvent) {
// Cooldown, ignore scroll events that are too close together
if (DateTime.now().millisecondsSinceEpoch - _lastMouseScrollTime.millisecondsSinceEpoch < _scrollCooldownMs) {
return;
}
_lastMouseScrollTime = DateTime.now();
if (event.scrollDelta.dy > 0 && widget.onPreviousPressed != null) {
widget.onPreviousPressed!();
} else if (event.scrollDelta.dy < 0 && widget.onNextPressed != null) {
widget.onNextPressed!();
}
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (PlatformInfo.isMobile) return child; if (PlatformInfo.isMobile) return widget.child;
return FullscreenKeyboardListener( return Listener(
onKeyDown: _handleKeyDown, onPointerSignal: widget.listenToMouseWheel ? _handleMouseScroll : null,
child: Stack( child: FullscreenKeyboardListener(
children: [ onKeyDown: _handleKeyDown,
child, child: Stack(
Center( children: [
child: SizedBox( widget.child,
width: maxWidth ?? double.infinity, Center(
child: Padding( child: SizedBox(
padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm), width: widget.maxWidth ?? double.infinity,
child: Row( child: Padding(
children: [ padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm),
CircleIconBtn( child: Row(
icon: AppIcons.prev, children: [
onPressed: onPreviousPressed, CircleIconBtn(
semanticLabel: 'Previous', icon: AppIcons.prev,
bgColor: previousBtnColor, onPressed: widget.onPreviousPressed,
), semanticLabel: 'Previous',
Spacer(), bgColor: widget.previousBtnColor,
CircleIconBtn( ),
icon: AppIcons.prev, Spacer(),
onPressed: onNextPressed, CircleIconBtn(
semanticLabel: 'Next', icon: AppIcons.prev,
flipIcon: true, onPressed: widget.onNextPressed,
bgColor: nextBtnColor, semanticLabel: 'Next',
) flipIcon: true,
], bgColor: widget.nextBtnColor,
)
],
),
), ),
), ),
), ),
), ],
], ),
), ),
); );
} }