From a8934b77a7cfa3ac2cd20de2bb3107267712dd69 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Tue, 8 Aug 2023 00:37:44 +0700 Subject: [PATCH] InputOverlay --- CHANGELOG.md | 1 + lib/src/ui.dart | 1 + lib/src/ui/overlay/input_overlay.dart | 77 +++++++++++++++++++ lib/src/ui/overlay/square_number_overlay.dart | 6 +- 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 lib/src/ui/overlay/input_overlay.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index b15a747..20bae72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - `BoardBuilder` now takes a parameter `forceSquareAlignment`, which defaults to true, and forces elements to be aligned to their squares (previously this was not the case). - `SquareBuilder` functions (such as those used by `BoardBuilder`) now return `Widget?`, i.e. they can return null. `BoardBuilder` will build an empty container in this case. - `BoardBuilder.index()`: a `BoardBuilder` that uses an index, rather than rank and file. +- `InputOverlay`: an easy way to support common gestures like right clicks and long presses. - `SquareNumberOverlay`: an overlay for debugging that shows the square index. - `LabelConfig` is now exported correctly with the rest of the package. diff --git a/lib/src/ui.dart b/lib/src/ui.dart index 6a38dad..aef61b4 100644 --- a/lib/src/ui.dart +++ b/lib/src/ui.dart @@ -4,6 +4,7 @@ export 'ui/board_controller.dart'; export 'ui/hand.dart'; export 'ui/move_animation.dart'; export 'ui/overlay/board_overlay.dart'; +export 'ui/overlay/input_overlay.dart'; export 'ui/overlay/label_overlay.dart'; export 'ui/overlay/square_number_overlay.dart'; export 'ui/piece.dart'; diff --git a/lib/src/ui/overlay/input_overlay.dart b/lib/src/ui/overlay/input_overlay.dart new file mode 100644 index 0000000..ffd0f00 --- /dev/null +++ b/lib/src/ui/overlay/input_overlay.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:squares/squares.dart'; + +/// Builds `GestureDetector`s for each square on the board, handling some +/// common gestures such as right clicks, long presses etc. Doesn't include +/// everything that `GestureDetector` supports because it has literally 60+ +/// parameters. It's easy enough to add more if you need them, and if you think +/// one is a common enough use case, feel free to make a PR. +/// +/// Note that this can't support `onTap` because it will interfere with the +/// standard piece drag behaviour. Also note that gestures like long press +/// will make tap responses on the pieces and squares take longer to respond +/// as the gestures have to go through this first. +class InputOverlay extends StatelessWidget { + /// The orientation that the board is being viewed from. + final int orientation; + final BoardSize size; + final void Function(int i)? onSecondaryTap; + final void Function(int i, TapDownDetails details)? onSecondaryTapDown; + final void Function(int i, TapUpDetails details)? onSecondaryTapUp; + final void Function(int i)? onSecondaryTapCancel; + final void Function(int i)? onLongPress; + final void Function(int i, LongPressStartDetails details)? onLongPressStart; + final void Function(int i, LongPressMoveUpdateDetails details)? + onLongPressMoveUpdate; + final void Function(int i, LongPressEndDetails details)? onLongPressEnd; + final void Function(int i)? onLongPressUp; + final void Function(int i)? onDoubleTap; + + const InputOverlay({ + super.key, + required this.orientation, + this.size = BoardSize.standard, + this.onSecondaryTap, + this.onSecondaryTapDown, + this.onSecondaryTapUp, + this.onSecondaryTapCancel, + this.onLongPress, + this.onLongPressStart, + this.onLongPressMoveUpdate, + this.onLongPressEnd, + this.onLongPressUp, + this.onDoubleTap, + }); + + @override + Widget build(BuildContext context) { + return BoardBuilder.index( + size: size, + orientation: orientation, + builder: (i, _) => GestureDetector( + onSecondaryTap: + onSecondaryTap == null ? null : () => onSecondaryTap!(i), + onSecondaryTapDown: onSecondaryTapDown == null + ? null + : (det) => onSecondaryTapDown!(i, det), + onSecondaryTapUp: onSecondaryTapUp == null + ? null + : (det) => onSecondaryTapUp!(i, det), + onSecondaryTapCancel: onSecondaryTapCancel == null + ? null + : () => onSecondaryTapCancel!(i), + onLongPress: onLongPress == null ? null : () => onLongPress!(i), + onLongPressStart: onLongPressStart == null + ? null + : (det) => onLongPressStart!(i, det), + onLongPressMoveUpdate: onLongPressMoveUpdate == null + ? null + : (det) => onLongPressMoveUpdate!(i, det), + onLongPressEnd: + onLongPressEnd == null ? null : (det) => onLongPressEnd!(i, det), + onLongPressUp: onLongPressUp == null ? null : () => onLongPressUp!(i), + onDoubleTap: onDoubleTap == null ? null : () => onDoubleTap!(i), + ), + ); + } +} diff --git a/lib/src/ui/overlay/square_number_overlay.dart b/lib/src/ui/overlay/square_number_overlay.dart index d5b077a..50042a3 100644 --- a/lib/src/ui/overlay/square_number_overlay.dart +++ b/lib/src/ui/overlay/square_number_overlay.dart @@ -7,6 +7,8 @@ class SquareNumberOverlay extends StatelessWidget { /// Required because this is a debugging tool and I want to help you :) final int orientation; + final BoardSize size; + /// Style of the number text. final TextStyle? textStyle; @@ -19,6 +21,7 @@ class SquareNumberOverlay extends StatelessWidget { const SquareNumberOverlay({ super.key, required this.orientation, + this.size = BoardSize.standard, this.textStyle, this.showCircle = true, this.circleColour, @@ -27,6 +30,8 @@ class SquareNumberOverlay extends StatelessWidget { @override Widget build(BuildContext context) { return BoardBuilder.index( + orientation: orientation, + size: size, builder: (i, size) => Padding( padding: EdgeInsets.all(size / 4), child: Container( @@ -40,7 +45,6 @@ class SquareNumberOverlay extends StatelessWidget { child: FittedBox(child: Center(child: Text('$i', style: textStyle))), ), ), - orientation: orientation, ); } }