Skip to content

Commit

Permalink
feat: initial zooming (#49)
Browse files Browse the repository at this point in the history
* feat: initial zooming

* fix linter

* fixing tests on CI
  • Loading branch information
erickzanardo authored Mar 11, 2024
1 parent 8ee50da commit bdac658
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 5 deletions.
17 changes: 17 additions & 0 deletions lib/crossword/game/crossword_game.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,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();
}
}
62 changes: 57 additions & 5 deletions lib/crossword/view/crossword_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,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<LoadedBoardView> createState() => LoadedBoardViewState();
}

@visibleForTesting
class LoadedBoardViewState extends State<LoadedBoardView> {
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),
),
],
),
),
],
);
}
}
56 changes: 56 additions & 0 deletions test/crossword/game/crossword_game_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -321,5 +321,61 @@ void main() {
expect(newCurrentSections.contains(subjectComponent), isFalse);
},
);

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));
},
);
});
}
49 changes: 49 additions & 0 deletions test/crossword/view/crossword_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,54 @@ void main() {
await tester.pumpCrosswordView(bloc);
expect(find.byType(GameWidget<CrosswordGame>), findsOneWidget);
});

testWidgets('can zoom in', (tester) async {
when(() => bloc.state).thenReturn(
CrosswordLoaded(
width: 40,
height: 40,
sectionSize: 40,
sections: const {},
),
);

await tester.pumpCrosswordView(bloc);

final crosswordViewState = tester.state<LoadedBoardViewState>(
find.byType(LoadedBoardView),
);
await crosswordViewState.game.loaded;

await tester.tap(find.byKey(LoadedBoardView.zoomInKey));

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);
final crosswordViewState = tester.state<LoadedBoardViewState>(
find.byType(LoadedBoardView),
);
await crosswordViewState.game.loaded;

await tester.tap(find.byKey(LoadedBoardView.zoomOutKey));

expect(
crosswordViewState.game.camera.viewfinder.zoom,
lessThan(1),
);
});
});
}

0 comments on commit bdac658

Please sign in to comment.