mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Move TapAndDragGestureRecognizer code under gestures (#119508)
This commit is contained in:
parent
3213588c03
commit
e4e9dde4ed
@ -30,5 +30,6 @@ export 'src/gestures/recognizer.dart';
|
||||
export 'src/gestures/resampler.dart';
|
||||
export 'src/gestures/scale.dart';
|
||||
export 'src/gestures/tap.dart';
|
||||
export 'src/gestures/tap_and_drag.dart';
|
||||
export 'src/gestures/team.dart';
|
||||
export 'src/gestures/velocity_tracker.dart';
|
||||
|
@ -5,11 +5,13 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/services.dart' show HardwareKeyboard, LogicalKeyboardKey;
|
||||
|
||||
import 'framework.dart';
|
||||
import 'gesture_detector.dart';
|
||||
import 'constants.dart';
|
||||
import 'events.dart';
|
||||
import 'monodrag.dart';
|
||||
import 'recognizer.dart';
|
||||
import 'scale.dart';
|
||||
import 'tap.dart';
|
||||
|
||||
// Examples can assume:
|
||||
// void setState(VoidCallback fn) { }
|
||||
@ -75,14 +77,13 @@ typedef GestureTapDragDownCallback = void Function(TapDragDownDetails details);
|
||||
class TapDragDownDetails with Diagnosticable {
|
||||
/// Creates details for a [GestureTapDragDownCallback].
|
||||
///
|
||||
/// The [globalPosition], [localPosition], [consecutiveTapCount], and
|
||||
/// [keysPressedOnDown] arguments must be provided and must not be null.
|
||||
/// The [globalPosition], [localPosition], and [consecutiveTapCount]
|
||||
/// arguments must be provided and must not be null.
|
||||
TapDragDownDetails({
|
||||
required this.globalPosition,
|
||||
required this.localPosition,
|
||||
this.kind,
|
||||
required this.consecutiveTapCount,
|
||||
required this.keysPressedOnDown,
|
||||
});
|
||||
|
||||
/// The global position at which the pointer contacted the screen.
|
||||
@ -98,9 +99,6 @@ class TapDragDownDetails with Diagnosticable {
|
||||
/// the number in the series this tap is.
|
||||
final int consecutiveTapCount;
|
||||
|
||||
/// The keys that were pressed when the most recent [PointerDownEvent] occurred.
|
||||
final Set<LogicalKeyboardKey> keysPressedOnDown;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
@ -108,7 +106,6 @@ class TapDragDownDetails with Diagnosticable {
|
||||
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
|
||||
properties.add(DiagnosticsProperty<PointerDeviceKind?>('kind', kind));
|
||||
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
|
||||
properties.add(DiagnosticsProperty<Set<LogicalKeyboardKey>>('keysPressedOnDown', keysPressedOnDown));
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,14 +131,13 @@ typedef GestureTapDragUpCallback = void Function(TapDragUpDetails details);
|
||||
class TapDragUpDetails with Diagnosticable {
|
||||
/// Creates details for a [GestureTapDragUpCallback].
|
||||
///
|
||||
/// The [kind], [globalPosition], [localPosition], [consecutiveTapCount], and
|
||||
/// [keysPressedOnDown] arguments must be provided and must not be null.
|
||||
/// The [kind], [globalPosition], [localPosition], and [consecutiveTapCount]
|
||||
/// arguments must be provided and must not be null.
|
||||
TapDragUpDetails({
|
||||
required this.kind,
|
||||
required this.globalPosition,
|
||||
required this.localPosition,
|
||||
required this.consecutiveTapCount,
|
||||
required this.keysPressedOnDown,
|
||||
});
|
||||
|
||||
/// The global position at which the pointer contacted the screen.
|
||||
@ -157,9 +153,6 @@ class TapDragUpDetails with Diagnosticable {
|
||||
/// the number in the series this tap is.
|
||||
final int consecutiveTapCount;
|
||||
|
||||
/// The keys that were pressed when the most recent [PointerDownEvent] occurred.
|
||||
final Set<LogicalKeyboardKey> keysPressedOnDown;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
@ -167,7 +160,6 @@ class TapDragUpDetails with Diagnosticable {
|
||||
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
|
||||
properties.add(DiagnosticsProperty<PointerDeviceKind?>('kind', kind));
|
||||
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
|
||||
properties.add(DiagnosticsProperty<Set<LogicalKeyboardKey>>('keysPressedOnDown', keysPressedOnDown));
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,15 +185,14 @@ typedef GestureTapDragStartCallback = void Function(TapDragStartDetails details)
|
||||
class TapDragStartDetails with Diagnosticable {
|
||||
/// Creates details for a [GestureTapDragStartCallback].
|
||||
///
|
||||
/// The [globalPosition], [localPosition], [consecutiveTapCount], and
|
||||
/// [keysPressedOnDown] arguments must be provided and must not be null.
|
||||
/// The [globalPosition], [localPosition], and [consecutiveTapCount]
|
||||
/// arguments must be provided and must not be null.
|
||||
TapDragStartDetails({
|
||||
this.sourceTimeStamp,
|
||||
required this.globalPosition,
|
||||
required this.localPosition,
|
||||
this.kind,
|
||||
required this.consecutiveTapCount,
|
||||
required this.keysPressedOnDown,
|
||||
});
|
||||
|
||||
/// Recorded timestamp of the source pointer event that triggered the drag
|
||||
@ -229,9 +220,6 @@ class TapDragStartDetails with Diagnosticable {
|
||||
/// the number in the series this tap is.
|
||||
final int consecutiveTapCount;
|
||||
|
||||
/// The keys that were pressed when the most recent [PointerDownEvent] occurred.
|
||||
final Set<LogicalKeyboardKey> keysPressedOnDown;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
@ -240,7 +228,6 @@ class TapDragStartDetails with Diagnosticable {
|
||||
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
|
||||
properties.add(DiagnosticsProperty<PointerDeviceKind?>('kind', kind));
|
||||
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
|
||||
properties.add(DiagnosticsProperty<Set<LogicalKeyboardKey>>('keysPressedOnDown', keysPressedOnDown));
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,8 +259,7 @@ class TapDragUpdateDetails with Diagnosticable {
|
||||
/// coordinates of [delta] and the other coordinate must be zero.
|
||||
///
|
||||
/// The [globalPosition], [localPosition], [offsetFromOrigin], [localOffsetFromOrigin],
|
||||
/// [consecutiveTapCount], and [keysPressedOnDown] arguments must be provided and must
|
||||
/// not be null.
|
||||
/// and [consecutiveTapCount] arguments must be provided and must not be null.
|
||||
TapDragUpdateDetails({
|
||||
this.sourceTimeStamp,
|
||||
this.delta = Offset.zero,
|
||||
@ -284,7 +270,6 @@ class TapDragUpdateDetails with Diagnosticable {
|
||||
required this.offsetFromOrigin,
|
||||
required this.localOffsetFromOrigin,
|
||||
required this.consecutiveTapCount,
|
||||
required this.keysPressedOnDown,
|
||||
}) : assert(
|
||||
primaryDelta == null
|
||||
|| (primaryDelta == delta.dx && delta.dy == 0.0)
|
||||
@ -357,9 +342,6 @@ class TapDragUpdateDetails with Diagnosticable {
|
||||
/// the number in the series this tap is.
|
||||
final int consecutiveTapCount;
|
||||
|
||||
/// The keys that were pressed when the most recent [PointerDownEvent] occurred.
|
||||
final Set<LogicalKeyboardKey> keysPressedOnDown;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
@ -372,7 +354,6 @@ class TapDragUpdateDetails with Diagnosticable {
|
||||
properties.add(DiagnosticsProperty<Offset>('offsetFromOrigin', offsetFromOrigin));
|
||||
properties.add(DiagnosticsProperty<Offset>('localOffsetFromOrigin', localOffsetFromOrigin));
|
||||
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
|
||||
properties.add(DiagnosticsProperty<Set<LogicalKeyboardKey>>('keysPressedOnDown', keysPressedOnDown));
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,13 +381,11 @@ class TapDragEndDetails with Diagnosticable {
|
||||
///
|
||||
/// The [velocity] argument must not be null.
|
||||
///
|
||||
/// The [consecutiveTapCount], and [keysPressedOnDown] arguments must
|
||||
/// be provided and must not be null.
|
||||
/// The [consecutiveTapCount] argument must be provided and must not be null.
|
||||
TapDragEndDetails({
|
||||
this.velocity = Velocity.zero,
|
||||
this.primaryVelocity,
|
||||
required this.consecutiveTapCount,
|
||||
required this.keysPressedOnDown,
|
||||
}) : assert(
|
||||
primaryVelocity == null
|
||||
|| primaryVelocity == velocity.pixelsPerSecond.dx
|
||||
@ -434,16 +413,12 @@ class TapDragEndDetails with Diagnosticable {
|
||||
/// the number in the series this tap is.
|
||||
final int consecutiveTapCount;
|
||||
|
||||
/// The keys that were pressed when the most recent [PointerDownEvent] occurred.
|
||||
final Set<LogicalKeyboardKey> keysPressedOnDown;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(DiagnosticsProperty<Velocity>('velocity', velocity));
|
||||
properties.add(DiagnosticsProperty<double?>('primaryVelocity', primaryVelocity));
|
||||
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
|
||||
properties.add(DiagnosticsProperty<Set<LogicalKeyboardKey>>('keysPressedOnDown', keysPressedOnDown));
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,15 +481,6 @@ mixin _TapStatusTrackerMixin on OneSequenceGestureRecognizer {
|
||||
// this value will be set to `0`, and a new series will begin.
|
||||
int get consecutiveTapCount => _consecutiveTapCount;
|
||||
|
||||
// The set of [LogicalKeyboardKey]s pressed when the most recent [PointerDownEvent]
|
||||
// was tracked in [addAllowedPointer].
|
||||
//
|
||||
// This value defaults to an empty set.
|
||||
//
|
||||
// When the timer between two taps elapses, the recognizer loses the arena, the gesture is cancelled
|
||||
// or the recognizer is disposed of then this value is reset.
|
||||
Set<LogicalKeyboardKey> get keysPressedOnDown => _keysPressedOnDown ?? <LogicalKeyboardKey>{};
|
||||
|
||||
// The upper limit for the [consecutiveTapCount]. When this limit is reached
|
||||
// all tap related state is reset and a new tap series is tracked.
|
||||
//
|
||||
@ -525,7 +491,6 @@ mixin _TapStatusTrackerMixin on OneSequenceGestureRecognizer {
|
||||
PointerDownEvent? _down;
|
||||
PointerUpEvent? _up;
|
||||
int _consecutiveTapCount = 0;
|
||||
Set<LogicalKeyboardKey>? _keysPressedOnDown;
|
||||
|
||||
OffsetPair? _originPosition;
|
||||
int? _previousButtons;
|
||||
@ -534,6 +499,21 @@ mixin _TapStatusTrackerMixin on OneSequenceGestureRecognizer {
|
||||
Timer? _consecutiveTapTimer;
|
||||
Offset? _lastTapOffset;
|
||||
|
||||
/// {@template flutter.gestures.selectionrecognizers.BaseTapAndDragGestureRecognizer.onTapTrackStart}
|
||||
/// Callback used to indicate that a tap tracking has started upon
|
||||
/// a [PointerDownEvent].
|
||||
/// {@endtemplate}
|
||||
VoidCallback? onTapTrackStart;
|
||||
|
||||
/// {@template flutter.gestures.selectionrecognizers.BaseTapAndDragGestureRecognizer.onTapTrackReset}
|
||||
/// Callback used to indicate that a tap tracking has been reset which
|
||||
/// happens on the next [PointerDownEvent] after the timer between two taps
|
||||
/// elapses, the recognizer loses the arena, the gesture is cancelled or
|
||||
/// the recognizer is disposed of.
|
||||
/// {@endtemplate}
|
||||
|
||||
VoidCallback? onTapTrackReset;
|
||||
|
||||
// When tracking a tap, the [consecutiveTapCount] is incremented if the given tap
|
||||
// falls under the tolerance specifications and reset to 1 if not.
|
||||
@override
|
||||
@ -595,10 +575,10 @@ mixin _TapStatusTrackerMixin on OneSequenceGestureRecognizer {
|
||||
|
||||
void _trackTap(PointerDownEvent event) {
|
||||
_down = event;
|
||||
_keysPressedOnDown = HardwareKeyboard.instance.logicalKeysPressed;
|
||||
_previousButtons = event.buttons;
|
||||
_lastTapOffset = event.position;
|
||||
_originPosition = OffsetPair(local: event.localPosition, global: event.position);
|
||||
onTapTrackStart?.call();
|
||||
}
|
||||
|
||||
bool _hasSameButton(int buttons) {
|
||||
@ -653,9 +633,9 @@ mixin _TapStatusTrackerMixin on OneSequenceGestureRecognizer {
|
||||
_originPosition = null;
|
||||
_lastTapOffset = null;
|
||||
_consecutiveTapCount = 0;
|
||||
_keysPressedOnDown = null;
|
||||
_down = null;
|
||||
_up = null;
|
||||
onTapTrackReset?.call();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1204,7 +1184,6 @@ sealed class BaseTapAndDragGestureRecognizer extends OneSequenceGestureRecognize
|
||||
localPosition: event.localPosition,
|
||||
kind: getKindForPointer(event.pointer),
|
||||
consecutiveTapCount: consecutiveTapCount,
|
||||
keysPressedOnDown: keysPressedOnDown,
|
||||
);
|
||||
|
||||
if (onTapDown != null) {
|
||||
@ -1224,7 +1203,6 @@ sealed class BaseTapAndDragGestureRecognizer extends OneSequenceGestureRecognize
|
||||
globalPosition: event.position,
|
||||
localPosition: event.localPosition,
|
||||
consecutiveTapCount: consecutiveTapCount,
|
||||
keysPressedOnDown: keysPressedOnDown,
|
||||
);
|
||||
|
||||
if (onTapUp != null) {
|
||||
@ -1245,7 +1223,6 @@ sealed class BaseTapAndDragGestureRecognizer extends OneSequenceGestureRecognize
|
||||
localPosition: _initialPosition.local,
|
||||
kind: getKindForPointer(event.pointer),
|
||||
consecutiveTapCount: consecutiveTapCount,
|
||||
keysPressedOnDown: keysPressedOnDown,
|
||||
);
|
||||
|
||||
invokeCallback<void>('onDragStart', () => onDragStart!(details));
|
||||
@ -1267,7 +1244,6 @@ sealed class BaseTapAndDragGestureRecognizer extends OneSequenceGestureRecognize
|
||||
offsetFromOrigin: globalPosition - _initialPosition.global,
|
||||
localOffsetFromOrigin: localPosition - _initialPosition.local,
|
||||
consecutiveTapCount: consecutiveTapCount,
|
||||
keysPressedOnDown: keysPressedOnDown,
|
||||
);
|
||||
|
||||
if (dragUpdateThrottleFrequency != null) {
|
||||
@ -1293,7 +1269,6 @@ sealed class BaseTapAndDragGestureRecognizer extends OneSequenceGestureRecognize
|
||||
TapDragEndDetails(
|
||||
primaryVelocity: 0.0,
|
||||
consecutiveTapCount: consecutiveTapCount,
|
||||
keysPressedOnDown: keysPressedOnDown,
|
||||
);
|
||||
|
||||
if (onDragEnd != null) {
|
@ -24,7 +24,6 @@ import 'gesture_detector.dart';
|
||||
import 'magnifier.dart';
|
||||
import 'overlay.dart';
|
||||
import 'scrollable.dart';
|
||||
import 'tap_and_drag_gestures.dart';
|
||||
import 'tap_region.dart';
|
||||
import 'ticker_provider.dart';
|
||||
import 'transitions.dart';
|
||||
@ -1993,11 +1992,6 @@ class TextSelectionGestureDetectorBuilder {
|
||||
&& targetSelection.end >= textPosition.offset;
|
||||
}
|
||||
|
||||
/// Returns true if shift left or right is contained in the given set.
|
||||
static bool _containsShift(Set<LogicalKeyboardKey> keysPressed) {
|
||||
return keysPressed.any(<LogicalKeyboardKey>{ LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.shiftRight }.contains);
|
||||
}
|
||||
|
||||
// Expand the selection to the given global position.
|
||||
//
|
||||
// Either base or extent will be moved to the last tapped position, whichever
|
||||
@ -2074,6 +2068,10 @@ class TextSelectionGestureDetectorBuilder {
|
||||
@protected
|
||||
RenderEditable get renderEditable => editableText.renderEditable;
|
||||
|
||||
/// Whether the Shift key was pressed when the most recent [PointerDownEvent]
|
||||
/// was tracked by the [BaseTapAndDragGestureRecognizer].
|
||||
bool _isShiftPressed = false;
|
||||
|
||||
/// The viewport offset pixels of any [Scrollable] containing the
|
||||
/// [RenderEditable] at the last drag start.
|
||||
double _dragStartScrollOffset = 0.0;
|
||||
@ -2113,6 +2111,30 @@ class TextSelectionGestureDetectorBuilder {
|
||||
// focused, the cursor moves to the long press position.
|
||||
bool _longPressStartedWithoutFocus = false;
|
||||
|
||||
/// Handler for [TextSelectionGestureDetector.onTapTrackStart].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [TextSelectionGestureDetector.onTapTrackStart], which triggers this
|
||||
/// callback.
|
||||
@protected
|
||||
void onTapTrackStart() {
|
||||
_isShiftPressed = HardwareKeyboard.instance.logicalKeysPressed
|
||||
.intersection(<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.shiftRight})
|
||||
.isNotEmpty;
|
||||
}
|
||||
|
||||
/// Handler for [TextSelectionGestureDetector.onTapTrackReset].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [TextSelectionGestureDetector.onTapTrackReset], which triggers this
|
||||
/// callback.
|
||||
@protected
|
||||
void onTapTrackReset() {
|
||||
_isShiftPressed = false;
|
||||
}
|
||||
|
||||
/// Handler for [TextSelectionGestureDetector.onTapDown].
|
||||
///
|
||||
/// By default, it forwards the tap to [RenderEditable.handleTapDown] and sets
|
||||
@ -2145,11 +2167,9 @@ class TextSelectionGestureDetectorBuilder {
|
||||
|| kind == PointerDeviceKind.touch
|
||||
|| kind == PointerDeviceKind.stylus;
|
||||
|
||||
// Handle shift + click selection if needed.
|
||||
final bool isShiftPressed = _containsShift(details.keysPressedOnDown);
|
||||
// It is impossible to extend the selection when the shift key is pressed, if the
|
||||
// renderEditable.selection is invalid.
|
||||
final bool isShiftPressedValid = isShiftPressed && renderEditable.selection?.baseOffset != null;
|
||||
final bool isShiftPressedValid = _isShiftPressed && renderEditable.selection?.baseOffset != null;
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
@ -2246,11 +2266,9 @@ class TextSelectionGestureDetectorBuilder {
|
||||
@protected
|
||||
void onSingleTapUp(TapDragUpDetails details) {
|
||||
if (delegate.selectionEnabled) {
|
||||
// Handle shift + click selection if needed.
|
||||
final bool isShiftPressed = _containsShift(details.keysPressedOnDown);
|
||||
// It is impossible to extend the selection when the shift key is pressed, if the
|
||||
// renderEditable.selection is invalid.
|
||||
final bool isShiftPressedValid = isShiftPressed && renderEditable.selection?.baseOffset != null;
|
||||
final bool isShiftPressedValid = _isShiftPressed && renderEditable.selection?.baseOffset != null;
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.linux:
|
||||
case TargetPlatform.macOS:
|
||||
@ -2641,9 +2659,7 @@ class TextSelectionGestureDetectorBuilder {
|
||||
return;
|
||||
}
|
||||
|
||||
final bool isShiftPressed = _containsShift(details.keysPressedOnDown);
|
||||
|
||||
if (isShiftPressed && renderEditable.selection != null && renderEditable.selection!.isValid) {
|
||||
if (_isShiftPressed && renderEditable.selection != null && renderEditable.selection!.isValid) {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
@ -2730,9 +2746,7 @@ class TextSelectionGestureDetectorBuilder {
|
||||
return;
|
||||
}
|
||||
|
||||
final bool isShiftPressed = _containsShift(details.keysPressedOnDown);
|
||||
|
||||
if (!isShiftPressed) {
|
||||
if (!_isShiftPressed) {
|
||||
// Adjust the drag start offset for possible viewport offset changes.
|
||||
final Offset editableOffset = renderEditable.maxLines == 1
|
||||
? Offset(renderEditable.offset.pixels - _dragStartViewportOffset, 0.0)
|
||||
@ -2931,14 +2945,13 @@ class TextSelectionGestureDetectorBuilder {
|
||||
/// callback.
|
||||
@protected
|
||||
void onDragSelectionEnd(TapDragEndDetails details) {
|
||||
final bool isShiftPressed = _containsShift(details.keysPressedOnDown);
|
||||
_dragBeganOnPreviousSelection = null;
|
||||
|
||||
if (_shouldShowSelectionToolbar && _TextSelectionGestureDetectorState._getEffectiveConsecutiveTapCount(details.consecutiveTapCount) == 2) {
|
||||
editableText.showToolbar();
|
||||
}
|
||||
|
||||
if (isShiftPressed) {
|
||||
if (_isShiftPressed) {
|
||||
_dragStartSelection = null;
|
||||
}
|
||||
|
||||
@ -2956,6 +2969,8 @@ class TextSelectionGestureDetectorBuilder {
|
||||
}) {
|
||||
return TextSelectionGestureDetector(
|
||||
key: key,
|
||||
onTapTrackStart: onTapTrackStart,
|
||||
onTapTrackReset: onTapTrackReset,
|
||||
onTapDown: onTapDown,
|
||||
onForcePressStart: delegate.forcePressEnabled ? onForcePressStart : null,
|
||||
onForcePressEnd: delegate.forcePressEnabled ? onForcePressEnd : null,
|
||||
@ -2996,6 +3011,8 @@ class TextSelectionGestureDetector extends StatefulWidget {
|
||||
/// The [child] parameter must not be null.
|
||||
const TextSelectionGestureDetector({
|
||||
super.key,
|
||||
this.onTapTrackStart,
|
||||
this.onTapTrackReset,
|
||||
this.onTapDown,
|
||||
this.onForcePressStart,
|
||||
this.onForcePressEnd,
|
||||
@ -3015,6 +3032,12 @@ class TextSelectionGestureDetector extends StatefulWidget {
|
||||
required this.child,
|
||||
});
|
||||
|
||||
/// {@macro flutter.gestures.selectionrecognizers.BaseTapAndDragGestureRecognizer.onTapTrackStart}
|
||||
final VoidCallback? onTapTrackStart;
|
||||
|
||||
/// {@macro flutter.gestures.selectionrecognizers.BaseTapAndDragGestureRecognizer.onTapTrackReset}
|
||||
final VoidCallback? onTapTrackReset;
|
||||
|
||||
/// Called for every tap down including every tap down that's part of a
|
||||
/// double click or a long press, except touches that include enough movement
|
||||
/// to not qualify as taps (e.g. pans and flings).
|
||||
@ -3125,6 +3148,14 @@ class _TextSelectionGestureDetectorState extends State<TextSelectionGestureDetec
|
||||
}
|
||||
}
|
||||
|
||||
void _handleTapTrackStart() {
|
||||
widget.onTapTrackStart?.call();
|
||||
}
|
||||
|
||||
void _handleTapTrackReset() {
|
||||
widget.onTapTrackReset?.call();
|
||||
}
|
||||
|
||||
// The down handler is force-run on success of a single tap and optimistically
|
||||
// run before a long press success.
|
||||
void _handleTapDown(TapDragDownDetails details) {
|
||||
@ -3231,6 +3262,8 @@ class _TextSelectionGestureDetectorState extends State<TextSelectionGestureDetec
|
||||
// Text selection should start from the position of the first pointer
|
||||
// down event.
|
||||
..dragStartBehavior = DragStartBehavior.down
|
||||
..onTapTrackStart = _handleTapTrackStart
|
||||
..onTapTrackReset = _handleTapTrackReset
|
||||
..onTapDown = _handleTapDown
|
||||
..onDragStart = _handleDragStart
|
||||
..onDragUpdate = _handleDragUpdate
|
||||
@ -3249,6 +3282,8 @@ class _TextSelectionGestureDetectorState extends State<TextSelectionGestureDetec
|
||||
// Text selection should start from the position of the first pointer
|
||||
// down event.
|
||||
..dragStartBehavior = DragStartBehavior.down
|
||||
..onTapTrackStart = _handleTapTrackStart
|
||||
..onTapTrackReset = _handleTapTrackReset
|
||||
..onTapDown = _handleTapDown
|
||||
..onDragStart = _handleDragStart
|
||||
..onDragUpdate = _handleDragUpdate
|
||||
|
@ -140,7 +140,6 @@ export 'src/widgets/spacer.dart';
|
||||
export 'src/widgets/spell_check.dart';
|
||||
export 'src/widgets/status_transitions.dart';
|
||||
export 'src/widgets/table.dart';
|
||||
export 'src/widgets/tap_and_drag_gestures.dart';
|
||||
export 'src/widgets/tap_region.dart';
|
||||
export 'src/widgets/text.dart';
|
||||
export 'src/widgets/text_editing_intents.dart';
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../gestures/gesture_tester.dart';
|
@ -3,7 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/foundation.dart' show ValueListenable, defaultTargetPlatform;
|
||||
import 'package:flutter/gestures.dart' show PointerDeviceKind, kSecondaryButton;
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
Loading…
Reference in New Issue
Block a user