// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';

import 'semantics_tester.dart';

void main() {
  testWidgets('Vertical gesture detector has up/down actions', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    int callCount = 0;
    final GlobalKey detectorKey = GlobalKey();

    await tester.pumpWidget(
      Center(
        child: GestureDetector(
          key: detectorKey,
          onVerticalDragStart: (DragStartDetails _) {
            callCount += 1;
          },
          child: Container(),
        ),
      ),
    );

    expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.scrollUp, SemanticsAction.scrollDown]),
    );

    final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollLeft);
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollRight);
    expect(callCount, 0);
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollUp);
    expect(callCount, 1);
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollDown);
    expect(callCount, 2);

    semantics.dispose();
  });

  testWidgets('Horizontal gesture detector has up/down actions', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    int callCount = 0;
    final GlobalKey detectorKey = GlobalKey();

    await tester.pumpWidget(
        Center(
          child: GestureDetector(
            key: detectorKey,
            onHorizontalDragStart: (DragStartDetails _) {
              callCount += 1;
            },
            child: Container(),
          ),
        ),
    );

    expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.scrollLeft, SemanticsAction.scrollRight]),
    );

    final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollUp);
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollDown);
    expect(callCount, 0);
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollLeft);
    expect(callCount, 1);
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollRight);
    expect(callCount, 2);

    semantics.dispose();
  });

  testWidgets('All registered handlers for the gesture kind are called', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    final Set<String> logs = <String>{};
    final GlobalKey detectorKey = GlobalKey();

    await tester.pumpWidget(
      Center(
        child: GestureDetector(
          key: detectorKey,
          onHorizontalDragStart: (_) { logs.add('horizontal'); },
          onPanStart: (_) { logs.add('pan'); },
          child: Container(),
        ),
      ),
    );

    final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollLeft);
    expect(logs, <String>{'horizontal', 'pan'});

    semantics.dispose();
  });

  testWidgets('Replacing recognizers should update semantic handlers', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    // How the test is set up:
    //
    //  * In the base state, RawGestureDetector's recognizer is a HorizontalGR
    //  * Calling `introduceLayoutPerformer()` adds a `_TestLayoutPerformer` as
    //    child of RawGestureDetector, which invokes a given callback during
    //    layout phase.
    //  * The aforementioned callback replaces the detector's recognizer with a
    //    TapGR.
    //  * This test makes sure the replacement correctly updates semantics.

    final Set<String> logs = <String>{};
    final GlobalKey<RawGestureDetectorState> detectorKey = GlobalKey();
    final VoidCallback performLayout = () {
      detectorKey.currentState!.replaceGestureRecognizers(<Type, GestureRecognizerFactory>{
        TapGestureRecognizer: GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
          () => TapGestureRecognizer(),
          (TapGestureRecognizer instance) {
            instance.onTap = () { logs.add('tap'); };
          },
        ),
      });
    };

    bool hasLayoutPerformer = false;
    late VoidCallback introduceLayoutPerformer;
    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setter) {
          introduceLayoutPerformer = () {
            setter(() {
              hasLayoutPerformer = true;
            });
          };
          return Center(
            child: RawGestureDetector(
              key: detectorKey,
              gestures: <Type, GestureRecognizerFactory>{
                HorizontalDragGestureRecognizer: GestureRecognizerFactoryWithHandlers<HorizontalDragGestureRecognizer>(
                  () => HorizontalDragGestureRecognizer(),
                  (HorizontalDragGestureRecognizer instance) {
                    instance.onStart = (_) { logs.add('horizontal'); };
                  },
                ),
              },
              child: hasLayoutPerformer ? _TestLayoutPerformer(performLayout: performLayout) : null,
            ),
          );
        },
      ),
    );

    final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollLeft);
    expect(logs, <String>{'horizontal'});
    logs.clear();

    introduceLayoutPerformer();
    await tester.pumpAndSettle();

    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollLeft);
    tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.tap);
    expect(logs, <String>{'tap'});
    logs.clear();

    semantics.dispose();
  });

  group("RawGestureDetector's custom semantics delegate", () {
    testWidgets('should update semantics notations when switching from the default delegate', (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      final Map<Type, GestureRecognizerFactory> gestures =
        _buildGestureMap(() => LongPressGestureRecognizer(), null)
        ..addAll( _buildGestureMap(() => TapGestureRecognizer(), null));
      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            gestures: gestures,
            child: Container(),
          ),
        ),
      );

      expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.longPress, SemanticsAction.tap]),
      );

      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            gestures: gestures,
            semantics: _TestSemanticsGestureDelegate(onTap: () {}),
            child: Container(),
          ),
        ),
      );

      expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.tap]),
      );

      semantics.dispose();
    });

    testWidgets('should update semantics notations when switching to the default delegate', (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      final Map<Type, GestureRecognizerFactory> gestures =
        _buildGestureMap(() => LongPressGestureRecognizer(), null)
        ..addAll( _buildGestureMap(() => TapGestureRecognizer(), null));
      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            gestures: gestures,
            semantics: _TestSemanticsGestureDelegate(onTap: () {}),
            child: Container(),
          ),
        ),
      );

      expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.tap]),
      );

      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            gestures: gestures,
            child: Container(),
          ),
        ),
      );

      expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.longPress, SemanticsAction.tap]),
      );

      semantics.dispose();
    });

    testWidgets('should update semantics notations when switching from a different custom delegate', (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      final Map<Type, GestureRecognizerFactory> gestures =
        _buildGestureMap(() => LongPressGestureRecognizer(), null)
        ..addAll( _buildGestureMap(() => TapGestureRecognizer(), null));
      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            gestures: gestures,
            semantics: _TestSemanticsGestureDelegate(onTap: () {}),
            child: Container(),
          ),
        ),
      );

      expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.tap]),
      );

      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            gestures: gestures,
            semantics: _TestSemanticsGestureDelegate(onLongPress: () {}),
            child: Container(),
          ),
        ),
      );

      expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.longPress]),
      );

      semantics.dispose();
    });

    testWidgets('should correctly call callbacks', (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      final List<String> logs = <String>[];
      final GlobalKey<RawGestureDetectorState> detectorKey = GlobalKey();
      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            key: detectorKey,
            gestures: const <Type, GestureRecognizerFactory>{},
            semantics: _TestSemanticsGestureDelegate(
              onTap: () { logs.add('tap'); },
              onLongPress: () { logs.add('longPress'); },
              onHorizontalDragUpdate: (_) { logs.add('horizontal'); },
              onVerticalDragUpdate: (_) { logs.add('vertical'); },
            ),
            child: Container(),
          ),
        ),
      );

      final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
      tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.tap);
      expect(logs, <String>['tap']);
      logs.clear();

      tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.longPress);
      expect(logs, <String>['longPress']);
      logs.clear();

      tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollLeft);
      expect(logs, <String>['horizontal']);
      logs.clear();

      tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollUp);
      expect(logs, <String>['vertical']);
      logs.clear();

      semantics.dispose();
    });
  });

  group("RawGestureDetector's default semantics delegate", () {
    group('should map onTap to', () {
      testWidgets('null when there is no TapGR', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(null, null),
              child: Container(),
            ),
          ),
        );

        expect(semantics, isNot(includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.tap],
        )));

        semantics.dispose();
      });

      testWidgets('non-null when there is TapGR with no callbacks', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(
                () => TapGestureRecognizer(),
                null,
              ),
              child: Container(),
            ),
          ),
        );

        expect(semantics, includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.tap],
        ));

        semantics.dispose();
      });

      testWidgets('a callback that correctly calls callbacks', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        final GlobalKey detectorKey = GlobalKey();
        final List<String> logs = <String>[];
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              key: detectorKey,
              gestures: _buildGestureMap(
                () => TapGestureRecognizer(),
                (TapGestureRecognizer tap) {
                  tap
                    ..onTap = () {logs.add('tap');}
                    ..onTapUp = (_) {logs.add('tapUp');}
                    ..onTapDown = (_) {logs.add('tapDown');}
                    ..onTapCancel = () {logs.add('WRONG');}
                    ..onSecondaryTapDown = (_) {logs.add('WRONG');}
                    ..onTertiaryTapDown = (_) {logs.add('WRONG');};
                },
              ),
              child: Container(),
            ),
          ),
        );

        final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
        tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.tap);
        expect(logs, <String>['tapDown', 'tapUp', 'tap']);

        semantics.dispose();
      });
    });

    group('should map onLongPress to', () {
      testWidgets('null when there is no LongPressGR ', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(null, null),
              child: Container(),
            ),
          ),
        );

        expect(semantics, isNot(includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.longPress],
        )));

        semantics.dispose();
      });

      testWidgets('non-null when there is LongPressGR with no callbacks', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(
                () => LongPressGestureRecognizer(),
                null,
              ),
              child: Container(),
            ),
          ),
        );

        expect(semantics, includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.longPress],
        ));

        semantics.dispose();
      });

      testWidgets('a callback that correctly calls callbacks', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        final GlobalKey detectorKey = GlobalKey();
        final List<String> logs = <String>[];
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              key: detectorKey,
              gestures: _buildGestureMap(
                () => LongPressGestureRecognizer(),
                (LongPressGestureRecognizer longPress) {
                  longPress
                    ..onLongPress = () {logs.add('LP');}
                    ..onLongPressStart = (_) {logs.add('LPStart');}
                    ..onLongPressUp = () {logs.add('LPUp');}
                    ..onLongPressEnd = (_) {logs.add('LPEnd');}
                    ..onLongPressMoveUpdate = (_) {logs.add('WRONG');};
                },
              ),
              child: Container(),
            ),
          ),
        );

        final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
        tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.longPress);
        expect(logs, <String>['LPStart', 'LP', 'LPEnd', 'LPUp']);

        semantics.dispose();
      });
    });

    group('should map onHorizontalDragUpdate to', () {
      testWidgets('null when there is no matching recognizers ', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(null, null),
              child: Container(),
            ),
          ),
        );

        expect(semantics, isNot(includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.scrollLeft, SemanticsAction.scrollRight],
        )));

        semantics.dispose();
      });

      testWidgets('non-null when there is either matching recognizer with no callbacks', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(
                () => HorizontalDragGestureRecognizer(),
                null,
              ),
              child: Container(),
            ),
          ),
        );

        expect(semantics, includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.scrollLeft, SemanticsAction.scrollRight],
        ));

        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(
                () => PanGestureRecognizer(),
                null,
              ),
              child: Container(),
            ),
          ),
        );

        expect(semantics, includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.scrollLeft, SemanticsAction.scrollRight,
            SemanticsAction.scrollDown, SemanticsAction.scrollUp],
        ));

        semantics.dispose();
      });

      testWidgets('a callback that correctly calls callbacks', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        final GlobalKey detectorKey = GlobalKey();
        final List<String> logs = <String>[];
        final Map<Type, GestureRecognizerFactory> gestures = _buildGestureMap(
          () => HorizontalDragGestureRecognizer(),
          (HorizontalDragGestureRecognizer horizontal) {
            horizontal
              ..onStart = (_) {logs.add('HStart');}
              ..onDown = (_) {logs.add('HDown');}
              ..onEnd = (_) {logs.add('HEnd');}
              ..onUpdate = (_) {logs.add('HUpdate');}
              ..onCancel = () {logs.add('WRONG');};
          },
        )..addAll(_buildGestureMap(
          () => PanGestureRecognizer(),
          (PanGestureRecognizer pan) {
            pan
              ..onStart = (_) {logs.add('PStart');}
              ..onDown = (_) {logs.add('PDown');}
              ..onEnd = (_) {logs.add('PEnd');}
              ..onUpdate = (_) {logs.add('PUpdate');}
              ..onCancel = () {logs.add('WRONG');};
          },
        ));
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              key: detectorKey,
              gestures: gestures,
              child: Container(),
            ),
          ),
        );

        final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
        tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollLeft);
        expect(logs, <String>['HDown', 'HStart', 'HUpdate', 'HEnd',
          'PDown', 'PStart', 'PUpdate', 'PEnd',]);
        logs.clear();

        tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollLeft);
        expect(logs, <String>['HDown', 'HStart', 'HUpdate', 'HEnd',
          'PDown', 'PStart', 'PUpdate', 'PEnd',]);

        semantics.dispose();
      });
    });

    group('should map onVerticalDragUpdate to', () {
      testWidgets('null when there is no matching recognizers ', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(null, null),
              child: Container(),
            ),
          ),
        );

        expect(semantics, isNot(includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.scrollUp, SemanticsAction.scrollDown],
        )));

        semantics.dispose();
      });

      testWidgets('non-null when there is either matching recognizer with no callbacks', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              gestures: _buildGestureMap(
                () => VerticalDragGestureRecognizer(),
                null,
              ),
              child: Container(),
            ),
          ),
        );

        expect(semantics, includesNodeWith(
          actions: <SemanticsAction>[SemanticsAction.scrollUp, SemanticsAction.scrollDown],
        ));

        // Pan has bene tested in Horizontal

        semantics.dispose();
      });

      testWidgets('a callback that correctly calls callbacks', (WidgetTester tester) async {
        final SemanticsTester semantics = SemanticsTester(tester);
        final GlobalKey detectorKey = GlobalKey();
        final List<String> logs = <String>[];
        final Map<Type, GestureRecognizerFactory> gestures = _buildGestureMap(
          () => VerticalDragGestureRecognizer(),
          (VerticalDragGestureRecognizer horizontal) {
            horizontal
              ..onStart = (_) {logs.add('VStart');}
              ..onDown = (_) {logs.add('VDown');}
              ..onEnd = (_) {logs.add('VEnd');}
              ..onUpdate = (_) {logs.add('VUpdate');}
              ..onCancel = () {logs.add('WRONG');};
          },
        )..addAll(_buildGestureMap(
          () => PanGestureRecognizer(),
          (PanGestureRecognizer pan) {
            pan
              ..onStart = (_) {logs.add('PStart');}
              ..onDown = (_) {logs.add('PDown');}
              ..onEnd = (_) {logs.add('PEnd');}
              ..onUpdate = (_) {logs.add('PUpdate');}
              ..onCancel = () {logs.add('WRONG');};
          },
        ));
        await tester.pumpWidget(
          Center(
            child: RawGestureDetector(
              key: detectorKey,
              gestures: gestures,
              child: Container(),
            ),
          ),
        );

        final int detectorId = detectorKey.currentContext!.findRenderObject()!.debugSemantics!.id;
        tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollUp);
        expect(logs, <String>['VDown', 'VStart', 'VUpdate', 'VEnd',
          'PDown', 'PStart', 'PUpdate', 'PEnd',]);
        logs.clear();

        tester.binding.pipelineOwner.semanticsOwner!.performAction(detectorId, SemanticsAction.scrollDown);
        expect(logs, <String>['VDown', 'VStart', 'VUpdate', 'VEnd',
          'PDown', 'PStart', 'PUpdate', 'PEnd',]);

        semantics.dispose();
      });
    });

    testWidgets('should update semantics notations when receiving new gestures', (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            gestures: _buildGestureMap(() => LongPressGestureRecognizer(), null),
            child: Container(),
          ),
        ),
      );

      expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.longPress]),
      );

      await tester.pumpWidget(
        Center(
          child: RawGestureDetector(
            gestures: _buildGestureMap(() => TapGestureRecognizer(), null),
            child: Container(),
          ),
        ),
      );

      expect(semantics, includesNodeWith(
        actions: <SemanticsAction>[SemanticsAction.tap]),
      );

      semantics.dispose();
    });
  });
}

class _TestLayoutPerformer extends SingleChildRenderObjectWidget {
  const _TestLayoutPerformer({
    Key? key,
    required this.performLayout,
  }) : super(key: key);

  final VoidCallback performLayout;

  @override
  _RenderTestLayoutPerformer createRenderObject(BuildContext context) {
    return _RenderTestLayoutPerformer(performLayout: performLayout);
  }
}

class _RenderTestLayoutPerformer extends RenderBox {
  _RenderTestLayoutPerformer({required VoidCallback performLayout}) : _performLayout = performLayout;

  final VoidCallback _performLayout;

  @override
  void performLayout() {
    size = const Size(1, 1);
    if (_performLayout != null)
      _performLayout();
  }
}

Map<Type, GestureRecognizerFactory> _buildGestureMap<T extends GestureRecognizer>(
  GestureRecognizerFactoryConstructor<T>? constructor,
  GestureRecognizerFactoryInitializer<T>? initializer,
) {
  if (constructor == null)
    return <Type, GestureRecognizerFactory>{};
  return <Type, GestureRecognizerFactory>{
    T: GestureRecognizerFactoryWithHandlers<T>(
      constructor,
      initializer ?? (T o) {},
    ),
  };
}

class _TestSemanticsGestureDelegate extends SemanticsGestureDelegate {
  const _TestSemanticsGestureDelegate({
    this.onTap,
    this.onLongPress,
    this.onHorizontalDragUpdate,
    this.onVerticalDragUpdate,
  });

  final GestureTapCallback? onTap;
  final GestureLongPressCallback? onLongPress;
  final GestureDragUpdateCallback? onHorizontalDragUpdate;
  final GestureDragUpdateCallback? onVerticalDragUpdate;

  @override
  void assignSemantics(RenderSemanticsGestureHandler renderObject) {
    renderObject
      ..onTap = onTap
      ..onLongPress = onLongPress
      ..onHorizontalDragUpdate = onHorizontalDragUpdate
      ..onVerticalDragUpdate = onVerticalDragUpdate;
  }
}
