diff --git a/packages/flame/lib/src/game/game_widget/game_widget.dart b/packages/flame/lib/src/game/game_widget/game_widget.dart index 0ce160091cd..b0237464b60 100644 --- a/packages/flame/lib/src/game/game_widget/game_widget.dart +++ b/packages/flame/lib/src/game/game_widget/game_widget.dart @@ -304,15 +304,8 @@ class _GameWidgetState extends State> { 'not receive events', ); - if (hasBasicGestureDetectors(currentGame)) { - internalGameWidget = applyBasicGesturesDetectors( - currentGame, - internalGameWidget, - ); - } - - if (hasAdvancedGestureDetectors(currentGame)) { - internalGameWidget = applyAdvancedGesturesDetectors( + if (hasGestureDetectors(currentGame)) { + internalGameWidget = applyGesturesDetectors( currentGame, internalGameWidget, ); diff --git a/packages/flame/lib/src/game/game_widget/gestures.dart b/packages/flame/lib/src/game/game_widget/gestures.dart index bf78c7dd582..ddd1fc336e3 100644 --- a/packages/flame/lib/src/game/game_widget/gestures.dart +++ b/packages/flame/lib/src/game/game_widget/gestures.dart @@ -4,7 +4,7 @@ import 'package:flame/src/game/mixins/game.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; -bool hasBasicGestureDetectors(Game game) { +bool hasGestureDetectors(Game game) { return game is TapDetector || game is SecondaryTapDetector || game is DoubleTapDetector || @@ -13,11 +13,8 @@ bool hasBasicGestureDetectors(Game game) { game is HorizontalDragDetector || game is ForcePressDetector || game is PanDetector || - game is ScaleDetector; -} - -bool hasAdvancedGestureDetectors(Game game) { - return game is MultiTapListener || + game is ScaleDetector || + game is MultiTapListener || game is MultiTouchDragDetector || game is HasDraggables; } @@ -28,155 +25,7 @@ bool hasMouseDetectors(Game game) { game is HasHoverables; } -Widget applyBasicGesturesDetectors(Game game, Widget child) { - return GestureDetector( - key: const ObjectKey('BasicGesturesDetector'), - behavior: HitTestBehavior.opaque, - - // Taps - onTap: game is TapDetector ? () => game.onTap() : null, - onTapCancel: game is TapDetector ? () => game.onTapCancel() : null, - onTapDown: game is TapDetector - ? (TapDownDetails d) => game.onTapDown(TapDownInfo.fromDetails(game, d)) - : null, - onTapUp: game is TapDetector - ? (TapUpDetails d) => game.onTapUp(TapUpInfo.fromDetails(game, d)) - : null, - - // Secondary taps - onSecondaryTapDown: game is SecondaryTapDetector - ? (TapDownDetails d) => - game.onSecondaryTapDown(TapDownInfo.fromDetails(game, d)) - : null, - onSecondaryTapUp: game is SecondaryTapDetector - ? (TapUpDetails d) => - game.onSecondaryTapUp(TapUpInfo.fromDetails(game, d)) - : null, - onSecondaryTapCancel: - game is SecondaryTapDetector ? () => game.onSecondaryTapCancel() : null, - - // Double tap - onDoubleTap: game is DoubleTapDetector ? () => game.onDoubleTap() : null, - onDoubleTapCancel: - game is DoubleTapDetector ? () => game.onDoubleTapCancel() : null, - onDoubleTapDown: game is DoubleTapDetector - ? (TapDownDetails d) => - game.onDoubleTapDown(TapDownInfo.fromDetails(game, d)) - : null, - - // Long presses - onLongPress: game is LongPressDetector ? () => game.onLongPress() : null, - onLongPressStart: game is LongPressDetector - ? (LongPressStartDetails d) => - game.onLongPressStart(LongPressStartInfo.fromDetails(game, d)) - : null, - onLongPressMoveUpdate: game is LongPressDetector - ? (LongPressMoveUpdateDetails d) => game - .onLongPressMoveUpdate(LongPressMoveUpdateInfo.fromDetails(game, d)) - : null, - onLongPressUp: - game is LongPressDetector ? () => game.onLongPressUp() : null, - onLongPressEnd: game is LongPressDetector - ? (LongPressEndDetails d) => - game.onLongPressEnd(LongPressEndInfo.fromDetails(game, d)) - : null, - - // Vertical drag - onVerticalDragDown: game is VerticalDragDetector - ? (DragDownDetails d) => - game.onVerticalDragDown(DragDownInfo.fromDetails(game, d)) - : null, - onVerticalDragStart: game is VerticalDragDetector - ? (DragStartDetails d) => - game.onVerticalDragStart(DragStartInfo.fromDetails(game, d)) - : null, - onVerticalDragUpdate: game is VerticalDragDetector - ? (DragUpdateDetails d) => - game.onVerticalDragUpdate(DragUpdateInfo.fromDetails(game, d)) - : null, - onVerticalDragEnd: game is VerticalDragDetector - ? (DragEndDetails d) => - game.onVerticalDragEnd(DragEndInfo.fromDetails(game, d)) - : null, - onVerticalDragCancel: - game is VerticalDragDetector ? () => game.onVerticalDragCancel() : null, - - // Horizontal drag - onHorizontalDragDown: game is HorizontalDragDetector - ? (DragDownDetails d) => - game.onHorizontalDragDown(DragDownInfo.fromDetails(game, d)) - : null, - onHorizontalDragStart: game is HorizontalDragDetector - ? (DragStartDetails d) => - game.onHorizontalDragStart(DragStartInfo.fromDetails(game, d)) - : null, - onHorizontalDragUpdate: game is HorizontalDragDetector - ? (DragUpdateDetails d) => - game.onHorizontalDragUpdate(DragUpdateInfo.fromDetails(game, d)) - : null, - onHorizontalDragEnd: game is HorizontalDragDetector - ? (DragEndDetails d) => - game.onHorizontalDragEnd(DragEndInfo.fromDetails(game, d)) - : null, - onHorizontalDragCancel: game is HorizontalDragDetector - ? () => game.onHorizontalDragCancel() - : null, - - // Force presses - onForcePressStart: game is ForcePressDetector - ? (ForcePressDetails d) => - game.onForcePressStart(ForcePressInfo.fromDetails(game, d)) - : null, - onForcePressPeak: game is ForcePressDetector - ? (ForcePressDetails d) => - game.onForcePressPeak(ForcePressInfo.fromDetails(game, d)) - : null, - onForcePressUpdate: game is ForcePressDetector - ? (ForcePressDetails d) => - game.onForcePressUpdate(ForcePressInfo.fromDetails(game, d)) - : null, - onForcePressEnd: game is ForcePressDetector - ? (ForcePressDetails d) => - game.onForcePressEnd(ForcePressInfo.fromDetails(game, d)) - : null, - - // Pan - onPanDown: game is PanDetector - ? (DragDownDetails d) => - game.onPanDown(DragDownInfo.fromDetails(game, d)) - : null, - onPanStart: game is PanDetector - ? (DragStartDetails d) => - game.onPanStart(DragStartInfo.fromDetails(game, d)) - : null, - onPanUpdate: game is PanDetector - ? (DragUpdateDetails d) => - game.onPanUpdate(DragUpdateInfo.fromDetails(game, d)) - : null, - onPanEnd: game is PanDetector - ? (DragEndDetails d) => game.onPanEnd(DragEndInfo.fromDetails(game, d)) - : null, - onPanCancel: game is PanDetector ? () => game.onPanCancel() : null, - - // Scales - onScaleStart: game is ScaleDetector - ? (ScaleStartDetails d) => - game.onScaleStart(ScaleStartInfo.fromDetails(game, d)) - : null, - onScaleUpdate: game is ScaleDetector - ? (ScaleUpdateDetails d) => - game.onScaleUpdate(ScaleUpdateInfo.fromDetails(game, d)) - : null, - onScaleEnd: game is ScaleDetector - ? (ScaleEndDetails d) => - game.onScaleEnd(ScaleEndInfo.fromDetails(game, d)) - : null, - - child: child, - ); -} - -Widget applyAdvancedGesturesDetectors(Game game, Widget child) { +Widget applyGesturesDetectors(Game game, Widget child) { final gestures = {}; void addRecognizer( @@ -186,6 +35,104 @@ Widget applyAdvancedGesturesDetectors(Game game, Widget child) { gestures[T] = GestureRecognizerFactoryWithHandlers(factory, handlers); } + if (game is TapDetector || game is SecondaryTapDetector) { + addRecognizer( + TapGestureRecognizer.new, + (TapGestureRecognizer instance) { + if (game is TapDetector) { + instance.onTap = game.onTap; + instance.onTapCancel = game.onTapCancel; + instance.onTapUp = game.handleTapUp; + instance.onTapDown = game.handleTapDown; + } + if (game is SecondaryTapDetector) { + instance.onSecondaryTapCancel = game.onSecondaryTapCancel; + instance.onSecondaryTapUp = game.handleSecondaryTapUp; + instance.onSecondaryTapDown = game.handleSecondaryTapDown; + } + }, + ); + } + if (game is DoubleTapDetector) { + addRecognizer( + DoubleTapGestureRecognizer.new, + (DoubleTapGestureRecognizer instance) { + instance.onDoubleTap = game.onDoubleTap; + instance.onDoubleTapDown = game.handleDoubleTapDown; + instance.onDoubleTapCancel = game.onDoubleTapCancel; + }, + ); + } + if (game is LongPressDetector) { + addRecognizer( + LongPressGestureRecognizer.new, + (LongPressGestureRecognizer instance) { + instance.onLongPress = game.onLongPress; + instance.onLongPressStart = game.handleLongPressStart; + instance.onLongPressMoveUpdate = game.handleLongPressMoveUpdate; + instance.onLongPressEnd = game.handleLongPressEnd; + instance.onLongPressUp = game.onLongPressUp; + instance.onLongPressCancel = game.onLongPressCancel; + }, + ); + } + if (game is VerticalDragDetector) { + addRecognizer( + VerticalDragGestureRecognizer.new, + (VerticalDragGestureRecognizer instance) { + instance.onDown = game.handleVerticalDragDown; + instance.onStart = game.handleVerticalDragStart; + instance.onUpdate = game.handleVerticalDragUpdate; + instance.onEnd = game.handleVerticalDragEnd; + instance.onCancel = game.onVerticalDragCancel; + }, + ); + } + if (game is HorizontalDragDetector) { + addRecognizer( + HorizontalDragGestureRecognizer.new, + (HorizontalDragGestureRecognizer instance) { + instance.onDown = game.handleHorizontalDragDown; + instance.onStart = game.handleHorizontalDragStart; + instance.onUpdate = game.handleHorizontalDragUpdate; + instance.onEnd = game.handleHorizontalDragEnd; + instance.onCancel = game.onHorizontalDragCancel; + }, + ); + } + if (game is ForcePressDetector) { + addRecognizer( + ForcePressGestureRecognizer.new, + (ForcePressGestureRecognizer instance) { + instance.onStart = game.handleForcePressStart; + instance.onPeak = game.handleForcePressPeak; + instance.onUpdate = game.handleForcePressUpdate; + instance.onEnd = game.handleForcePressEnd; + }, + ); + } + if (game is PanDetector) { + addRecognizer( + PanGestureRecognizer.new, + (PanGestureRecognizer instance) { + instance.onDown = game.handlePanDown; + instance.onStart = game.handlePanStart; + instance.onUpdate = game.handlePanUpdate; + instance.onEnd = game.handlePanEnd; + instance.onCancel = game.onPanCancel; + }, + ); + } + if (game is ScaleDetector) { + addRecognizer( + ScaleGestureRecognizer.new, + (ScaleGestureRecognizer instance) { + instance.onStart = game.handleScaleStart; + instance.onUpdate = game.handleScaleUpdate; + instance.onEnd = game.handleScaleEnd; + }, + ); + } if (game is MultiTapListener) { addRecognizer( MultiTapGestureRecognizer.new, diff --git a/packages/flame/lib/src/gestures/detectors.dart b/packages/flame/lib/src/gestures/detectors.dart index ea828e07a42..427d4190e8f 100644 --- a/packages/flame/lib/src/gestures/detectors.dart +++ b/packages/flame/lib/src/gestures/detectors.dart @@ -1,5 +1,6 @@ import 'package:flame/src/game/mixins/game.dart'; import 'package:flame/src/gestures/events.dart'; +import 'package:flutter/gestures.dart'; // Basic touch detectors mixin TapDetector on Game { @@ -7,18 +8,38 @@ mixin TapDetector on Game { void onTapCancel() {} void onTapDown(TapDownInfo info) {} void onTapUp(TapUpInfo info) {} + + void handleTapUp(TapUpDetails details) { + onTapUp(TapUpInfo.fromDetails(this, details)); + } + + void handleTapDown(TapDownDetails details) { + onTapDown(TapDownInfo.fromDetails(this, details)); + } } mixin SecondaryTapDetector on Game { void onSecondaryTapDown(TapDownInfo info) {} void onSecondaryTapUp(TapUpInfo info) {} void onSecondaryTapCancel() {} + + void handleSecondaryTapUp(TapUpDetails details) { + onSecondaryTapUp(TapUpInfo.fromDetails(this, details)); + } + + void handleSecondaryTapDown(TapDownDetails details) { + onSecondaryTapDown(TapDownInfo.fromDetails(this, details)); + } } mixin DoubleTapDetector on Game { void onDoubleTap() {} void onDoubleTapCancel() {} void onDoubleTapDown(TapDownInfo info) {} + + void handleDoubleTapDown(TapDownDetails details) { + onDoubleTapDown(TapDownInfo.fromDetails(this, details)); + } } mixin LongPressDetector on Game { @@ -27,6 +48,19 @@ mixin LongPressDetector on Game { void onLongPressMoveUpdate(LongPressMoveUpdateInfo info) {} void onLongPressUp() {} void onLongPressEnd(LongPressEndInfo info) {} + void onLongPressCancel() {} + + void handleLongPressStart(LongPressStartDetails details) { + onLongPressStart(LongPressStartInfo.fromDetails(this, details)); + } + + void handleLongPressMoveUpdate(LongPressMoveUpdateDetails details) { + onLongPressMoveUpdate(LongPressMoveUpdateInfo.fromDetails(this, details)); + } + + void handleLongPressEnd(LongPressEndDetails details) { + onLongPressEnd(LongPressEndInfo.fromDetails(this, details)); + } } mixin VerticalDragDetector on Game { @@ -35,6 +69,22 @@ mixin VerticalDragDetector on Game { void onVerticalDragUpdate(DragUpdateInfo info) {} void onVerticalDragEnd(DragEndInfo info) {} void onVerticalDragCancel() {} + + void handleVerticalDragDown(DragDownDetails details) { + onVerticalDragDown(DragDownInfo.fromDetails(this, details)); + } + + void handleVerticalDragStart(DragStartDetails details) { + onVerticalDragStart(DragStartInfo.fromDetails(this, details)); + } + + void handleVerticalDragUpdate(DragUpdateDetails details) { + onVerticalDragUpdate(DragUpdateInfo.fromDetails(this, details)); + } + + void handleVerticalDragEnd(DragEndDetails details) { + onVerticalDragEnd(DragEndInfo.fromDetails(this, details)); + } } mixin HorizontalDragDetector on Game { @@ -43,6 +93,22 @@ mixin HorizontalDragDetector on Game { void onHorizontalDragUpdate(DragUpdateInfo info) {} void onHorizontalDragEnd(DragEndInfo info) {} void onHorizontalDragCancel() {} + + void handleHorizontalDragDown(DragDownDetails details) { + onHorizontalDragDown(DragDownInfo.fromDetails(this, details)); + } + + void handleHorizontalDragStart(DragStartDetails details) { + onHorizontalDragStart(DragStartInfo.fromDetails(this, details)); + } + + void handleHorizontalDragUpdate(DragUpdateDetails details) { + onHorizontalDragUpdate(DragUpdateInfo.fromDetails(this, details)); + } + + void handleHorizontalDragEnd(DragEndDetails details) { + onHorizontalDragEnd(DragEndInfo.fromDetails(this, details)); + } } mixin ForcePressDetector on Game { @@ -50,6 +116,22 @@ mixin ForcePressDetector on Game { void onForcePressPeak(ForcePressInfo info) {} void onForcePressUpdate(ForcePressInfo info) {} void onForcePressEnd(ForcePressInfo info) {} + + void handleForcePressStart(ForcePressDetails details) { + onForcePressStart(ForcePressInfo.fromDetails(this, details)); + } + + void handleForcePressPeak(ForcePressDetails details) { + onForcePressPeak(ForcePressInfo.fromDetails(this, details)); + } + + void handleForcePressUpdate(ForcePressDetails details) { + onForcePressUpdate(ForcePressInfo.fromDetails(this, details)); + } + + void handleForcePressEnd(ForcePressDetails details) { + onForcePressEnd(ForcePressInfo.fromDetails(this, details)); + } } mixin PanDetector on Game { @@ -58,12 +140,40 @@ mixin PanDetector on Game { void onPanUpdate(DragUpdateInfo info) {} void onPanEnd(DragEndInfo info) {} void onPanCancel() {} + + void handlePanDown(DragDownDetails details) { + onPanDown(DragDownInfo.fromDetails(this, details)); + } + + void handlePanStart(DragStartDetails details) { + onPanStart(DragStartInfo.fromDetails(this, details)); + } + + void handlePanUpdate(DragUpdateDetails details) { + onPanUpdate(DragUpdateInfo.fromDetails(this, details)); + } + + void handlePanEnd(DragEndDetails details) { + onPanEnd(DragEndInfo.fromDetails(this, details)); + } } mixin ScaleDetector on Game { void onScaleStart(ScaleStartInfo info) {} void onScaleUpdate(ScaleUpdateInfo info) {} void onScaleEnd(ScaleEndInfo info) {} + + void handleScaleStart(ScaleStartDetails details) { + onScaleStart(ScaleStartInfo.fromDetails(this, details)); + } + + void handleScaleUpdate(ScaleUpdateDetails details) { + onScaleUpdate(ScaleUpdateInfo.fromDetails(this, details)); + } + + void handleScaleEnd(ScaleEndDetails details) { + onScaleEnd(ScaleEndInfo.fromDetails(this, details)); + } } mixin MouseMovementDetector on Game {