Fix #1471 Add double tap gesture
This commit is contained in:
parent
6fcdb64a1a
commit
c9986651f4
@ -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';
|
||||||
|
51
packages/flutter/lib/src/gestures/double_tap.dart
Normal file
51
packages/flutter/lib/src/gestures/double_tap.dart
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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 @@
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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> {
|
|||||||
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> {
|
|||||||
|
|
||||||
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> {
|
|||||||
|
|
||||||
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> {
|
|||||||
_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> {
|
|||||||
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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user