diff --git a/examples/game/lib/main.dart b/examples/game/lib/main.dart index cdf38ed5b8f..5f8ff5abab9 100644 --- a/examples/game/lib/main.dart +++ b/examples/game/lib/main.dart @@ -169,7 +169,7 @@ class TextureButtonState extends State { ) ) ), - onTapDown: () { + onTapDown: (_) { setState(() { _highlight = true; }); diff --git a/sky/packages/sky/lib/src/gestures/tap.dart b/sky/packages/sky/lib/src/gestures/tap.dart index 56a8add85e1..b82c2a2eef8 100644 --- a/sky/packages/sky/lib/src/gestures/tap.dart +++ b/sky/packages/sky/lib/src/gestures/tap.dart @@ -11,28 +11,37 @@ import 'events.dart'; import 'pointer_router.dart'; import 'recognizer.dart'; +typedef void GestureTapDownCallback(ui.Point globalPosition); +typedef void GestureTapUpCallback(ui.Point globalPosition); typedef void GestureTapCallback(); +typedef void GestureTapCancelCallback(); /// TapGestureRecognizer is a tap recognizer that tracks only one primary /// pointer per gesture. That is, during tap recognition, extra pointer events /// are ignored: down-1, down-2, up-1, up-2 produces only one tap on up-1. class TapGestureRecognizer extends PrimaryPointerGestureRecognizer { - TapGestureRecognizer({ PointerRouter router, this.onTap }) - : super(router: router); + TapGestureRecognizer({ + PointerRouter router, + this.onTapDown, + this.onTapUp, + this.onTap, + this.onTapCancel + }) : super(router: router); + GestureTapDownCallback onTapDown; + GestureTapDownCallback onTapUp; GestureTapCallback onTap; - GestureTapCallback onTapDown; - GestureTapCallback onTapCancel; + GestureTapCancelCallback onTapCancel; bool _wonArena = false; - bool _didTap = false; + Point _finalPosition; void handlePrimaryPointer(PointerInputEvent event) { if (event.type == 'pointerdown') { if (onTapDown != null) - onTapDown(); + onTapDown(event.position); } else if (event.type == 'pointerup') { - _didTap = true; + _finalPosition = event.position; _check(); } } @@ -50,15 +59,17 @@ class TapGestureRecognizer extends PrimaryPointerGestureRecognizer { if (pointer == primaryPointer) { assert(state == GestureRecognizerState.defunct); _wonArena = false; - _didTap = false; + _finalPosition = null; if (onTapCancel != null) onTapCancel(); } } void _check() { - if (_wonArena && _didTap) { + if (_wonArena && _finalPosition != null) { resolve(GestureDisposition.accepted); + if (onTapUp != null) + onTapUp(_finalPosition); if (onTap != null) onTap(); } @@ -76,7 +87,7 @@ class _TapTracker { assert(event.type == 'pointerdown'); } - int pointer; + final int pointer; GestureArenaEntry entry; ui.Point _initialPosition; bool _isTrackingPointer; @@ -102,7 +113,7 @@ class _TapTracker { } -enum TapResolution { +enum _TapResolution { tap, cancel } @@ -113,17 +124,15 @@ enum TapResolution { class _TapGesture extends _TapTracker { _TapGesture({ this.gestureRecognizer, PointerInputEvent event }) - : super(event: event) { + : super(event: event) { entry = GestureArena.instance.add(event.pointer, gestureRecognizer); - _wonArena = false; - _didTap = false; startTrackingPointer(gestureRecognizer.router, handleEvent); } - MultiTapGestureRecognizer gestureRecognizer; + final MultiTapGestureRecognizer gestureRecognizer; - bool _wonArena; - bool _didTap; + bool _wonArena = false; + ui.Point _finalPosition; void handleEvent(PointerInputEvent event) { assert(event.pointer == pointer); @@ -133,7 +142,7 @@ class _TapGesture extends _TapTracker { cancel(); } else if (event.type == 'pointerup') { stopTrackingPointer(gestureRecognizer.router, handleEvent); - _didTap = true; + _finalPosition = event.position; _check(); } } @@ -145,7 +154,7 @@ class _TapGesture extends _TapTracker { void reject() { stopTrackingPointer(gestureRecognizer.router, handleEvent); - gestureRecognizer._resolveTap(pointer, TapResolution.cancel); + gestureRecognizer._resolveTap(pointer, _TapResolution.cancel, null); } void cancel() { @@ -158,8 +167,8 @@ class _TapGesture extends _TapTracker { } void _check() { - if (_wonArena && _didTap) - gestureRecognizer._resolveTap(pointer, TapResolution.tap); + if (_wonArena && _finalPosition != null) + gestureRecognizer._resolveTap(pointer, _TapResolution.tap, _finalPosition); } } @@ -169,12 +178,19 @@ class _TapGesture extends _TapTracker { /// does so independently of others: down-1, down-2, up-1, up-2 produces two /// taps, on up-1 and up-2. class MultiTapGestureRecognizer extends DisposableArenaMember { - MultiTapGestureRecognizer({ this.router, this.onTap, this.onTapDown, this.onTapCancel }); + MultiTapGestureRecognizer({ + this.router, + this.onTapDown, + this.onTapUp, + this.onTap, + this.onTapCancel + }); PointerRouter router; + GestureTapDownCallback onTapDown; + GestureTapDownCallback onTapUp; GestureTapCallback onTap; - GestureTapCallback onTapDown; - GestureTapCallback onTapCancel; + GestureTapCancelCallback onTapCancel; Map _gestureMap = new Map(); @@ -185,7 +201,7 @@ class MultiTapGestureRecognizer extends DisposableArenaMember { event: event ); if (onTapDown != null) - onTapDown(); + onTapDown(event.position); } void acceptGesture(int pointer) { @@ -198,9 +214,11 @@ class MultiTapGestureRecognizer extends DisposableArenaMember { _gestureMap[pointer]?.reject(); } - void _resolveTap(int pointer, TapResolution resolution) { + void _resolveTap(int pointer, _TapResolution resolution, ui.Point globalPosition) { _gestureMap.remove(pointer); - if (resolution == TapResolution.tap) { + if (resolution == _TapResolution.tap) { + if (onTapUp != null) + onTapUp(globalPosition); if (onTap != null) onTap(); } else { diff --git a/sky/packages/sky/lib/src/material/ink_well.dart b/sky/packages/sky/lib/src/material/ink_well.dart index 1b929c3192e..0d50e1b5987 100644 --- a/sky/packages/sky/lib/src/material/ink_well.dart +++ b/sky/packages/sky/lib/src/material/ink_well.dart @@ -41,7 +41,7 @@ class InkWell extends StatefulComponent { final _HighlightChangedCallback onHighlightChanged; final Color defaultColor; final Color highlightColor; - + _InkWellState createState() => new _InkWellState(); } @@ -237,7 +237,7 @@ class _RenderInkSplashes extends RenderProxyBox { _longPress = null; } - void _handleTapDown() { + void _handleTapDown(_) { if (onHighlightChanged != null) onHighlightChanged(true); } diff --git a/sky/packages/sky/lib/src/widgets/gesture_detector.dart b/sky/packages/sky/lib/src/widgets/gesture_detector.dart index 7ab716a0d27..5ac26e579ab 100644 --- a/sky/packages/sky/lib/src/widgets/gesture_detector.dart +++ b/sky/packages/sky/lib/src/widgets/gesture_detector.dart @@ -9,9 +9,10 @@ import 'basic.dart'; import 'framework.dart'; export 'package:flutter/gestures.dart' show + GestureTapDownCallback, + GestureTapUpCallback, GestureTapCallback, - GestureTapCallback, - GestureTapCallback, + GestureTapCancelCallback, GestureShowPressCallback, GestureLongPressCallback, GestureDragStartCallback, @@ -31,10 +32,11 @@ class GestureDetector extends StatefulComponent { const GestureDetector({ Key key, this.child, - this.onTap, - this.onDoubleTap, this.onTapDown, + this.onTapUp, + this.onTap, this.onTapCancel, + this.onDoubleTap, this.onShowPress, this.onLongPress, this.onVerticalDragStart, @@ -53,9 +55,10 @@ class GestureDetector extends StatefulComponent { final Widget child; + final GestureTapDownCallback onTapDown; + final GestureTapDownCallback onTapUp; final GestureTapCallback onTap; - final GestureTapCallback onTapDown; - final GestureTapCallback onTapCancel; + final GestureTapCancelCallback onTapCancel; final GestureTapCallback onDoubleTap; final GestureShowPressCallback onShowPress; @@ -125,13 +128,14 @@ class _GestureDetectorState extends State { } void _syncTap() { - if (config.onTap == null && config.onTapDown == null && config.onTapCancel == null) { + if (config.onTapDown == null && config.onTapUp == null && config.onTap == null && config.onTapCancel == null) { _tap = _ensureDisposed(_tap); } else { _tap ??= new TapGestureRecognizer(router: _router); _tap - ..onTap = config.onTap ..onTapDown = config.onTapDown + ..onTapUp = config.onTapUp + ..onTap = config.onTap ..onTapCancel = config.onTapCancel; } } diff --git a/sky/tools/skyanalyzer b/sky/tools/skyanalyzer index 57048edcd3b..6d781dcfb6c 100755 --- a/sky/tools/skyanalyzer +++ b/sky/tools/skyanalyzer @@ -43,7 +43,7 @@ _IGNORED_PATTERNS = [ # Bogus hint - https://github.com/dart-lang/sdk/issues/24710 re.compile(r'^\[hint\] \(toText == toPlainText\) \? toStyledText : toPlainText has inferred type \(String, String\) → Widget \(.+styled_text.dart,.+\)'), - re.compile(r'^\[hint\] .+ \? \([_, ]+\) {.+} : null has inferred type .+'), # + re.compile(r'^\[hint\] .+ [?:] \([_, ]+\) .+ has inferred type .+'), # # Disable the lint checks that will be caught by code review re.compile(r'^\[lint\] Avoid defining a one-member abstract class when a simple function will do'),