Add onTertiaryTap* to TapGestureRecognizer and GestureDetector (#62788)
This commit is contained in:
parent
4aed976812
commit
96b6aafb49
@ -23,6 +23,8 @@ export 'dart:ui' show Offset, PointerDeviceKind;
|
|||||||
///
|
///
|
||||||
/// * [kSecondaryButton], which describes a cross-device behavior of
|
/// * [kSecondaryButton], which describes a cross-device behavior of
|
||||||
/// "secondary operation".
|
/// "secondary operation".
|
||||||
|
/// * [kTertiaryButton], which describes a cross-device behavior of
|
||||||
|
/// "tertiary operation".
|
||||||
const int kPrimaryButton = 0x01;
|
const int kPrimaryButton = 0x01;
|
||||||
|
|
||||||
/// The bit of [PointerEvent.buttons] that corresponds to a cross-device
|
/// The bit of [PointerEvent.buttons] that corresponds to a cross-device
|
||||||
@ -37,6 +39,8 @@ const int kPrimaryButton = 0x01;
|
|||||||
///
|
///
|
||||||
/// * [kPrimaryButton], which describes a cross-device behavior of
|
/// * [kPrimaryButton], which describes a cross-device behavior of
|
||||||
/// "primary operation".
|
/// "primary operation".
|
||||||
|
/// * [kTertiaryButton], which describes a cross-device behavior of
|
||||||
|
/// "tertiary operation".
|
||||||
const int kSecondaryButton = 0x02;
|
const int kSecondaryButton = 0x02;
|
||||||
|
|
||||||
/// The bit of [PointerEvent.buttons] that corresponds to the primary mouse button.
|
/// The bit of [PointerEvent.buttons] that corresponds to the primary mouse button.
|
||||||
@ -81,18 +85,46 @@ const int kStylusContact = kPrimaryButton;
|
|||||||
/// concept.
|
/// concept.
|
||||||
const int kPrimaryStylusButton = kSecondaryButton;
|
const int kPrimaryStylusButton = kSecondaryButton;
|
||||||
|
|
||||||
|
/// The bit of [PointerEvent.buttons] that corresponds to a cross-device
|
||||||
|
/// behavior of "tertiary operation".
|
||||||
|
///
|
||||||
|
/// It is equivalent to:
|
||||||
|
///
|
||||||
|
/// * [kMiddleMouseButton]: The tertiary mouseButton.
|
||||||
|
/// * [kSecondaryStylusButton]: The secondary button on a stylus. This is considered
|
||||||
|
/// a tertiary button as the primary button of a stylus already corresponds to a
|
||||||
|
/// "secondary operation" (where stylus contact is the primary operation).
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kPrimaryButton], which describes a cross-device behavior of
|
||||||
|
/// "primary operation".
|
||||||
|
/// * [kSecondaryButton], which describes a cross-device behavior of
|
||||||
|
/// "secondary operation".
|
||||||
|
const int kTertiaryButton = 0x04;
|
||||||
|
|
||||||
/// The bit of [PointerEvent.buttons] that corresponds to the middle mouse button.
|
/// The bit of [PointerEvent.buttons] that corresponds to the middle mouse button.
|
||||||
///
|
///
|
||||||
/// The middle mouse button is typically between the left and right buttons on
|
/// The middle mouse button is typically between the left and right buttons on
|
||||||
/// the top of the mouse but can be reconfigured to be a different physical
|
/// the top of the mouse but can be reconfigured to be a different physical
|
||||||
/// button.
|
/// button.
|
||||||
const int kMiddleMouseButton = 0x04;
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], which has the same value but describes its cross-device
|
||||||
|
/// concept.
|
||||||
|
const int kMiddleMouseButton = kTertiaryButton;
|
||||||
|
|
||||||
/// The bit of [PointerEvent.buttons] that corresponds to the secondary stylus button.
|
/// The bit of [PointerEvent.buttons] that corresponds to the secondary stylus button.
|
||||||
///
|
///
|
||||||
/// The secondary stylus button is typically on the end of the stylus farthest
|
/// The secondary stylus button is typically on the end of the stylus farthest
|
||||||
/// from the tip but can be reconfigured to be a different physical button.
|
/// from the tip but can be reconfigured to be a different physical button.
|
||||||
const int kSecondaryStylusButton = 0x04;
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], which has the same value but describes its cross-device
|
||||||
|
/// concept.
|
||||||
|
const int kSecondaryStylusButton = kTertiaryButton;
|
||||||
|
|
||||||
/// The bit of [PointerEvent.buttons] that corresponds to the back mouse button.
|
/// The bit of [PointerEvent.buttons] that corresponds to the back mouse button.
|
||||||
///
|
///
|
||||||
|
@ -143,8 +143,8 @@ class LongPressEndDetails {
|
|||||||
/// [postAcceptSlopTolerance] constructor argument is specified.
|
/// [postAcceptSlopTolerance] constructor argument is specified.
|
||||||
///
|
///
|
||||||
/// [LongPressGestureRecognizer] may compete on pointer events of
|
/// [LongPressGestureRecognizer] may compete on pointer events of
|
||||||
/// [kPrimaryButton] and/or [kSecondaryButton] if at least one corresponding
|
/// [kPrimaryButton], [kSecondaryButton], and/or [kTertiaryButton] if at least
|
||||||
/// callback is non-null. If it has no callbacks, it is a no-op.
|
/// one corresponding callback is non-null. If it has no callbacks, it is a no-op.
|
||||||
class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
||||||
/// Creates a long-press gesture recognizer.
|
/// Creates a long-press gesture recognizer.
|
||||||
///
|
///
|
||||||
@ -277,6 +277,57 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
|||||||
/// * [LongPressEndDetails], which is passed as an argument to this callback.
|
/// * [LongPressEndDetails], which is passed as an argument to this callback.
|
||||||
GestureLongPressEndCallback? onSecondaryLongPressEnd;
|
GestureLongPressEndCallback? onSecondaryLongPressEnd;
|
||||||
|
|
||||||
|
/// Called when a long press gesture by a tertiary button has been
|
||||||
|
/// recognized.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
/// * [onTertiaryLongPressStart], which has the same timing but has data for
|
||||||
|
/// the press location.
|
||||||
|
GestureLongPressCallback? onTertiaryLongPress;
|
||||||
|
|
||||||
|
/// Called when a long press gesture by a tertiary button has been recognized.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
/// * [onTertiaryLongPress], which has the same timing but without details.
|
||||||
|
/// * [LongPressStartDetails], which is passed as an argument to this
|
||||||
|
/// callback.
|
||||||
|
GestureLongPressStartCallback? onTertiaryLongPressStart;
|
||||||
|
|
||||||
|
/// Called when moving after the long press by a tertiary button is
|
||||||
|
/// recognized.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
/// * [LongPressMoveUpdateDetails], which is passed as an argument to this
|
||||||
|
/// callback.
|
||||||
|
GestureLongPressMoveUpdateCallback? onTertiaryLongPressMoveUpdate;
|
||||||
|
|
||||||
|
/// Called when the pointer stops contacting the screen after a long-press by
|
||||||
|
/// a tertiary button.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
/// * [onTertiaryLongPressEnd], which has the same timing but has data for
|
||||||
|
/// the up gesture location.
|
||||||
|
GestureLongPressUpCallback? onTertiaryLongPressUp;
|
||||||
|
|
||||||
|
/// Called when the pointer stops contacting the screen after a long-press by
|
||||||
|
/// a tertiary button.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
/// * [onTertiaryLongPressUp], which has the same timing, but without
|
||||||
|
/// details.
|
||||||
|
/// * [LongPressEndDetails], which is passed as an argument to this callback.
|
||||||
|
GestureLongPressEndCallback? onTertiaryLongPressEnd;
|
||||||
|
|
||||||
VelocityTracker? _velocityTracker;
|
VelocityTracker? _velocityTracker;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -298,6 +349,14 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
|||||||
onSecondaryLongPressUp == null)
|
onSecondaryLongPressUp == null)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case kTertiaryButton:
|
||||||
|
if (onTertiaryLongPressStart == null &&
|
||||||
|
onTertiaryLongPress == null &&
|
||||||
|
onTertiaryLongPressMoveUpdate == null &&
|
||||||
|
onTertiaryLongPressEnd == null &&
|
||||||
|
onTertiaryLongPressUp == null)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -377,6 +436,19 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
|||||||
invokeCallback<void>('onSecondaryLongPress', onSecondaryLongPress!);
|
invokeCallback<void>('onSecondaryLongPress', onSecondaryLongPress!);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kTertiaryButton:
|
||||||
|
if (onTertiaryLongPressStart != null) {
|
||||||
|
final LongPressStartDetails details = LongPressStartDetails(
|
||||||
|
globalPosition: _longPressOrigin!.global,
|
||||||
|
localPosition: _longPressOrigin!.local,
|
||||||
|
);
|
||||||
|
invokeCallback<void>(
|
||||||
|
'onTertiaryLongPressStart', () => onTertiaryLongPressStart!(details));
|
||||||
|
}
|
||||||
|
if (onTertiaryLongPress != null) {
|
||||||
|
invokeCallback<void>('onTertiaryLongPress', onTertiaryLongPress!);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false, 'Unhandled button $_initialButtons');
|
assert(false, 'Unhandled button $_initialButtons');
|
||||||
}
|
}
|
||||||
@ -402,6 +474,12 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
|||||||
() => onSecondaryLongPressMoveUpdate!(details));
|
() => onSecondaryLongPressMoveUpdate!(details));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kTertiaryButton:
|
||||||
|
if (onTertiaryLongPressMoveUpdate != null) {
|
||||||
|
invokeCallback<void>('onTertiaryLongPressMoveUpdate',
|
||||||
|
() => onTertiaryLongPressMoveUpdate!(details));
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false, 'Unhandled button $_initialButtons');
|
assert(false, 'Unhandled button $_initialButtons');
|
||||||
}
|
}
|
||||||
@ -436,6 +514,14 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
|
|||||||
invokeCallback<void>('onSecondaryLongPressUp', onSecondaryLongPressUp!);
|
invokeCallback<void>('onSecondaryLongPressUp', onSecondaryLongPressUp!);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kTertiaryButton:
|
||||||
|
if (onTertiaryLongPressEnd != null) {
|
||||||
|
invokeCallback<void>('onTertiaryLongPressEnd', () => onTertiaryLongPressEnd!(details));
|
||||||
|
}
|
||||||
|
if (onTertiaryLongPressUp != null) {
|
||||||
|
invokeCallback<void>('onTertiaryLongPressUp', onTertiaryLongPressUp!);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false, 'Unhandled button $_initialButtons');
|
assert(false, 'Unhandled button $_initialButtons');
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ abstract class BaseTapGestureRecognizer extends PrimaryPointerGestureRecognizer
|
|||||||
|
|
||||||
/// A pointer has stopped contacting the screen, which is recognized as a tap.
|
/// A pointer has stopped contacting the screen, which is recognized as a tap.
|
||||||
///
|
///
|
||||||
/// This triggers on the up event, if the recognizer wins the arena with it
|
/// This triggers on the up event if the recognizer wins the arena with it
|
||||||
/// or has previously won.
|
/// or has previously won.
|
||||||
///
|
///
|
||||||
/// The parameter `down` is the down event of the primary pointer that started
|
/// The parameter `down` is the down event of the primary pointer that started
|
||||||
@ -174,7 +174,7 @@ abstract class BaseTapGestureRecognizer extends PrimaryPointerGestureRecognizer
|
|||||||
/// A pointer that previously triggered [handleTapDown] will not end up
|
/// A pointer that previously triggered [handleTapDown] will not end up
|
||||||
/// causing a tap.
|
/// causing a tap.
|
||||||
///
|
///
|
||||||
/// This triggers once the gesture loses the arena, if [handleTapDown] has
|
/// This triggers once the gesture loses the arena if [handleTapDown] has
|
||||||
/// been previously triggered.
|
/// been previously triggered.
|
||||||
///
|
///
|
||||||
/// The parameter `down` is the down event of the primary pointer that started
|
/// The parameter `down` is the down event of the primary pointer that started
|
||||||
@ -325,9 +325,11 @@ abstract class BaseTapGestureRecognizer extends PrimaryPointerGestureRecognizer
|
|||||||
/// taps. For example, down-1, down-2, up-1, up-2 produces only one tap on up-1.
|
/// taps. For example, down-1, down-2, up-1, up-2 produces only one tap on up-1.
|
||||||
///
|
///
|
||||||
/// [TapGestureRecognizer] competes on pointer events of [kPrimaryButton] only
|
/// [TapGestureRecognizer] competes on pointer events of [kPrimaryButton] only
|
||||||
/// when it has at least one non-null `onTap*` callback, and events of
|
/// when it has at least one non-null `onTap*` callback, on events of
|
||||||
/// [kSecondaryButton] only when it has at least one non-null `onSecondaryTap*`
|
/// [kSecondaryButton] only when it has at least one non-null `onSecondaryTap*`
|
||||||
/// callback. If it has no callbacks, it is a no-op.
|
/// callback, and on events of [kTertiaryButton] only when it has at least
|
||||||
|
/// one non-null `onTertiaryTap*` callback. If it has no callbacks, it is a
|
||||||
|
/// no-op.
|
||||||
///
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
@ -350,6 +352,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
///
|
///
|
||||||
/// * [kPrimaryButton], the button this callback responds to.
|
/// * [kPrimaryButton], the button this callback responds to.
|
||||||
/// * [onSecondaryTapDown], a similar callback but for a secondary button.
|
/// * [onSecondaryTapDown], a similar callback but for a secondary button.
|
||||||
|
/// * [onTertiaryTapDown], a similar callback but for a tertiary button.
|
||||||
/// * [TapDownDetails], which is passed as an argument to this callback.
|
/// * [TapDownDetails], which is passed as an argument to this callback.
|
||||||
/// * [GestureDetector.onTapDown], which exposes this callback.
|
/// * [GestureDetector.onTapDown], which exposes this callback.
|
||||||
GestureTapDownCallback? onTapDown;
|
GestureTapDownCallback? onTapDown;
|
||||||
@ -366,6 +369,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
///
|
///
|
||||||
/// * [kPrimaryButton], the button this callback responds to.
|
/// * [kPrimaryButton], the button this callback responds to.
|
||||||
/// * [onSecondaryTapUp], a similar callback but for a secondary button.
|
/// * [onSecondaryTapUp], a similar callback but for a secondary button.
|
||||||
|
/// * [onTertiaryTapUp], a similar callback but for a tertiary button.
|
||||||
/// * [TapUpDetails], which is passed as an argument to this callback.
|
/// * [TapUpDetails], which is passed as an argument to this callback.
|
||||||
/// * [GestureDetector.onTapUp], which exposes this callback.
|
/// * [GestureDetector.onTapUp], which exposes this callback.
|
||||||
GestureTapUpCallback? onTapUp;
|
GestureTapUpCallback? onTapUp;
|
||||||
@ -388,7 +392,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
/// A pointer that previously triggered [onTapDown] will not end up causing
|
/// A pointer that previously triggered [onTapDown] will not end up causing
|
||||||
/// a tap.
|
/// a tap.
|
||||||
///
|
///
|
||||||
/// This triggers once the gesture loses the arena, if [onTapDown] has
|
/// This triggers once the gesture loses the arena if [onTapDown] has
|
||||||
/// previously been triggered.
|
/// previously been triggered.
|
||||||
///
|
///
|
||||||
/// If this recognizer wins the arena, [onTapUp] and [onTap] are called
|
/// If this recognizer wins the arena, [onTapUp] and [onTap] are called
|
||||||
@ -398,6 +402,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
///
|
///
|
||||||
/// * [kPrimaryButton], the button this callback responds to.
|
/// * [kPrimaryButton], the button this callback responds to.
|
||||||
/// * [onSecondaryTapCancel], a similar callback but for a secondary button.
|
/// * [onSecondaryTapCancel], a similar callback but for a secondary button.
|
||||||
|
/// * [onTertiaryTapCancel], a similar callback but for a tertiary button.
|
||||||
/// * [GestureDetector.onTapCancel], which exposes this callback.
|
/// * [GestureDetector.onTapCancel], which exposes this callback.
|
||||||
GestureTapCancelCallback? onTapCancel;
|
GestureTapCancelCallback? onTapCancel;
|
||||||
|
|
||||||
@ -430,6 +435,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
///
|
///
|
||||||
/// * [kSecondaryButton], the button this callback responds to.
|
/// * [kSecondaryButton], the button this callback responds to.
|
||||||
/// * [onTapDown], a similar callback but for a primary button.
|
/// * [onTapDown], a similar callback but for a primary button.
|
||||||
|
/// * [onTertiaryTapDown], a similar callback but for a tertiary button.
|
||||||
/// * [TapDownDetails], which is passed as an argument to this callback.
|
/// * [TapDownDetails], which is passed as an argument to this callback.
|
||||||
/// * [GestureDetector.onSecondaryTapDown], which exposes this callback.
|
/// * [GestureDetector.onSecondaryTapDown], which exposes this callback.
|
||||||
GestureTapDownCallback? onSecondaryTapDown;
|
GestureTapDownCallback? onSecondaryTapDown;
|
||||||
@ -437,7 +443,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
/// A pointer has stopped contacting the screen at a particular location,
|
/// A pointer has stopped contacting the screen at a particular location,
|
||||||
/// which is recognized as a tap of a secondary button.
|
/// which is recognized as a tap of a secondary button.
|
||||||
///
|
///
|
||||||
/// This triggers on the up event, if the recognizer wins the arena with it
|
/// This triggers on the up event if the recognizer wins the arena with it
|
||||||
/// or has previously won.
|
/// or has previously won.
|
||||||
///
|
///
|
||||||
/// If this recognizer doesn't win the arena, [onSecondaryTapCancel] is called
|
/// If this recognizer doesn't win the arena, [onSecondaryTapCancel] is called
|
||||||
@ -449,6 +455,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
/// pass any details about the tap.
|
/// pass any details about the tap.
|
||||||
/// * [kSecondaryButton], the button this callback responds to.
|
/// * [kSecondaryButton], the button this callback responds to.
|
||||||
/// * [onTapUp], a similar callback but for a primary button.
|
/// * [onTapUp], a similar callback but for a primary button.
|
||||||
|
/// * [onTertiaryTapUp], a similar callback but for a tertiary button.
|
||||||
/// * [TapUpDetails], which is passed as an argument to this callback.
|
/// * [TapUpDetails], which is passed as an argument to this callback.
|
||||||
/// * [GestureDetector.onSecondaryTapUp], which exposes this callback.
|
/// * [GestureDetector.onSecondaryTapUp], which exposes this callback.
|
||||||
GestureTapUpCallback? onSecondaryTapUp;
|
GestureTapUpCallback? onSecondaryTapUp;
|
||||||
@ -456,7 +463,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
/// A pointer that previously triggered [onSecondaryTapDown] will not end up
|
/// A pointer that previously triggered [onSecondaryTapDown] will not end up
|
||||||
/// causing a tap.
|
/// causing a tap.
|
||||||
///
|
///
|
||||||
/// This triggers once the gesture loses the arena, if [onSecondaryTapDown]
|
/// This triggers once the gesture loses the arena if [onSecondaryTapDown]
|
||||||
/// has previously been triggered.
|
/// has previously been triggered.
|
||||||
///
|
///
|
||||||
/// If this recognizer wins the arena, [onSecondaryTapUp] is called instead.
|
/// If this recognizer wins the arena, [onSecondaryTapUp] is called instead.
|
||||||
@ -465,9 +472,62 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
///
|
///
|
||||||
/// * [kSecondaryButton], the button this callback responds to.
|
/// * [kSecondaryButton], the button this callback responds to.
|
||||||
/// * [onTapCancel], a similar callback but for a primary button.
|
/// * [onTapCancel], a similar callback but for a primary button.
|
||||||
/// * [GestureDetector.onTapCancel], which exposes this callback.
|
/// * [onTertiaryTapCancel], a similar callback but for a tertiary button.
|
||||||
|
/// * [GestureDetector.onSecondaryTapCancel], which exposes this callback.
|
||||||
GestureTapCancelCallback? onSecondaryTapCancel;
|
GestureTapCancelCallback? onSecondaryTapCancel;
|
||||||
|
|
||||||
|
/// A pointer has contacted the screen at a particular location with a
|
||||||
|
/// tertiary button, which might be the start of a tertiary tap.
|
||||||
|
///
|
||||||
|
/// This triggers after the down event, once a short timeout ([deadline]) has
|
||||||
|
/// elapsed, or once the gestures has won the arena, whichever comes first.
|
||||||
|
///
|
||||||
|
/// If this recognizer doesn't win the arena, [onTertiaryTapCancel] is called
|
||||||
|
/// next. Otherwise, [onTertiaryTapUp] is called next.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
/// * [onTapDown], a similar callback but for a primary button.
|
||||||
|
/// * [onSecondaryTapDown], a similar callback but for a secondary button.
|
||||||
|
/// * [TapDownDetails], which is passed as an argument to this callback.
|
||||||
|
/// * [GestureDetector.onTertiaryTapDown], which exposes this callback.
|
||||||
|
GestureTapDownCallback? onTertiaryTapDown;
|
||||||
|
|
||||||
|
/// A pointer has stopped contacting the screen at a particular location,
|
||||||
|
/// which is recognized as a tap of a tertiary button.
|
||||||
|
///
|
||||||
|
/// This triggers on the up event if the recognizer wins the arena with it
|
||||||
|
/// or has previously won.
|
||||||
|
///
|
||||||
|
/// If this recognizer doesn't win the arena, [onTertiaryTapCancel] is called
|
||||||
|
/// instead.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
/// * [onTapUp], a similar callback but for a primary button.
|
||||||
|
/// * [onSecondaryTapUp], a similar callback but for a secondary button.
|
||||||
|
/// * [TapUpDetails], which is passed as an argument to this callback.
|
||||||
|
/// * [GestureDetector.onTertiaryTapUp], which exposes this callback.
|
||||||
|
GestureTapUpCallback? onTertiaryTapUp;
|
||||||
|
|
||||||
|
/// A pointer that previously triggered [onTertiaryTapDown] will not end up
|
||||||
|
/// causing a tap.
|
||||||
|
///
|
||||||
|
/// This triggers once the gesture loses the arena if [onTertiaryTapDown]
|
||||||
|
/// has previously been triggered.
|
||||||
|
///
|
||||||
|
/// If this recognizer wins the arena, [onTertiaryTapUp] is called instead.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kSecondaryButton], the button this callback responds to.
|
||||||
|
/// * [onTapCancel], a similar callback but for a primary button.
|
||||||
|
/// * [onSecondaryTapCancel], a similar callback but for a secondary button.
|
||||||
|
/// * [GestureDetector.onTertiaryTapCancel], which exposes this callback.
|
||||||
|
GestureTapCancelCallback? onTertiaryTapCancel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isPointerAllowed(PointerDownEvent event) {
|
bool isPointerAllowed(PointerDownEvent event) {
|
||||||
switch (event.buttons) {
|
switch (event.buttons) {
|
||||||
@ -485,6 +545,12 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
onSecondaryTapCancel == null)
|
onSecondaryTapCancel == null)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case kTertiaryButton:
|
||||||
|
if (onTertiaryTapDown == null &&
|
||||||
|
onTertiaryTapUp == null &&
|
||||||
|
onTertiaryTapCancel == null)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -508,6 +574,10 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
if (onSecondaryTapDown != null)
|
if (onSecondaryTapDown != null)
|
||||||
invokeCallback<void>('onSecondaryTapDown', () => onSecondaryTapDown!(details));
|
invokeCallback<void>('onSecondaryTapDown', () => onSecondaryTapDown!(details));
|
||||||
break;
|
break;
|
||||||
|
case kTertiaryButton:
|
||||||
|
if (onTertiaryTapDown != null)
|
||||||
|
invokeCallback<void>('onTertiaryTapDown', () => onTertiaryTapDown!(details));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -533,6 +603,10 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
if (onSecondaryTap != null)
|
if (onSecondaryTap != null)
|
||||||
invokeCallback<void>('onSecondaryTap', () => onSecondaryTap!());
|
invokeCallback<void>('onSecondaryTap', () => onSecondaryTap!());
|
||||||
break;
|
break;
|
||||||
|
case kTertiaryButton:
|
||||||
|
if (onTertiaryTapUp != null)
|
||||||
|
invokeCallback<void>('onTertiaryTapUp', () => onTertiaryTapUp!(details));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,6 +624,10 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
if (onSecondaryTapCancel != null)
|
if (onSecondaryTapCancel != null)
|
||||||
invokeCallback<void>('${note}onSecondaryTapCancel', onSecondaryTapCancel!);
|
invokeCallback<void>('${note}onSecondaryTapCancel', onSecondaryTapCancel!);
|
||||||
break;
|
break;
|
||||||
|
case kTertiaryButton:
|
||||||
|
if (onTertiaryTapCancel != null)
|
||||||
|
invokeCallback<void>('${note}onTertiaryTapCancel', onTertiaryTapCancel!);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,9 @@ class GestureDetector extends StatelessWidget {
|
|||||||
this.onSecondaryTapDown,
|
this.onSecondaryTapDown,
|
||||||
this.onSecondaryTapUp,
|
this.onSecondaryTapUp,
|
||||||
this.onSecondaryTapCancel,
|
this.onSecondaryTapCancel,
|
||||||
|
this.onTertiaryTapDown,
|
||||||
|
this.onTertiaryTapUp,
|
||||||
|
this.onTertiaryTapCancel,
|
||||||
this.onDoubleTap,
|
this.onDoubleTap,
|
||||||
this.onLongPress,
|
this.onLongPress,
|
||||||
this.onLongPressStart,
|
this.onLongPressStart,
|
||||||
@ -391,6 +394,40 @@ class GestureDetector extends StatelessWidget {
|
|||||||
/// * [kSecondaryButton], the button this callback responds to.
|
/// * [kSecondaryButton], the button this callback responds to.
|
||||||
final GestureTapCancelCallback onSecondaryTapCancel;
|
final GestureTapCancelCallback onSecondaryTapCancel;
|
||||||
|
|
||||||
|
/// A pointer that might cause a tap with a tertiary button has contacted the
|
||||||
|
/// screen at a particular location.
|
||||||
|
///
|
||||||
|
/// This is called after a short timeout, even if the winning gesture has not
|
||||||
|
/// yet been selected. If the tap gesture wins, [onTertiaryTapUp] will be
|
||||||
|
/// called, otherwise [onTertiaryTapCancel] will be called.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
final GestureTapDownCallback onTertiaryTapDown;
|
||||||
|
|
||||||
|
/// A pointer that will trigger a tap with a tertiary button has stopped
|
||||||
|
/// contacting the screen at a particular location.
|
||||||
|
///
|
||||||
|
/// This triggers in the case of the tap gesture winning. If the tap gesture
|
||||||
|
/// did not win, [onTertiaryTapCancel] is called instead.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
final GestureTapUpCallback onTertiaryTapUp;
|
||||||
|
|
||||||
|
/// The pointer that previously triggered [onTertiaryTapDown] will not end up
|
||||||
|
/// causing a tap.
|
||||||
|
///
|
||||||
|
/// This is called after [onTertiaryTapDown], and instead of
|
||||||
|
/// [onTertiaryTapUp], if the tap gesture did not win.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [kTertiaryButton], the button this callback responds to.
|
||||||
|
final GestureTapCancelCallback onTertiaryTapCancel;
|
||||||
|
|
||||||
/// The user has tapped the screen with a primary button at the same location
|
/// The user has tapped the screen with a primary button at the same location
|
||||||
/// twice in quick succession.
|
/// twice in quick succession.
|
||||||
///
|
///
|
||||||
@ -709,7 +746,10 @@ class GestureDetector extends StatelessWidget {
|
|||||||
onSecondaryTap != null ||
|
onSecondaryTap != null ||
|
||||||
onSecondaryTapDown != null ||
|
onSecondaryTapDown != null ||
|
||||||
onSecondaryTapUp != null ||
|
onSecondaryTapUp != null ||
|
||||||
onSecondaryTapCancel != null
|
onSecondaryTapCancel != null||
|
||||||
|
onTertiaryTapDown != null ||
|
||||||
|
onTertiaryTapUp != null ||
|
||||||
|
onTertiaryTapCancel != null
|
||||||
) {
|
) {
|
||||||
gestures[TapGestureRecognizer] = GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
|
gestures[TapGestureRecognizer] = GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
|
||||||
() => TapGestureRecognizer(debugOwner: this),
|
() => TapGestureRecognizer(debugOwner: this),
|
||||||
@ -722,7 +762,10 @@ class GestureDetector extends StatelessWidget {
|
|||||||
..onSecondaryTap = onSecondaryTap
|
..onSecondaryTap = onSecondaryTap
|
||||||
..onSecondaryTapDown = onSecondaryTapDown
|
..onSecondaryTapDown = onSecondaryTapDown
|
||||||
..onSecondaryTapUp = onSecondaryTapUp
|
..onSecondaryTapUp = onSecondaryTapUp
|
||||||
..onSecondaryTapCancel = onSecondaryTapCancel;
|
..onSecondaryTapCancel = onSecondaryTapCancel
|
||||||
|
..onTertiaryTapDown = onTertiaryTapDown
|
||||||
|
..onTertiaryTapUp = onTertiaryTapUp
|
||||||
|
..onTertiaryTapCancel = onTertiaryTapCancel;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,18 @@ const PointerUpEvent up3 = PointerUpEvent(
|
|||||||
position: Offset(31, 29),
|
position: Offset(31, 29),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Down/up pair 4: tap sequence with tertiary button
|
||||||
|
const PointerDownEvent down4 = PointerDownEvent(
|
||||||
|
pointer: 8,
|
||||||
|
position: Offset(42, 24),
|
||||||
|
buttons: kTertiaryButton,
|
||||||
|
);
|
||||||
|
|
||||||
|
const PointerUpEvent up4 = PointerUpEvent(
|
||||||
|
pointer: 8,
|
||||||
|
position: Offset(43, 23),
|
||||||
|
);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
setUp(ensureGestureBinding);
|
setUp(ensureGestureBinding);
|
||||||
|
|
||||||
@ -241,7 +253,7 @@ void main() {
|
|||||||
longPress.addPointer(const PointerDownEvent(
|
longPress.addPointer(const PointerDownEvent(
|
||||||
pointer: 5,
|
pointer: 5,
|
||||||
kind: PointerDeviceKind.mouse,
|
kind: PointerDeviceKind.mouse,
|
||||||
buttons: kSecondaryMouseButton | kMiddleMouseButton,
|
buttons: kSecondaryMouseButton | kTertiaryButton,
|
||||||
position: Offset(10, 10),
|
position: Offset(10, 10),
|
||||||
));
|
));
|
||||||
tester.closeArena(5);
|
tester.closeArena(5);
|
||||||
@ -267,7 +279,7 @@ void main() {
|
|||||||
tester.route(const PointerMoveEvent(
|
tester.route(const PointerMoveEvent(
|
||||||
pointer: 5,
|
pointer: 5,
|
||||||
kind: PointerDeviceKind.mouse,
|
kind: PointerDeviceKind.mouse,
|
||||||
buttons: kMiddleMouseButton,
|
buttons: kTertiaryButton,
|
||||||
position: Offset(10, 10),
|
position: Offset(10, 10),
|
||||||
));
|
));
|
||||||
expect(longPressDown, isFalse);
|
expect(longPressDown, isFalse);
|
||||||
@ -613,4 +625,66 @@ void main() {
|
|||||||
longPress.dispose();
|
longPress.dispose();
|
||||||
recognized.clear();
|
recognized.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testGesture('A tertiary long press should not trigger primary or secondary', (GestureTester tester) {
|
||||||
|
final List<String> recognized = <String>[];
|
||||||
|
final LongPressGestureRecognizer longPress = LongPressGestureRecognizer()
|
||||||
|
..onLongPressStart = (LongPressStartDetails details) {
|
||||||
|
recognized.add('primaryStart');
|
||||||
|
}
|
||||||
|
..onLongPress = () {
|
||||||
|
recognized.add('primary');
|
||||||
|
}
|
||||||
|
..onLongPressMoveUpdate = (LongPressMoveUpdateDetails details) {
|
||||||
|
recognized.add('primaryUpdate');
|
||||||
|
}
|
||||||
|
..onLongPressEnd = (LongPressEndDetails details) {
|
||||||
|
recognized.add('primaryEnd');
|
||||||
|
}
|
||||||
|
..onLongPressUp = () {
|
||||||
|
recognized.add('primaryUp');
|
||||||
|
}
|
||||||
|
..onSecondaryLongPressStart = (LongPressStartDetails details) {
|
||||||
|
recognized.add('secondaryStart');
|
||||||
|
}
|
||||||
|
..onSecondaryLongPress = () {
|
||||||
|
recognized.add('secondary');
|
||||||
|
}
|
||||||
|
..onSecondaryLongPressMoveUpdate = (LongPressMoveUpdateDetails details) {
|
||||||
|
recognized.add('secondaryUpdate');
|
||||||
|
}
|
||||||
|
..onSecondaryLongPressEnd = (LongPressEndDetails details) {
|
||||||
|
recognized.add('secondaryEnd');
|
||||||
|
}
|
||||||
|
..onSecondaryLongPressUp = () {
|
||||||
|
recognized.add('secondaryUp');
|
||||||
|
};
|
||||||
|
|
||||||
|
const PointerDownEvent down2 = PointerDownEvent(
|
||||||
|
pointer: 2,
|
||||||
|
buttons: kTertiaryButton,
|
||||||
|
position: Offset(30.0, 30.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
const PointerMoveEvent move2 = PointerMoveEvent(
|
||||||
|
pointer: 2,
|
||||||
|
buttons: kTertiaryButton,
|
||||||
|
position: Offset(100, 200),
|
||||||
|
);
|
||||||
|
|
||||||
|
const PointerUpEvent up2 = PointerUpEvent(
|
||||||
|
pointer: 2,
|
||||||
|
position: Offset(100, 201),
|
||||||
|
);
|
||||||
|
|
||||||
|
longPress.addPointer(down2);
|
||||||
|
tester.closeArena(2);
|
||||||
|
tester.route(down2);
|
||||||
|
tester.async.elapse(const Duration(milliseconds: 700));
|
||||||
|
tester.route(move2);
|
||||||
|
tester.route(up2);
|
||||||
|
expect(recognized, <String>[]);
|
||||||
|
longPress.dispose();
|
||||||
|
recognized.clear();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,18 @@ void main() {
|
|||||||
position: Offset(20.0, 20.0),
|
position: Offset(20.0, 20.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Down/up sequence 6: tap sequence with tertiary button
|
||||||
|
const PointerDownEvent down6 = PointerDownEvent(
|
||||||
|
pointer: 6,
|
||||||
|
position: Offset(20.0, 20.0),
|
||||||
|
buttons: kTertiaryButton,
|
||||||
|
);
|
||||||
|
|
||||||
|
const PointerUpEvent up6 = PointerUpEvent(
|
||||||
|
pointer: 6,
|
||||||
|
position: Offset(20.0, 20.0),
|
||||||
|
);
|
||||||
|
|
||||||
testGesture('Should recognize tap', (GestureTester tester) {
|
testGesture('Should recognize tap', (GestureTester tester) {
|
||||||
final TapGestureRecognizer tap = TapGestureRecognizer();
|
final TapGestureRecognizer tap = TapGestureRecognizer();
|
||||||
|
|
||||||
@ -777,6 +789,7 @@ void main() {
|
|||||||
TapGestureRecognizer primary;
|
TapGestureRecognizer primary;
|
||||||
TapGestureRecognizer primary2;
|
TapGestureRecognizer primary2;
|
||||||
TapGestureRecognizer secondary;
|
TapGestureRecognizer secondary;
|
||||||
|
TapGestureRecognizer tertiary;
|
||||||
setUp(() {
|
setUp(() {
|
||||||
primary = TapGestureRecognizer()
|
primary = TapGestureRecognizer()
|
||||||
..onTapDown = (TapDownDetails details) {
|
..onTapDown = (TapDownDetails details) {
|
||||||
@ -808,6 +821,16 @@ void main() {
|
|||||||
..onSecondaryTapCancel = () {
|
..onSecondaryTapCancel = () {
|
||||||
recognized.add('secondaryCancel');
|
recognized.add('secondaryCancel');
|
||||||
};
|
};
|
||||||
|
tertiary = TapGestureRecognizer()
|
||||||
|
..onTertiaryTapDown = (TapDownDetails details) {
|
||||||
|
recognized.add('tertiaryDown');
|
||||||
|
}
|
||||||
|
..onTertiaryTapUp = (TapUpDetails details) {
|
||||||
|
recognized.add('tertiaryUp');
|
||||||
|
}
|
||||||
|
..onTertiaryTapCancel = () {
|
||||||
|
recognized.add('tertiaryCancel');
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
@ -815,6 +838,7 @@ void main() {
|
|||||||
primary.dispose();
|
primary.dispose();
|
||||||
primary2.dispose();
|
primary2.dispose();
|
||||||
secondary.dispose();
|
secondary.dispose();
|
||||||
|
tertiary.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
testGesture('A primary tap recognizer does not form competition with a secondary tap recognizer', (GestureTester tester) {
|
testGesture('A primary tap recognizer does not form competition with a secondary tap recognizer', (GestureTester tester) {
|
||||||
@ -830,6 +854,19 @@ void main() {
|
|||||||
expect(recognized, <String>['primaryUp']);
|
expect(recognized, <String>['primaryUp']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testGesture('A primary tap recognizer does not form competition with a tertiary tap recognizer', (GestureTester tester) {
|
||||||
|
primary.addPointer(down1);
|
||||||
|
tertiary.addPointer(down1);
|
||||||
|
tester.closeArena(1);
|
||||||
|
|
||||||
|
tester.route(down1);
|
||||||
|
expect(recognized, <String>['primaryDown']);
|
||||||
|
recognized.clear();
|
||||||
|
|
||||||
|
tester.route(up1);
|
||||||
|
expect(recognized, <String>['primaryUp']);
|
||||||
|
});
|
||||||
|
|
||||||
testGesture('A primary tap recognizer forms competition with another primary tap recognizer', (GestureTester tester) {
|
testGesture('A primary tap recognizer forms competition with another primary tap recognizer', (GestureTester tester) {
|
||||||
primary.addPointer(down1);
|
primary.addPointer(down1);
|
||||||
primary2.addPointer(down1);
|
primary2.addPointer(down1);
|
||||||
@ -852,6 +889,9 @@ void main() {
|
|||||||
const PointerCancelEvent cancel5 = PointerCancelEvent(
|
const PointerCancelEvent cancel5 = PointerCancelEvent(
|
||||||
pointer: 5,
|
pointer: 5,
|
||||||
);
|
);
|
||||||
|
const PointerCancelEvent cancel6 = PointerCancelEvent(
|
||||||
|
pointer: 6,
|
||||||
|
);
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
tap = TapGestureRecognizer()
|
tap = TapGestureRecognizer()
|
||||||
@ -875,6 +915,15 @@ void main() {
|
|||||||
}
|
}
|
||||||
..onSecondaryTapCancel = () {
|
..onSecondaryTapCancel = () {
|
||||||
recognized.add('secondaryCancel');
|
recognized.add('secondaryCancel');
|
||||||
|
}
|
||||||
|
..onTertiaryTapDown = (TapDownDetails details) {
|
||||||
|
recognized.add('tertiaryDown');
|
||||||
|
}
|
||||||
|
..onTertiaryTapUp = (TapUpDetails details) {
|
||||||
|
recognized.add('tertiaryUp');
|
||||||
|
}
|
||||||
|
..onTertiaryTapCancel = () {
|
||||||
|
recognized.add('tertiaryCancel');
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -922,6 +971,19 @@ void main() {
|
|||||||
expect(recognized, <String>['secondaryUp']);
|
expect(recognized, <String>['secondaryUp']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testGesture('A tertiary tap should trigger tertiary callbacks', (GestureTester tester) {
|
||||||
|
tap.addPointer(down6);
|
||||||
|
tester.closeArena(down6.pointer);
|
||||||
|
expect(recognized, <String>[]);
|
||||||
|
tester.async.elapse(const Duration(milliseconds: 500));
|
||||||
|
expect(recognized, <String>['tertiaryDown']);
|
||||||
|
recognized.clear();
|
||||||
|
|
||||||
|
tester.route(up6);
|
||||||
|
GestureBinding.instance.gestureArena.sweep(down6.pointer);
|
||||||
|
expect(recognized, <String>['tertiaryUp']);
|
||||||
|
});
|
||||||
|
|
||||||
testGesture('A secondary tap cancel should trigger secondary callbacks', (GestureTester tester) {
|
testGesture('A secondary tap cancel should trigger secondary callbacks', (GestureTester tester) {
|
||||||
tap.addPointer(down5);
|
tap.addPointer(down5);
|
||||||
tester.closeArena(down5.pointer);
|
tester.closeArena(down5.pointer);
|
||||||
@ -934,6 +996,19 @@ void main() {
|
|||||||
GestureBinding.instance.gestureArena.sweep(down5.pointer);
|
GestureBinding.instance.gestureArena.sweep(down5.pointer);
|
||||||
expect(recognized, <String>['secondaryCancel']);
|
expect(recognized, <String>['secondaryCancel']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testGesture('A tertiary tap cancel should trigger tertiary callbacks', (GestureTester tester) {
|
||||||
|
tap.addPointer(down6);
|
||||||
|
tester.closeArena(down6.pointer);
|
||||||
|
expect(recognized, <String>[]);
|
||||||
|
tester.async.elapse(const Duration(milliseconds: 500));
|
||||||
|
expect(recognized, <String>['tertiaryDown']);
|
||||||
|
recognized.clear();
|
||||||
|
|
||||||
|
tester.route(cancel6);
|
||||||
|
GestureBinding.instance.gestureArena.sweep(down6.pointer);
|
||||||
|
expect(recognized, <String>['tertiaryCancel']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testGesture('A second tap after rejection is ignored', (GestureTester tester) {
|
testGesture('A second tap after rejection is ignored', (GestureTester tester) {
|
||||||
|
@ -379,7 +379,8 @@ void main() {
|
|||||||
..onTapUp = (_) {logs.add('tapUp');}
|
..onTapUp = (_) {logs.add('tapUp');}
|
||||||
..onTapDown = (_) {logs.add('tapDown');}
|
..onTapDown = (_) {logs.add('tapDown');}
|
||||||
..onTapCancel = () {logs.add('WRONG');}
|
..onTapCancel = () {logs.add('WRONG');}
|
||||||
..onSecondaryTapDown = (_) {logs.add('WRONG');};
|
..onSecondaryTapDown = (_) {logs.add('WRONG');}
|
||||||
|
..onTertiaryTapDown = (_) {logs.add('WRONG');};
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
child: Container(),
|
child: Container(),
|
||||||
|
@ -129,10 +129,11 @@ void main() {
|
|||||||
|
|
||||||
group('Tap', () {
|
group('Tap', () {
|
||||||
final ButtonVariant buttonVariant = ButtonVariant(
|
final ButtonVariant buttonVariant = ButtonVariant(
|
||||||
values: <int>[kPrimaryButton, kSecondaryButton],
|
values: <int>[kPrimaryButton, kSecondaryButton, kTertiaryButton],
|
||||||
descriptions: <int, String>{
|
descriptions: <int, String>{
|
||||||
kPrimaryButton: 'primary',
|
kPrimaryButton: 'primary',
|
||||||
kSecondaryButton: 'secondary',
|
kSecondaryButton: 'secondary',
|
||||||
|
kTertiaryButton: 'tertiary',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -166,6 +167,9 @@ void main() {
|
|||||||
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
|
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
|
||||||
didTap = true;
|
didTap = true;
|
||||||
} : null,
|
} : null,
|
||||||
|
onTertiaryTapDown: ButtonVariant.button == kTertiaryButton ? (_) {
|
||||||
|
didTap = true;
|
||||||
|
} : null,
|
||||||
behavior: behavior,
|
behavior: behavior,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -215,6 +219,9 @@ void main() {
|
|||||||
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
|
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
|
||||||
didTap = true;
|
didTap = true;
|
||||||
} : null,
|
} : null,
|
||||||
|
onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (_) {
|
||||||
|
didTap = true;
|
||||||
|
} : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -234,6 +241,9 @@ void main() {
|
|||||||
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
|
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
|
||||||
didTap = true;
|
didTap = true;
|
||||||
} : null,
|
} : null,
|
||||||
|
onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (_) {
|
||||||
|
didTap = true;
|
||||||
|
} : null,
|
||||||
child: Container(),
|
child: Container(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -251,6 +261,7 @@ void main() {
|
|||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: ButtonVariant.button == kPrimaryButton ? inputCallback : null,
|
onTap: ButtonVariant.button == kPrimaryButton ? inputCallback : null,
|
||||||
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? inputCallback : null,
|
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? inputCallback : null,
|
||||||
|
onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (_) => inputCallback() : null,
|
||||||
child: Container(),
|
child: Container(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -263,6 +274,7 @@ void main() {
|
|||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: ButtonVariant.button == kPrimaryButton ? inputCallback : null,
|
onTap: ButtonVariant.button == kPrimaryButton ? inputCallback : null,
|
||||||
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? inputCallback : null,
|
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? inputCallback : null,
|
||||||
|
onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (_) => inputCallback() : null,
|
||||||
child: Container(),
|
child: Container(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -286,31 +298,64 @@ void main() {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
height: 100.0,
|
height: 100.0,
|
||||||
color: const Color(0xFF00FF00),
|
color: const Color(0xFF00FF00),
|
||||||
child: GestureDetector(
|
child: RawGestureDetector(
|
||||||
onTapDown: ButtonVariant.button == kPrimaryButton ? (TapDownDetails details) {
|
behavior: HitTestBehavior.translucent,
|
||||||
tapDown += 1;
|
// Adding long press callbacks here will cause the on*TapDown callbacks to be executed only after
|
||||||
} : null,
|
// kPressTimeout has passed. Without the long press callbacks, there would be no press pointers
|
||||||
onSecondaryTapDown: ButtonVariant.button == kSecondaryButton ? (TapDownDetails details) {
|
// competing in the arena. Hence, we add them to the arena to test this behavior.
|
||||||
tapDown += 1;
|
//
|
||||||
} : null,
|
// We use a raw gesture detector directly here because gesture detector does
|
||||||
onTap: ButtonVariant.button == kPrimaryButton ? () {
|
// not expose callbacks for the tertiary variant of long presses, i.e. no onTertiaryLongPress*
|
||||||
tap += 1;
|
// callbacks are exposed in GestureDetector.
|
||||||
} : null,
|
//
|
||||||
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
|
// The primary and secondary long press callbacks could also be put into the gesture detector below,
|
||||||
tap += 1;
|
// however, it is clearer when they are all in one place.
|
||||||
} : null,
|
gestures: <Type, GestureRecognizerFactory>{
|
||||||
onTapCancel: ButtonVariant.button == kPrimaryButton ? () {
|
LongPressGestureRecognizer: GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
|
||||||
tapCancel += 1;
|
() => LongPressGestureRecognizer(),
|
||||||
} : null,
|
(LongPressGestureRecognizer instance) {
|
||||||
onSecondaryTapCancel: ButtonVariant.button == kSecondaryButton ? () {
|
instance
|
||||||
tapCancel += 1;
|
..onLongPress = ButtonVariant.button == kPrimaryButton ? () {
|
||||||
} : null,
|
longPress += 1;
|
||||||
onLongPress: ButtonVariant.button == kPrimaryButton ? () {
|
} : null
|
||||||
longPress += 1;
|
..onSecondaryLongPress = ButtonVariant.button == kSecondaryButton ? () {
|
||||||
} : null,
|
longPress += 1;
|
||||||
onSecondaryLongPress: ButtonVariant.button == kSecondaryButton ? () {
|
} : null
|
||||||
longPress += 1;
|
..onTertiaryLongPress = ButtonVariant.button == kTertiaryButton ? () {
|
||||||
} : null,
|
longPress += 1;
|
||||||
|
} : null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
child: GestureDetector(
|
||||||
|
onTapDown: ButtonVariant.button == kPrimaryButton ? (TapDownDetails details) {
|
||||||
|
tapDown += 1;
|
||||||
|
} : null,
|
||||||
|
onSecondaryTapDown: ButtonVariant.button == kSecondaryButton ? (TapDownDetails details) {
|
||||||
|
tapDown += 1;
|
||||||
|
} : null,
|
||||||
|
onTertiaryTapDown: ButtonVariant.button == kTertiaryButton ? (TapDownDetails details) {
|
||||||
|
tapDown += 1;
|
||||||
|
} : null,
|
||||||
|
onTap: ButtonVariant.button == kPrimaryButton ? () {
|
||||||
|
tap += 1;
|
||||||
|
} : null,
|
||||||
|
onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
|
||||||
|
tap += 1;
|
||||||
|
} : null,
|
||||||
|
onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (TapUpDetails details) {
|
||||||
|
tap += 1;
|
||||||
|
} : null,
|
||||||
|
onTapCancel: ButtonVariant.button == kPrimaryButton ? () {
|
||||||
|
tapCancel += 1;
|
||||||
|
} : null,
|
||||||
|
onSecondaryTapCancel: ButtonVariant.button == kSecondaryButton ? () {
|
||||||
|
tapCancel += 1;
|
||||||
|
} : null,
|
||||||
|
onTertiaryTapCancel: ButtonVariant.button == kTertiaryButton ? () {
|
||||||
|
tapCancel += 1;
|
||||||
|
} : null,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -358,13 +403,30 @@ void main() {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
height: 100.0,
|
height: 100.0,
|
||||||
color: const Color(0xFF00FF00),
|
color: const Color(0xFF00FF00),
|
||||||
child: GestureDetector(
|
child: RawGestureDetector(
|
||||||
onLongPressUp: ButtonVariant.button == kPrimaryButton ? () {
|
// We use a raw gesture detector directly here because gesture detector does
|
||||||
longPressUp += 1;
|
// not expose callbacks for the tertiary variant of long presses, i.e. no onTertiaryLongPress*
|
||||||
} : null,
|
// callbacks are exposed in GestureDetector, and we want to test all three variants.
|
||||||
onSecondaryLongPressUp: ButtonVariant.button == kSecondaryButton ? () {
|
//
|
||||||
longPressUp += 1;
|
// The primary and secondary long press callbacks could also be put into the gesture detector below,
|
||||||
} : null,
|
// however, it is more convenient to have them all in one place.
|
||||||
|
gestures: <Type, GestureRecognizerFactory>{
|
||||||
|
LongPressGestureRecognizer: GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
|
||||||
|
() => LongPressGestureRecognizer(),
|
||||||
|
(LongPressGestureRecognizer instance) {
|
||||||
|
instance
|
||||||
|
..onLongPressUp = ButtonVariant.button == kPrimaryButton ? () {
|
||||||
|
longPressUp += 1;
|
||||||
|
} : null
|
||||||
|
..onSecondaryLongPressUp = ButtonVariant.button == kSecondaryButton ? () {
|
||||||
|
longPressUp += 1;
|
||||||
|
} : null
|
||||||
|
..onTertiaryLongPressUp = ButtonVariant.button == kTertiaryButton ? () {
|
||||||
|
longPressUp += 1;
|
||||||
|
} : null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user