Skip to content

Commit

Permalink
Add allowedButtonsFilter to prevent Draggable from appearing with s…
Browse files Browse the repository at this point in the history
…econdary click. (#111852)

* DragTarget part 1.

[WIP] Change GestureRecognizer. Sorry.

[WIP] Move from GestureRecognizer to MultiDragGestureRecognizer.

Make it a `Set<int>?`

Get bitwise operations working.

Fix test. Rename to allowedInputPointers.

Convert into a builder.

Improve code with default funciton.

Refactor everything again.

Rename to buttonEventFilter.

Use static function.

Fix analyzer.

Fix private reference.

Use // in private method.

* Fix Renzo request.

* Add `allowedButtonsFilter` everywhere.

* Refactor monoDrag for multi pointer support.

* Fix tests?

* Change default to always true.

* Fix PR comments.

* Completely refactor long press.

* Add forgotten class.

* Revert "Completely refactor long press."

This reverts commit 5038e8603e250e8c928b0f1754fb794b7b75738b.

* Add default value to LongPress

* Refactor doubleTap.

* Relax double tap.

* Write comment in LongPress.

* Use template.
  • Loading branch information
bernaferrari committed Jan 13, 2023
1 parent 9024a70 commit 0752af8
Show file tree
Hide file tree
Showing 14 changed files with 358 additions and 52 deletions.
1 change: 1 addition & 0 deletions packages/flutter/lib/src/gestures/eager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class EagerGestureRecognizer extends OneSequenceGestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
});

@override
Expand Down
1 change: 1 addition & 0 deletions packages/flutter/lib/src/gestures/force_press.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
}) : assert(startPressure != null),
assert(peakPressure != null),
assert(interpolation != null),
Expand Down
9 changes: 9 additions & 0 deletions packages/flutter/lib/src/gestures/long_press.dart
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
/// The [duration] argument can be used to overwrite the default duration
/// after which the long press will be recognized.
///
/// {@macro flutter.gestures.tap.TapGestureRecognizer.allowedButtonsFilter}
///
/// {@macro flutter.gestures.GestureRecognizer.supportedDevices}
LongPressGestureRecognizer({
Duration? duration,
Expand All @@ -258,6 +260,7 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
super.kind,
super.supportedDevices,
super.debugOwner,
super.allowedButtonsFilter = _defaultButtonAcceptBehavior,
}) : super(
deadline: duration ?? kLongPressTimeout,
);
Expand All @@ -268,6 +271,12 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
// different set of buttons, the gesture is canceled.
int? _initialButtons;

// Accept the input if, and only if, a single button is pressed.
static bool _defaultButtonAcceptBehavior(int buttons) =>
buttons == kPrimaryButton ||
buttons == kSecondaryButton ||
buttons == kTertiaryButton;

/// Called when a pointer has contacted the screen at a particular location
/// with a primary button, which might be the start of a long-press.
///
Expand Down
45 changes: 20 additions & 25 deletions packages/flutter/lib/src/gestures/monodrag.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ typedef GestureVelocityTrackerBuilder = VelocityTracker Function(PointerEvent ev
/// consider using one of its subclasses to recognize specific types for drag
/// gestures.
///
/// [DragGestureRecognizer] competes on pointer events of [kPrimaryButton]
/// only when it has at least one non-null callback. If it has no callbacks, it
/// is a no-op.
/// [DragGestureRecognizer] competes on pointer events only when it has at
/// least one non-null callback. If it has no callbacks, it is a no-op.
///
/// See also:
///
Expand All @@ -84,10 +83,14 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
this.dragStartBehavior = DragStartBehavior.start,
this.velocityTrackerBuilder = _defaultBuilder,
super.supportedDevices,
super.allowedButtonsFilter = _defaultButtonAcceptBehavior,
}) : assert(dragStartBehavior != null);

static VelocityTracker _defaultBuilder(PointerEvent event) => VelocityTracker.withKind(event.kind);

// Accept the input if, and only if, [kPrimaryButton] is pressed.
static bool _defaultButtonAcceptBehavior(int buttons) => buttons == kPrimaryButton;

/// Configure the behavior of offsets passed to [onStart].
///
/// If set to [DragStartBehavior.start], the [onStart] callback will be called
Expand Down Expand Up @@ -122,7 +125,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
///
/// See also:
///
/// * [kPrimaryButton], the button this callback responds to.
/// * [allowedButtonsFilter], which decides which button will be allowed.
/// * [DragDownDetails], which is passed as an argument to this callback.
GestureDragDownCallback? onDown;

Expand All @@ -137,7 +140,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
///
/// See also:
///
/// * [kPrimaryButton], the button this callback responds to.
/// * [allowedButtonsFilter], which decides which button will be allowed.
/// * [DragStartDetails], which is passed as an argument to this callback.
GestureDragStartCallback? onStart;

Expand All @@ -151,7 +154,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
///
/// See also:
///
/// * [kPrimaryButton], the button this callback responds to.
/// * [allowedButtonsFilter], which decides which button will be allowed.
/// * [DragUpdateDetails], which is passed as an argument to this callback.
GestureDragUpdateCallback? onUpdate;

Expand All @@ -166,15 +169,15 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
///
/// See also:
///
/// * [kPrimaryButton], the button this callback responds to.
/// * [allowedButtonsFilter], which decides which button will be allowed.
/// * [DragEndDetails], which is passed as an argument to this callback.
GestureDragEndCallback? onEnd;

/// The pointer that previously triggered [onDown] did not complete.
///
/// See also:
///
/// * [kPrimaryButton], the button this callback responds to.
/// * [allowedButtonsFilter], which decides which button will be allowed.
GestureDragCancelCallback? onCancel;

/// The minimum distance an input pointer drag must have moved to
Expand Down Expand Up @@ -251,18 +254,12 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
@override
bool isPointerAllowed(PointerEvent event) {
if (_initialButtons == null) {
switch (event.buttons) {
case kPrimaryButton:
if (onDown == null &&
onStart == null &&
onUpdate == null &&
onEnd == null &&
onCancel == null) {
return false;
}
break;
default:
return false;
if (onDown == null &&
onStart == null &&
onUpdate == null &&
onEnd == null &&
onCancel == null) {
return false;
}
} else {
// There can be multiple drags simultaneously. Their effects are combined.
Expand Down Expand Up @@ -449,7 +446,6 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
}

void _checkDown() {
assert(_initialButtons == kPrimaryButton);
if (onDown != null) {
final DragDownDetails details = DragDownDetails(
globalPosition: _initialPosition.global,
Expand All @@ -460,7 +456,6 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
}

void _checkStart(Duration timestamp, int pointer) {
assert(_initialButtons == kPrimaryButton);
if (onStart != null) {
final DragStartDetails details = DragStartDetails(
sourceTimeStamp: timestamp,
Expand All @@ -479,7 +474,6 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
required Offset globalPosition,
Offset? localPosition,
}) {
assert(_initialButtons == kPrimaryButton);
if (onUpdate != null) {
final DragUpdateDetails details = DragUpdateDetails(
sourceTimeStamp: sourceTimeStamp,
Expand All @@ -493,7 +487,6 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
}

void _checkEnd(int pointer) {
assert(_initialButtons == kPrimaryButton);
if (onEnd == null) {
return;
}
Expand Down Expand Up @@ -530,7 +523,6 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
}

void _checkCancel() {
assert(_initialButtons == kPrimaryButton);
if (onCancel != null) {
invokeCallback<void>('onCancel', onCancel!);
}
Expand Down Expand Up @@ -570,6 +562,7 @@ class VerticalDragGestureRecognizer extends DragGestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
});

@override
Expand Down Expand Up @@ -616,6 +609,7 @@ class HorizontalDragGestureRecognizer extends DragGestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
});

@override
Expand Down Expand Up @@ -654,6 +648,7 @@ class PanGestureRecognizer extends DragGestureRecognizer {
PanGestureRecognizer({
super.debugOwner,
super.supportedDevices,
super.allowedButtonsFilter,
});

@override
Expand Down
8 changes: 8 additions & 0 deletions packages/flutter/lib/src/gestures/multidrag.dart
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,12 @@ abstract class MultiDragGestureRecognizer extends GestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter = _defaultButtonAcceptBehavior,
});

// Accept the input if, and only if, [kPrimaryButton] is pressed.
static bool _defaultButtonAcceptBehavior(int buttons) => buttons == kPrimaryButton;

/// Called when this class recognizes the start of a drag gesture.
///
/// The remaining notifications for this drag gesture are delivered to the
Expand Down Expand Up @@ -382,6 +386,7 @@ class ImmediateMultiDragGestureRecognizer extends MultiDragGestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
});

@override
Expand Down Expand Up @@ -439,6 +444,7 @@ class HorizontalMultiDragGestureRecognizer extends MultiDragGestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
});

@override
Expand Down Expand Up @@ -496,6 +502,7 @@ class VerticalMultiDragGestureRecognizer extends MultiDragGestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
});

@override
Expand Down Expand Up @@ -606,6 +613,7 @@ class DelayedMultiDragGestureRecognizer extends MultiDragGestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
}) : assert(delay != null);

/// The amount of time the pointer must remain in the same place for the drag
Expand Down
40 changes: 23 additions & 17 deletions packages/flutter/lib/src/gestures/multitap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ class _TapTracker {
/// Recognizes when the user has tapped the screen at the same location twice in
/// quick succession.
///
/// [DoubleTapGestureRecognizer] competes on pointer events of [kPrimaryButton]
/// only when it has a non-null callback. If it has no callbacks, it is a no-op.
/// [DoubleTapGestureRecognizer] competes on pointer events when it
/// has a non-null callback. If it has no callbacks, it is a no-op.
///
class DoubleTapGestureRecognizer extends GestureRecognizer {
/// Create a gesture recognizer for double taps.
Expand All @@ -128,8 +128,13 @@ class DoubleTapGestureRecognizer extends GestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter = _defaultButtonAcceptBehavior,
});

// The default value for [allowedButtonsFilter].
// Accept the input if, and only if, [kPrimaryButton] is pressed.
static bool _defaultButtonAcceptBehavior(int buttons) => buttons == kPrimaryButton;

// Implementation notes:
//
// The double tap recognizer can be in one of four states. There's no
Expand Down Expand Up @@ -165,7 +170,7 @@ class DoubleTapGestureRecognizer extends GestureRecognizer {
///
/// See also:
///
/// * [kPrimaryButton], the button this callback responds to.
/// * [allowedButtonsFilter], which decides which button will be allowed.
/// * [TapDownDetails], which is passed as an argument to this callback.
/// * [GestureDetector.onDoubleTapDown], which exposes this callback.
GestureTapDownCallback? onDoubleTapDown;
Expand All @@ -178,7 +183,7 @@ class DoubleTapGestureRecognizer extends GestureRecognizer {
///
/// See also:
///
/// * [kPrimaryButton], the button this callback responds to.
/// * [allowedButtonsFilter], which decides which button will be allowed.
/// * [GestureDetector.onDoubleTap], which exposes this callback.
GestureDoubleTapCallback? onDoubleTap;

Expand All @@ -192,7 +197,7 @@ class DoubleTapGestureRecognizer extends GestureRecognizer {
///
/// See also:
///
/// * [kPrimaryButton], the button this callback responds to.
/// * [allowedButtonsFilter], which decides which button will be allowed.
/// * [GestureDetector.onDoubleTapCancel], which exposes this callback.
GestureTapCancelCallback? onDoubleTapCancel;

Expand All @@ -203,19 +208,19 @@ class DoubleTapGestureRecognizer extends GestureRecognizer {
@override
bool isPointerAllowed(PointerDownEvent event) {
if (_firstTap == null) {
switch (event.buttons) {
case kPrimaryButton:
if (onDoubleTapDown == null &&
onDoubleTap == null &&
onDoubleTapCancel == null) {
return false;
}
break;
default:
return false;
if (onDoubleTapDown == null &&
onDoubleTap == null &&
onDoubleTapCancel == null) {
return false;
}
}
return super.isPointerAllowed(event);

// If second tap is not allowed, reset the state.
final bool isPointerAllowed = super.isPointerAllowed(event);
if (isPointerAllowed == false) {
_reset();
}
return isPointerAllowed;
}

@override
Expand Down Expand Up @@ -367,7 +372,6 @@ class DoubleTapGestureRecognizer extends GestureRecognizer {
}

void _checkUp(int buttons) {
assert(buttons == kPrimaryButton);
if (onDoubleTap != null) {
invokeCallback<void>('onDoubleTap', onDoubleTap!);
}
Expand Down Expand Up @@ -492,6 +496,7 @@ class MultiTapGestureRecognizer extends GestureRecognizer {
)
super.kind,
super.supportedDevices,
super.allowedButtonsFilter,
});

/// A pointer that might cause a tap has contacted the screen at a particular
Expand Down Expand Up @@ -813,6 +818,7 @@ class SerialTapGestureRecognizer extends GestureRecognizer {
SerialTapGestureRecognizer({
super.debugOwner,
super.supportedDevices,
super.allowedButtonsFilter,
});

/// A pointer has contacted the screen at a particular location, which might
Expand Down
Loading

0 comments on commit 0752af8

Please sign in to comment.