diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index f9018ee5..372c62f7 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -23,7 +23,8 @@ class PinballGame extends Forge2DGame PinballGame({ required this.characterTheme, required this.audio, - }) : super(gravity: Vector2(0, 30)) { + }) : focusNode = FocusNode(), + super(gravity: Vector2(0, 30)) { images.prefix = ''; controller = _GameBallsController(this); } @@ -38,6 +39,8 @@ class PinballGame extends Forge2DGame final PinballAudio audio; + final FocusNode focusNode; + late final GameFlowController gameFlowController; @override diff --git a/lib/game/view/pinball_game_page.dart b/lib/game/view/pinball_game_page.dart index 9ac25cfe..35516bbc 100644 --- a/lib/game/view/pinball_game_page.dart +++ b/lib/game/view/pinball_game_page.dart @@ -120,19 +120,27 @@ class PinballGameLoadedView extends StatelessWidget { return Stack( children: [ Positioned.fill( - child: GameWidget( - game: game, - initialActiveOverlays: const [PinballGame.playButtonOverlay], - overlayBuilderMap: { - PinballGame.playButtonOverlay: (context, game) { - return Positioned( - bottom: 20, - right: 0, - left: 0, - child: PlayButtonOverlay(game: game), - ); - }, + child: MouseRegion( + onHover: (_) { + if (!game.focusNode.hasFocus) { + game.focusNode.requestFocus(); + } }, + child: GameWidget( + game: game, + initialActiveOverlays: const [PinballGame.playButtonOverlay], + focusNode: game.focusNode, + overlayBuilderMap: { + PinballGame.playButtonOverlay: (context, game) { + return Positioned( + bottom: 20, + right: 0, + left: 0, + child: PlayButtonOverlay(game: game), + ); + }, + }, + ), ), ), // TODO(arturplaczek): add Visibility to GameHud based on StartGameBloc diff --git a/test/game/view/pinball_game_page_test.dart b/test/game/view/pinball_game_page_test.dart index d3b32d85..802f49f8 100644 --- a/test/game/view/pinball_game_page_test.dart +++ b/test/game/view/pinball_game_page_test.dart @@ -1,5 +1,7 @@ // ignore_for_file: prefer_const_constructors +import 'dart:ui'; + import 'package:bloc_test/bloc_test.dart'; import 'package:flame/game.dart'; import 'package:flutter/material.dart'; @@ -237,5 +239,26 @@ void main() { findsOneWidget, ); }); + + testWidgets('keep focus on game when mouse hovers over it', (tester) async { + await tester.pumpApp( + PinballGameView(game: game), + gameBloc: gameBloc, + startGameBloc: startGameBloc, + ); + + game.focusNode.unfocus(); + await tester.pump(); + + expect(game.focusNode.hasFocus, isFalse); + + final gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); + await gesture.addPointer(location: Offset.zero); + addTearDown(gesture.removePointer); + await gesture.moveTo((game.size / 2).toOffset()); + await tester.pump(); + + expect(game.focusNode.hasFocus, isTrue); + }); }); }