Fix #1471 Add double tap gesture

This commit is contained in:
Kris Giesing 2015-10-02 18:49:38 -07:00
parent 6fcdb64a1a
commit c9986651f4
5 changed files with 83 additions and 3 deletions

View File

@ -8,6 +8,7 @@ library gestures;
export 'src/gestures/arena.dart';
export 'src/gestures/constants.dart';
export 'src/gestures/drag.dart';
export 'src/gestures/double_tap.dart';
export 'src/gestures/long_press.dart';
export 'src/gestures/pointer_router.dart';
export 'src/gestures/recognizer.dart';

View File

@ -0,0 +1,51 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:sky' as sky;
import 'package:sky/src/gestures/arena.dart';
import 'package:sky/src/gestures/constants.dart';
import 'package:sky/src/gestures/recognizer.dart';
import 'package:sky/src/gestures/tap.dart';
class DoubleTapGestureRecognizer extends PrimaryPointerGestureRecognizer {
DoubleTapGestureRecognizer({ PointerRouter router, this.onDoubleTap })
: super(router: router, deadline: kTapTimeout);
GestureTapListener onDoubleTap;
int _numTaps = 0;
Timer _longTimer;
void resolve(GestureDisposition disposition) {
super.resolve(disposition);
if (disposition == GestureDisposition.rejected) {
_numTaps = 0;
}
}
void didExceedDeadline() {
stopTrackingPointer(primaryPointer);
resolve(GestureDisposition.rejected);
}
void didExceedLongDeadline() {
_numTaps = 0;
_longTimer = null;
}
void handlePrimaryPointer(sky.PointerEvent event) {
if (event.type == 'pointerup') {
_numTaps++;
if (_numTaps == 1) {
_longTimer = new Timer(kDoubleTapTimeout, didExceedLongDeadline);
} else if (_numTaps == 2) {
resolve(GestureDisposition.accepted);
onDoubleTap();
}
}
}
}

View File

@ -99,10 +99,12 @@ abstract class PrimaryPointerGestureRecognizer extends GestureRecognizer {
assert(state != GestureRecognizerState.ready);
if (state == GestureRecognizerState.possible && event.pointer == primaryPointer) {
// TODO(abarth): Maybe factor the slop handling out into a separate class?
if (event.type == 'pointermove' && _getDistance(event) > kTouchSlop)
if (event.type == 'pointermove' && _getDistance(event) > kTouchSlop) {
resolve(GestureDisposition.rejected);
else
stopTrackingPointer(event.pointer);
} else {
handlePrimaryPointer(event);
}
}
stopTrackingIfPointerNoLongerDown(event);
}

View File

@ -5,16 +5,22 @@
import 'dart:sky' as sky;
import 'package:sky/src/gestures/arena.dart';
import 'package:sky/src/gestures/constants.dart';
import 'package:sky/src/gestures/recognizer.dart';
typedef void GestureTapListener();
class TapGestureRecognizer extends PrimaryPointerGestureRecognizer {
TapGestureRecognizer({ PointerRouter router, this.onTap })
: super(router: router);
: super(router: router, deadline: kTapTimeout);
GestureTapListener onTap;
void didExceedDeadline() {
stopTrackingPointer(primaryPointer);
resolve(GestureDisposition.rejected);
}
void handlePrimaryPointer(sky.PointerEvent event) {
if (event.type == 'pointerup') {
resolve(GestureDisposition.accepted);

View File

@ -14,6 +14,7 @@ class GestureDetector extends StatefulComponent {
Key key,
this.child,
this.onTap,
this.onDoubleTap,
this.onShowPress,
this.onLongPress,
this.onVerticalDragStart,
@ -32,6 +33,7 @@ class GestureDetector extends StatefulComponent {
final Widget child;
final GestureTapListener onTap;
final GestureTapListener onDoubleTap;
final GestureShowPressListener onShowPress;
final GestureLongPressListener onLongPress;
@ -69,6 +71,13 @@ class GestureDetectorState extends State<GestureDetector> {
return _tap;
}
DoubleTapGestureRecognizer _doubleTap;
DoubleTapGestureRecognizer _ensureDoubleTap() {
if (_doubleTap == null)
_doubleTap = new DoubleTapGestureRecognizer(router: _router);
return _doubleTap;
}
ShowPressGestureRecognizer _showPress;
ShowPressGestureRecognizer _ensureShowPress() {
if (_showPress == null)
@ -115,6 +124,7 @@ class GestureDetectorState extends State<GestureDetector> {
void dispose() {
_tap = _ensureDisposed(_tap);
_doubleTap = _ensureDisposed(_doubleTap);
_showPress = _ensureDisposed(_showPress);
_longPress = _ensureDisposed(_longPress);
_verticalDrag = _ensureDisposed(_verticalDrag);
@ -126,6 +136,7 @@ class GestureDetectorState extends State<GestureDetector> {
void didUpdateConfig(GestureDetector oldConfig) {
_syncTap();
_syncDoubleTap();
_syncShowPress();
_syncLongPress();
_syncVerticalDrag();
@ -141,6 +152,13 @@ class GestureDetectorState extends State<GestureDetector> {
_ensureTap().onTap = config.onTap;
}
void _syncDoubleTap() {
if (config.onDoubleTap == null)
_doubleTap = _ensureDisposed(_doubleTap);
else
_ensureDoubleTap().onDoubleTap = config.onDoubleTap;
}
void _syncShowPress() {
if (config.onShowPress == null)
_showPress = _ensureDisposed(_showPress);
@ -207,6 +225,8 @@ class GestureDetectorState extends State<GestureDetector> {
void _handlePointerDown(sky.PointerEvent event) {
if (_tap != null)
_tap.addPointer(event);
if (_doubleTap != null)
_doubleTap.addPointer(event);
if (_showPress != null)
_showPress.addPointer(event);
if (_longPress != null)