From a57abcd1b6ca055b57197948560dfee4f04ca213 Mon Sep 17 00:00:00 2001 From: Erick Zanardo Date: Fri, 8 Mar 2024 15:21:41 -0300 Subject: [PATCH 1/3] feat: initial zooming --- lib/crossword/game/crossword_game.dart | 18 ++++++ lib/crossword/view/crossword_page.dart | 62 ++++++++++++++++++-- test/crossword/game/crossword_game_test.dart | 56 ++++++++++++++++++ test/crossword/view/crossword_page_test.dart | 48 +++++++++++++++ 4 files changed, 179 insertions(+), 5 deletions(-) diff --git a/lib/crossword/game/crossword_game.dart b/lib/crossword/game/crossword_game.dart index 35665907e..b1be4be61 100644 --- a/lib/crossword/game/crossword_game.dart +++ b/lib/crossword/game/crossword_game.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:math' as math; import 'package:flame/camera.dart'; import 'package:flame/components.dart'; @@ -137,4 +138,21 @@ class CrosswordGame extends FlameGame with PanDetector { _updateVisibleSections(); } } + + void zoomOut() { + if (camera.viewfinder.zoom <= 0.05) { + return; + } + camera.viewport.position /= 1.05; + camera.viewfinder.zoom = camera.viewfinder.zoom - 0.05; + + _updateVisibleSections(); + } + + void zoomIn() { + camera.viewport.position *= 1.05; + camera.viewfinder.zoom += 0.05; + + _updateVisibleSections(); + } } diff --git a/lib/crossword/view/crossword_page.dart b/lib/crossword/view/crossword_page.dart index c6ef214b7..e3cc3daf9 100644 --- a/lib/crossword/view/crossword_page.dart +++ b/lib/crossword/view/crossword_page.dart @@ -41,13 +41,65 @@ class CrosswordView extends StatelessWidget { } else if (state is CrosswordError) { child = const Center(child: Text('Error loading crossword')); } else if (state is CrosswordLoaded) { - child = GameWidget.controlled( - gameFactory: () => CrosswordGame( - context.read(), - ), - ); + child = const LoadedBoardView(); } return Scaffold(body: child); } } + +class LoadedBoardView extends StatefulWidget { + const LoadedBoardView({super.key}); + + @visibleForTesting + static const zoomInKey = Key('game_zoomIn'); + @visibleForTesting + static const zoomOutKey = Key('game_zoomOut'); + + @override + State createState() => LoadedBoardViewState(); +} + +@visibleForTesting +class LoadedBoardViewState extends State { + late final CrosswordGame game; + + @override + void initState() { + super.initState(); + + game = CrosswordGame(context.read()); + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + GameWidget(game: game), + Positioned( + right: 16, + bottom: 16, + child: Column( + children: [ + ElevatedButton( + key: LoadedBoardView.zoomInKey, + onPressed: () { + game.zoomIn(); + }, + child: const Icon(Icons.zoom_in), + ), + const SizedBox(height: 16), + ElevatedButton( + key: LoadedBoardView.zoomOutKey, + onPressed: () { + game.zoomOut(); + }, + child: const Icon(Icons.zoom_out), + ), + ], + ), + ), + ], + ); + } +} diff --git a/test/crossword/game/crossword_game_test.dart b/test/crossword/game/crossword_game_test.dart index 1b7a75827..5d4d6a14d 100644 --- a/test/crossword/game/crossword_game_test.dart +++ b/test/crossword/game/crossword_game_test.dart @@ -288,5 +288,61 @@ void main() { expect(removed, completes); }, ); + + testWithGame( + 'can zoom in', + createGame, + (game) async { + const state = CrosswordLoaded( + width: 40, + height: 40, + sectionSize: 400, + sections: {}, + ); + mockState(state); + + await game.ready(); + game.zoomIn(); + expect(game.camera.viewfinder.zoom, 1.05); + }, + ); + + testWithGame( + 'can zoom out', + createGame, + (game) async { + const state = CrosswordLoaded( + width: 40, + height: 40, + sectionSize: 400, + sections: {}, + ); + mockState(state); + + await game.ready(); + game.zoomOut(); + expect(game.camera.viewfinder.zoom, .95); + }, + ); + + testWithGame( + 'cannot zoom out more than 0.05', + createGame, + (game) async { + const state = CrosswordLoaded( + width: 40, + height: 40, + sectionSize: 400, + sections: {}, + ); + mockState(state); + + await game.ready(); + for (var i = 0; i < 100; i++) { + game.zoomOut(); + } + expect(game.camera.viewfinder.zoom, greaterThan(0)); + }, + ); }); } diff --git a/test/crossword/view/crossword_page_test.dart b/test/crossword/view/crossword_page_test.dart index b168addbb..0ebcb38a0 100644 --- a/test/crossword/view/crossword_page_test.dart +++ b/test/crossword/view/crossword_page_test.dart @@ -97,5 +97,53 @@ void main() { await tester.pumpCrosswordView(bloc); expect(find.byType(GameWidget), findsOneWidget); }); + + testWidgets('can zoom in', (tester) async { + when(() => bloc.state).thenReturn( + CrosswordLoaded( + width: 40, + height: 40, + sectionSize: 40, + sections: const {}, + ), + ); + + await tester.pumpCrosswordView(bloc); + + await tester.tap(find.byKey(LoadedBoardView.zoomInKey)); + + final crosswordViewState = tester.state( + find.byType(LoadedBoardView), + ); + + expect( + crosswordViewState.game.camera.viewfinder.zoom, + greaterThan(1), + ); + }); + + testWidgets('can zoom out', (tester) async { + when(() => bloc.state).thenReturn( + CrosswordLoaded( + width: 40, + height: 40, + sectionSize: 40, + sections: const {}, + ), + ); + + await tester.pumpCrosswordView(bloc); + + await tester.tap(find.byKey(LoadedBoardView.zoomOutKey)); + + final crosswordViewState = tester.state( + find.byType(LoadedBoardView), + ); + + expect( + crosswordViewState.game.camera.viewfinder.zoom, + lessThan(1), + ); + }); }); } From f4d8f1db74db3d82bd1502d52cd5812d34cb3265 Mon Sep 17 00:00:00 2001 From: Erick Zanardo Date: Fri, 8 Mar 2024 15:26:11 -0300 Subject: [PATCH 2/3] fix linter --- lib/crossword/game/crossword_game.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/crossword/game/crossword_game.dart b/lib/crossword/game/crossword_game.dart index b1be4be61..da9f3780d 100644 --- a/lib/crossword/game/crossword_game.dart +++ b/lib/crossword/game/crossword_game.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:math' as math; import 'package:flame/camera.dart'; import 'package:flame/components.dart'; From 44b3e26ebdce56a1aa512c0a193ceabff727241c Mon Sep 17 00:00:00 2001 From: Erick Zanardo Date: Fri, 8 Mar 2024 16:08:13 -0300 Subject: [PATCH 3/3] fixing tests on CI --- test/crossword/view/crossword_page_test.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/crossword/view/crossword_page_test.dart b/test/crossword/view/crossword_page_test.dart index 0ebcb38a0..103ea8e94 100644 --- a/test/crossword/view/crossword_page_test.dart +++ b/test/crossword/view/crossword_page_test.dart @@ -110,11 +110,12 @@ void main() { await tester.pumpCrosswordView(bloc); - await tester.tap(find.byKey(LoadedBoardView.zoomInKey)); - final crosswordViewState = tester.state( find.byType(LoadedBoardView), ); + await crosswordViewState.game.loaded; + + await tester.tap(find.byKey(LoadedBoardView.zoomInKey)); expect( crosswordViewState.game.camera.viewfinder.zoom, @@ -133,12 +134,12 @@ void main() { ); await tester.pumpCrosswordView(bloc); - - await tester.tap(find.byKey(LoadedBoardView.zoomOutKey)); - final crosswordViewState = tester.state( find.byType(LoadedBoardView), ); + await crosswordViewState.game.loaded; + + await tester.tap(find.byKey(LoadedBoardView.zoomOutKey)); expect( crosswordViewState.game.camera.viewfinder.zoom,