applyBasicGesturesDetectors function

Widget applyBasicGesturesDetectors(
  1. Stage stage,
  2. Widget child
)

Implementation

Widget applyBasicGesturesDetectors(Stage stage, Widget child) {
  final isTapMixin = stage is TapDetectorMixin;
  final isDoubleTapMixin = stage is DoubleTapDetectorMixin;

  if (!isTapMixin && !isDoubleTapMixin) return child;

  final onlyDoubleTap = isDoubleTapMixin && !isTapMixin;

  int tapDownTime = 0;
  Offset tapDownPosition = Offset.zero;
  bool doubleTapMode = false;

  void reset() {
    doubleTapMode = false;
    tapDownTime = 0;
    tapDownPosition = Offset.zero;
  }

  return GestureDetector(
    key: const ObjectKey('BasicGesturesDetector'),
    behavior: HitTestBehavior.opaque,

    // Taps & Double Taps
    onTapDown: isTapMixin
        ? (TapDownDetails details) {
            final info = TapDownInfo.fromDetails(stage, details);
            final now = DateTime.now().microsecondsSinceEpoch;

            doubleTapMode = now - tapDownTime <= kDoubleTapTimeout.inMicroseconds &&
                (details.localPosition - tapDownPosition).distance < kDoubleTapSlop;
            tapDownTime = now;
            tapDownPosition = details.localPosition;

            isDoubleTapMixin && doubleTapMode
                ? (stage as DoubleTapDetectorMixin).onDoubleTapDown(info)
                : stage.onTapDown(info);
          }
        : null,
    onTapUp: isTapMixin
        ? (TapUpDetails details) {
            isDoubleTapMixin && doubleTapMode
                ? null
                : stage.onTapUp(TapUpInfo.fromDetails(stage, details));
          }
        : null,
    onTap: isTapMixin
        ? () {
            isDoubleTapMixin && doubleTapMode
                ? (stage as DoubleTapDetectorMixin).onDoubleTap()
                : stage.onTap();

            if (doubleTapMode) reset();
          }
        : null,
    onTapCancel: isTapMixin
        ? () {
            isDoubleTapMixin && doubleTapMode
                ? (stage as DoubleTapDetectorMixin).onDoubleTapCancel()
                : stage.onTapCancel();
            reset();
          }
        : null,

    // Double Taps
    onDoubleTapDown: onlyDoubleTap
        ? (TapDownDetails details) => stage.onDoubleTapDown(TapDownInfo.fromDetails(stage, details))
        : null,
    onDoubleTap: onlyDoubleTap ? () => stage.onDoubleTap() : null,
    onDoubleTapCancel: onlyDoubleTap ? () => stage.onDoubleTapCancel() : null,

    child: child,
  );
}