Commit c9986651 authored by Kris Giesing's avatar Kris Giesing

Fix #1471 Add double tap gesture

parent 6fcdb64a
...@@ -8,6 +8,7 @@ library gestures; ...@@ -8,6 +8,7 @@ library gestures;
export 'src/gestures/arena.dart'; export 'src/gestures/arena.dart';
export 'src/gestures/constants.dart'; export 'src/gestures/constants.dart';
export 'src/gestures/drag.dart'; export 'src/gestures/drag.dart';
export 'src/gestures/double_tap.dart';
export 'src/gestures/long_press.dart'; export 'src/gestures/long_press.dart';
export 'src/gestures/pointer_router.dart'; export 'src/gestures/pointer_router.dart';
export 'src/gestures/recognizer.dart'; export 'src/gestures/recognizer.dart';
......
// 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();
}
}
}
}
...@@ -99,11 +99,13 @@ abstract class PrimaryPointerGestureRecognizer extends GestureRecognizer { ...@@ -99,11 +99,13 @@ abstract class PrimaryPointerGestureRecognizer extends GestureRecognizer {
assert(state != GestureRecognizerState.ready); assert(state != GestureRecognizerState.ready);
if (state == GestureRecognizerState.possible && event.pointer == primaryPointer) { if (state == GestureRecognizerState.possible && event.pointer == primaryPointer) {
// TODO(abarth): Maybe factor the slop handling out into a separate class? // 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); resolve(GestureDisposition.rejected);
else stopTrackingPointer(event.pointer);
} else {
handlePrimaryPointer(event); handlePrimaryPointer(event);
} }
}
stopTrackingIfPointerNoLongerDown(event); stopTrackingIfPointerNoLongerDown(event);
} }
......
...@@ -5,16 +5,22 @@ ...@@ -5,16 +5,22 @@
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/recognizer.dart'; import 'package:sky/src/gestures/recognizer.dart';
typedef void GestureTapListener(); typedef void GestureTapListener();
class TapGestureRecognizer extends PrimaryPointerGestureRecognizer { class TapGestureRecognizer extends PrimaryPointerGestureRecognizer {
TapGestureRecognizer({ PointerRouter router, this.onTap }) TapGestureRecognizer({ PointerRouter router, this.onTap })
: super(router: router); : super(router: router, deadline: kTapTimeout);
GestureTapListener onTap; GestureTapListener onTap;
void didExceedDeadline() {
stopTrackingPointer(primaryPointer);
resolve(GestureDisposition.rejected);
}
void handlePrimaryPointer(sky.PointerEvent event) { void handlePrimaryPointer(sky.PointerEvent event) {
if (event.type == 'pointerup') { if (event.type == 'pointerup') {
resolve(GestureDisposition.accepted); resolve(GestureDisposition.accepted);
......
...@@ -14,6 +14,7 @@ class GestureDetector extends StatefulComponent { ...@@ -14,6 +14,7 @@ class GestureDetector extends StatefulComponent {
Key key, Key key,
this.child, this.child,
this.onTap, this.onTap,
this.onDoubleTap,
this.onShowPress, this.onShowPress,
this.onLongPress, this.onLongPress,
this.onVerticalDragStart, this.onVerticalDragStart,
...@@ -32,6 +33,7 @@ class GestureDetector extends StatefulComponent { ...@@ -32,6 +33,7 @@ class GestureDetector extends StatefulComponent {
final Widget child; final Widget child;
final GestureTapListener onTap; final GestureTapListener onTap;
final GestureTapListener onDoubleTap;
final GestureShowPressListener onShowPress; final GestureShowPressListener onShowPress;
final GestureLongPressListener onLongPress; final GestureLongPressListener onLongPress;
...@@ -69,6 +71,13 @@ class GestureDetectorState extends State<GestureDetector> { ...@@ -69,6 +71,13 @@ class GestureDetectorState extends State<GestureDetector> {
return _tap; return _tap;
} }
DoubleTapGestureRecognizer _doubleTap;
DoubleTapGestureRecognizer _ensureDoubleTap() {
if (_doubleTap == null)
_doubleTap = new DoubleTapGestureRecognizer(router: _router);
return _doubleTap;
}
ShowPressGestureRecognizer _showPress; ShowPressGestureRecognizer _showPress;
ShowPressGestureRecognizer _ensureShowPress() { ShowPressGestureRecognizer _ensureShowPress() {
if (_showPress == null) if (_showPress == null)
...@@ -115,6 +124,7 @@ class GestureDetectorState extends State<GestureDetector> { ...@@ -115,6 +124,7 @@ class GestureDetectorState extends State<GestureDetector> {
void dispose() { void dispose() {
_tap = _ensureDisposed(_tap); _tap = _ensureDisposed(_tap);
_doubleTap = _ensureDisposed(_doubleTap);
_showPress = _ensureDisposed(_showPress); _showPress = _ensureDisposed(_showPress);
_longPress = _ensureDisposed(_longPress); _longPress = _ensureDisposed(_longPress);
_verticalDrag = _ensureDisposed(_verticalDrag); _verticalDrag = _ensureDisposed(_verticalDrag);
...@@ -126,6 +136,7 @@ class GestureDetectorState extends State<GestureDetector> { ...@@ -126,6 +136,7 @@ class GestureDetectorState extends State<GestureDetector> {
void didUpdateConfig(GestureDetector oldConfig) { void didUpdateConfig(GestureDetector oldConfig) {
_syncTap(); _syncTap();
_syncDoubleTap();
_syncShowPress(); _syncShowPress();
_syncLongPress(); _syncLongPress();
_syncVerticalDrag(); _syncVerticalDrag();
...@@ -141,6 +152,13 @@ class GestureDetectorState extends State<GestureDetector> { ...@@ -141,6 +152,13 @@ class GestureDetectorState extends State<GestureDetector> {
_ensureTap().onTap = config.onTap; _ensureTap().onTap = config.onTap;
} }
void _syncDoubleTap() {
if (config.onDoubleTap == null)
_doubleTap = _ensureDisposed(_doubleTap);
else
_ensureDoubleTap().onDoubleTap = config.onDoubleTap;
}
void _syncShowPress() { void _syncShowPress() {
if (config.onShowPress == null) if (config.onShowPress == null)
_showPress = _ensureDisposed(_showPress); _showPress = _ensureDisposed(_showPress);
...@@ -207,6 +225,8 @@ class GestureDetectorState extends State<GestureDetector> { ...@@ -207,6 +225,8 @@ class GestureDetectorState extends State<GestureDetector> {
void _handlePointerDown(sky.PointerEvent event) { void _handlePointerDown(sky.PointerEvent event) {
if (_tap != null) if (_tap != null)
_tap.addPointer(event); _tap.addPointer(event);
if (_doubleTap != null)
_doubleTap.addPointer(event);
if (_showPress != null) if (_showPress != null)
_showPress.addPointer(event); _showPress.addPointer(event);
if (_longPress != null) if (_longPress != null)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment