Temporary holding commit
This commit is contained in:
parent
79c88b4d7c
commit
cc201f3293
@ -10,42 +10,150 @@ import 'package:sky/src/gestures/constants.dart';
|
|||||||
import 'package:sky/src/gestures/recognizer.dart';
|
import 'package:sky/src/gestures/recognizer.dart';
|
||||||
import 'package:sky/src/gestures/tap.dart';
|
import 'package:sky/src/gestures/tap.dart';
|
||||||
|
|
||||||
class DoubleTapGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
class DoubleTapGestureRecognizer extends GestureArenaMember {
|
||||||
DoubleTapGestureRecognizer({ PointerRouter router, this.onDoubleTap })
|
static int sInstances = 0;
|
||||||
: super(router: router, deadline: kTapTimeout);
|
|
||||||
|
|
||||||
|
DoubleTapGestureRecognizer({ this.router, this.onDoubleTap }) {
|
||||||
|
_instance = sInstances++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PointerRouter router;
|
||||||
GestureTapListener onDoubleTap;
|
GestureTapListener onDoubleTap;
|
||||||
|
|
||||||
int _numTaps = 0;
|
int _numTaps = 0;
|
||||||
Timer _longTimer;
|
int _instance = 0;
|
||||||
|
bool _isTrackingPointer = false;
|
||||||
|
int _pointer;
|
||||||
|
sky.Point _initialPosition;
|
||||||
|
Timer _tapTimer;
|
||||||
|
Timer _doubleTapTimer;
|
||||||
|
GestureArenaEntry _entry = null;
|
||||||
|
|
||||||
void resolve(GestureDisposition disposition) {
|
void addPointer(sky.PointerEvent event) {
|
||||||
super.resolve(disposition);
|
message("add pointer");
|
||||||
if (disposition == GestureDisposition.rejected) {
|
if (_initialPosition != null && !_isWithinTolerance(event)) {
|
||||||
_numTaps = 0;
|
message("reset");
|
||||||
|
_reset();
|
||||||
|
}
|
||||||
|
_pointer = event.pointer;
|
||||||
|
_initialPosition = _getPoint(event);
|
||||||
|
_isTrackingPointer = false;
|
||||||
|
_startTapTimer();
|
||||||
|
_stopDoubleTapTimer();
|
||||||
|
_startTrackingPointer();
|
||||||
|
if (_entry == null) {
|
||||||
|
message("register entry");
|
||||||
|
_entry = GestureArena.instance.add(event.pointer, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void didExceedDeadline() {
|
void message(String s) {
|
||||||
stopTrackingPointer(primaryPointer);
|
print("Double tap " + _instance.toString() + ": " + s);
|
||||||
resolve(GestureDisposition.rejected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void didExceedLongDeadline() {
|
void handleEvent(sky.PointerEvent event) {
|
||||||
_numTaps = 0;
|
message("handle event");
|
||||||
_longTimer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handlePrimaryPointer(sky.PointerEvent event) {
|
|
||||||
if (event.type == 'pointerup') {
|
if (event.type == 'pointerup') {
|
||||||
_numTaps++;
|
_numTaps++;
|
||||||
|
_stopTapTimer();
|
||||||
|
_stopTrackingPointer();
|
||||||
if (_numTaps == 1) {
|
if (_numTaps == 1) {
|
||||||
_longTimer = new Timer(kDoubleTapTimeout, didExceedLongDeadline);
|
message("start long timer");
|
||||||
|
_startDoubleTapTimer();
|
||||||
} else if (_numTaps == 2) {
|
} else if (_numTaps == 2) {
|
||||||
resolve(GestureDisposition.accepted);
|
message("start found second tap");
|
||||||
onDoubleTap();
|
_entry.resolve(GestureDisposition.accepted);
|
||||||
}
|
}
|
||||||
|
} else if (event.type == 'pointermove' && !_isWithinTolerance(event)) {
|
||||||
|
message("outside tap tolerance");
|
||||||
|
_entry.resolve(GestureDisposition.rejected);
|
||||||
|
} else if (event.type == 'pointercancel') {
|
||||||
|
message("cancel");
|
||||||
|
_entry.resolve(GestureDisposition.rejected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void acceptGesture(int pointer) {
|
||||||
|
message("accepted");
|
||||||
|
_reset();
|
||||||
|
_entry = null;
|
||||||
|
print ("Entry is assigned null");
|
||||||
|
onDoubleTap?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rejectGesture(int pointer) {
|
||||||
|
message("rejected");
|
||||||
|
_reset();
|
||||||
|
_entry = null;
|
||||||
|
print ("Entry is assigned null");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
_entry?.resolve(GestureDisposition.rejected);
|
||||||
|
router = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _reset() {
|
||||||
|
_numTaps = 0;
|
||||||
|
_initialPosition = null;
|
||||||
|
_stopTapTimer();
|
||||||
|
_stopDoubleTapTimer();
|
||||||
|
_stopTrackingPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startTapTimer() {
|
||||||
|
if (_tapTimer == null) {
|
||||||
|
_tapTimer = new Timer(
|
||||||
|
kTapTimeout,
|
||||||
|
() => _entry.resolve(GestureDisposition.rejected)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stopTapTimer() {
|
||||||
|
if (_tapTimer != null) {
|
||||||
|
_tapTimer.cancel();
|
||||||
|
_tapTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startDoubleTapTimer() {
|
||||||
|
if (_doubleTapTimer == null) {
|
||||||
|
_doubleTapTimer = new Timer(
|
||||||
|
kDoubleTapTimeout,
|
||||||
|
() => _entry.resolve(GestureDisposition.rejected)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stopDoubleTapTimer() {
|
||||||
|
if (_doubleTapTimer != null) {
|
||||||
|
_doubleTapTimer.cancel();
|
||||||
|
_doubleTapTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startTrackingPointer() {
|
||||||
|
if (!_isTrackingPointer) {
|
||||||
|
_isTrackingPointer = true;
|
||||||
|
router.addRoute(_pointer, handleEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stopTrackingPointer() {
|
||||||
|
if (_isTrackingPointer) {
|
||||||
|
_isTrackingPointer = false;
|
||||||
|
router.removeRoute(_pointer, handleEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sky.Point _getPoint(sky.PointerEvent event) {
|
||||||
|
return new sky.Point(event.x, event.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isWithinTolerance(sky.PointerEvent event) {
|
||||||
|
sky.Offset offset = _getPoint(event) - _initialPosition;
|
||||||
|
return offset.distance <= kDoubleTapTouchSlop;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,44 +2,161 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:sky' as sky;
|
import 'dart:sky' as sky;
|
||||||
|
|
||||||
import 'package:sky/src/gestures/arena.dart';
|
import 'package:sky/src/gestures/arena.dart';
|
||||||
import 'package:sky/src/gestures/constants.dart';
|
import 'package:sky/src/gestures/constants.dart';
|
||||||
import 'package:sky/src/gestures/recognizer.dart';
|
|
||||||
|
|
||||||
typedef void GestureTapCallback();
|
typedef void GestureTapCallback();
|
||||||
|
|
||||||
class TapGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
enum TapResolution {
|
||||||
TapGestureRecognizer({ PointerRouter router, this.onTap })
|
tap,
|
||||||
: super(router: router, deadline: kTapTimeout);
|
cancel
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TapGesture {
|
||||||
|
_TapGesture({ this.gestureRecognizer, sky.PointerEvent event }) {
|
||||||
|
assert(event.type == 'pointerdown');
|
||||||
|
_pointer = event.pointer;
|
||||||
|
_isTrackingPointer = false;
|
||||||
|
_initialPosition = _getPoint(event);
|
||||||
|
_entry = GestureArena.instance.add(_pointer, gestureRecognizer);
|
||||||
|
_wonArena = false;
|
||||||
|
_didTap = false;
|
||||||
|
_startTimer();
|
||||||
|
_startTrackingPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
TapGestureRecognizer gestureRecognizer;
|
||||||
|
|
||||||
|
int _pointer;
|
||||||
|
bool _isTrackingPointer;
|
||||||
|
sky.Point _initialPosition;
|
||||||
|
GestureArenaEntry _entry;
|
||||||
|
Timer _deadline;
|
||||||
|
bool _wonArena;
|
||||||
|
bool _didTap;
|
||||||
|
|
||||||
|
void handleEvent(sky.PointerEvent event) {
|
||||||
|
print("Tap gesture handleEvent");
|
||||||
|
assert(event.pointer == _pointer);
|
||||||
|
if (event.type == 'pointermove' && !_isWithinTolerance(event)) {
|
||||||
|
_entry.resolve(GestureDisposition.rejected);
|
||||||
|
} else if (event.type == 'pointercancel') {
|
||||||
|
_entry.resolve(GestureDisposition.rejected);
|
||||||
|
} else if (event.type == 'pointerup') {
|
||||||
|
_stopTimer();
|
||||||
|
_stopTrackingPointer();
|
||||||
|
_didTap = true;
|
||||||
|
_check();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void accept() {
|
||||||
|
print("Tap gesture accept");
|
||||||
|
_wonArena = true;
|
||||||
|
_check();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reject() {
|
||||||
|
print("Tap gesture reject");
|
||||||
|
_stopTimer();
|
||||||
|
_stopTrackingPointer();
|
||||||
|
gestureRecognizer._resolveTap(_pointer, TapResolution.cancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void abort() {
|
||||||
|
_entry.resolve(GestureDisposition.rejected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _check() {
|
||||||
|
if (_wonArena && _didTap)
|
||||||
|
gestureRecognizer._resolveTap(_pointer, TapResolution.tap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startTimer() {
|
||||||
|
if (_deadline == null) {
|
||||||
|
_deadline = new Timer(
|
||||||
|
kTapTimeout,
|
||||||
|
() => _entry.resolve(GestureDisposition.rejected)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stopTimer() {
|
||||||
|
if (_deadline != null) {
|
||||||
|
_deadline.cancel();
|
||||||
|
_deadline = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startTrackingPointer() {
|
||||||
|
if (!_isTrackingPointer) {
|
||||||
|
_isTrackingPointer = true;
|
||||||
|
gestureRecognizer.router.addRoute(_pointer, handleEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stopTrackingPointer() {
|
||||||
|
if (_isTrackingPointer) {
|
||||||
|
_isTrackingPointer = false;
|
||||||
|
gestureRecognizer.router.removeRoute(_pointer, handleEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sky.Point _getPoint(sky.PointerEvent event) {
|
||||||
|
return new sky.Point(event.x, event.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isWithinTolerance(sky.PointerEvent event) {
|
||||||
|
sky.Offset offset = _getPoint(event) - _initialPosition;
|
||||||
|
return offset.distance <= kTouchSlop;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class TapGestureRecognizer extends GestureArenaMember {
|
||||||
|
TapGestureRecognizer({ this.router, this.onTap, this.onTapDown, this.onTapCancel });
|
||||||
|
|
||||||
|
PointerRouter router;
|
||||||
GestureTapCallback onTap;
|
GestureTapCallback onTap;
|
||||||
GestureTapCallback onTapDown;
|
GestureTapCallback onTapDown;
|
||||||
GestureTapCallback onTapCancel;
|
GestureTapCallback onTapCancel;
|
||||||
|
|
||||||
void didExceedDeadline() {
|
Map<int, _TapGesture> _gestureMap = new Map<int, _TapGesture>();
|
||||||
stopTrackingPointer(primaryPointer);
|
|
||||||
resolve(GestureDisposition.rejected);
|
void addPointer(sky.PointerEvent event) {
|
||||||
|
_gestureMap[event.pointer] = new _TapGesture(
|
||||||
|
gestureRecognizer: this,
|
||||||
|
event: event
|
||||||
|
);
|
||||||
|
onTapDown?.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlePrimaryPointer(sky.PointerEvent event) {
|
void acceptGesture(int pointer) {
|
||||||
if (event.type == 'pointerdown') {
|
_gestureMap[pointer]?.accept();
|
||||||
if (onTapDown != null)
|
|
||||||
onTapDown();
|
|
||||||
} else if (event.type == 'pointerup') {
|
|
||||||
resolve(GestureDisposition.accepted);
|
|
||||||
if (onTap != null)
|
|
||||||
onTap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rejectGesture(int pointer) {
|
void rejectGesture(int pointer) {
|
||||||
super.rejectGesture(pointer);
|
_gestureMap[pointer]?.reject();
|
||||||
if (pointer == primaryPointer) {
|
|
||||||
assert(state == GestureRecognizerState.defunct);
|
|
||||||
if (onTapCancel != null)
|
|
||||||
onTapCancel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _resolveTap(int pointer, TapResolution resolution) {
|
||||||
|
_gestureMap.remove(pointer);
|
||||||
|
if (resolution == TapResolution.tap)
|
||||||
|
onTap?.call();
|
||||||
|
else
|
||||||
|
onTapCancel?.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
List<_TapGesture> localGestures = new List.from(_gestureMap.values);
|
||||||
|
for (_TapGesture gesture in localGestures)
|
||||||
|
entry.abort();
|
||||||
|
// Rejection of each gesture should cause it to be removed from our map
|
||||||
|
assert(_gestureMap.isEmpty);
|
||||||
|
router = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -119,10 +119,12 @@ class _GestureDetectorState extends State<GestureDetector> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _syncDoubleTap() {
|
void _syncDoubleTap() {
|
||||||
if (config.onDoubleTap == null)
|
if (config.onDoubleTap == null) {
|
||||||
_doubleTap = _ensureDisposed(_doubleTap);
|
_doubleTap = _ensureDisposed(_doubleTap);
|
||||||
else
|
} else {
|
||||||
_ensureDoubleTap().onDoubleTap = config.onDoubleTap;
|
_doubleTap = new DoubleTapGestureRecognizer(router: _router);
|
||||||
|
_doubleTap.onDoubleTap = config.onDoubleTap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _syncShowPress() {
|
void _syncShowPress() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user