mirror of https://github.com/flutter/pinball.git
feat: adding leaderboard pagination buttons (#420)
* feat: adding leaderboard pagination buttons * lint * cspellpull/423/head
parent
96beecfc82
commit
ea33c1c889
After Width: | Height: | Size: 866 B |
After Width: | Height: | Size: 842 B |
@ -0,0 +1,49 @@
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame/input.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
|
||||
/// enum with the available directions for an [ArrowIcon].
|
||||
enum ArrowIconDirection {
|
||||
/// Left.
|
||||
left,
|
||||
|
||||
/// Right.
|
||||
right,
|
||||
}
|
||||
|
||||
/// {@template arrow_icon}
|
||||
/// A [SpriteComponent] that renders a simple arrow icon.
|
||||
/// {@endtemplate}
|
||||
class ArrowIcon extends SpriteComponent with Tappable, HasGameRef {
|
||||
/// {@macro arrow_icon}
|
||||
ArrowIcon({
|
||||
required Vector2 position,
|
||||
required this.direction,
|
||||
required this.onTap,
|
||||
}) : super(position: position);
|
||||
|
||||
final ArrowIconDirection direction;
|
||||
final VoidCallback onTap;
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
anchor = Anchor.center;
|
||||
final sprite = Sprite(
|
||||
gameRef.images.fromCache(
|
||||
direction == ArrowIconDirection.left
|
||||
? Assets.images.displayArrows.arrowLeft.keyName
|
||||
: Assets.images.displayArrows.arrowRight.keyName,
|
||||
),
|
||||
);
|
||||
|
||||
size = sprite.originalSize / 20;
|
||||
this.sprite = sprite;
|
||||
}
|
||||
|
||||
@override
|
||||
bool onTapUp(TapUpInfo info) {
|
||||
onTap();
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
import 'package:sandbox/common/games.dart';
|
||||
|
||||
class ArrowIconGame extends AssetsGame with HasTappables {
|
||||
ArrowIconGame()
|
||||
: super(
|
||||
imagesFileNames: [
|
||||
Assets.images.displayArrows.arrowLeft.keyName,
|
||||
Assets.images.displayArrows.arrowRight.keyName,
|
||||
],
|
||||
);
|
||||
|
||||
static const description = 'Shows how ArrowIcons are rendered.';
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
camera.followVector2(Vector2.zero());
|
||||
|
||||
await add(
|
||||
ArrowIcon(
|
||||
position: Vector2.zero(),
|
||||
direction: ArrowIconDirection.left,
|
||||
onTap: () {},
|
||||
),
|
||||
);
|
||||
|
||||
await add(
|
||||
ArrowIcon(
|
||||
position: Vector2(0, 20),
|
||||
direction: ArrowIconDirection.right,
|
||||
onTap: () {},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import 'package:dashbook/dashbook.dart';
|
||||
import 'package:sandbox/common/common.dart';
|
||||
import 'package:sandbox/stories/arrow_icon/arrow_icon_game.dart';
|
||||
|
||||
void addArrowIconStories(Dashbook dashbook) {
|
||||
dashbook.storiesOf('ArrowIcon').addGame(
|
||||
title: 'Basic',
|
||||
description: ArrowIconGame.description,
|
||||
gameBuilder: (context) => ArrowIconGame(),
|
||||
);
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
// ignore_for_file: cascade_invocations, one_member_abstracts
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame_test/flame_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
|
||||
import '../../helpers/helpers.dart';
|
||||
|
||||
abstract class _VoidCallbackStubBase {
|
||||
void onCall();
|
||||
}
|
||||
|
||||
class _VoidCallbackStub extends Mock implements _VoidCallbackStubBase {}
|
||||
|
||||
void main() {
|
||||
group('ArrowIcon', () {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
final assets = [
|
||||
Assets.images.displayArrows.arrowLeft.keyName,
|
||||
Assets.images.displayArrows.arrowRight.keyName,
|
||||
];
|
||||
final flameTester = FlameTester(() => TappablesTestGame(assets));
|
||||
|
||||
flameTester.testGameWidget(
|
||||
'is tappable',
|
||||
setUp: (game, tester) async {
|
||||
final stub = _VoidCallbackStub();
|
||||
await game.images.loadAll(assets);
|
||||
await game.ensureAdd(
|
||||
ArrowIcon(
|
||||
position: Vector2.zero(),
|
||||
direction: ArrowIconDirection.left,
|
||||
onTap: stub.onCall,
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
await tester.tapAt(Offset.zero);
|
||||
await tester.pump();
|
||||
},
|
||||
verify: (game, tester) async {
|
||||
final icon = game.descendants().whereType<ArrowIcon>().single;
|
||||
verify(icon.onTap).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
group('left', () {
|
||||
flameTester.testGameWidget(
|
||||
'renders correctly',
|
||||
setUp: (game, tester) async {
|
||||
await game.images.loadAll(assets);
|
||||
game.camera.followVector2(Vector2.zero());
|
||||
await game.add(
|
||||
ArrowIcon(
|
||||
position: Vector2.zero(),
|
||||
direction: ArrowIconDirection.left,
|
||||
onTap: () {},
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
},
|
||||
verify: (game, tester) async {
|
||||
await expectLater(
|
||||
find.byGame<TestGame>(),
|
||||
matchesGoldenFile('golden/arrow_icon_left.png'),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('right', () {
|
||||
flameTester.testGameWidget(
|
||||
'renders correctly',
|
||||
setUp: (game, tester) async {
|
||||
await game.images.loadAll(assets);
|
||||
game.camera.followVector2(Vector2.zero());
|
||||
await game.add(
|
||||
ArrowIcon(
|
||||
position: Vector2.zero(),
|
||||
direction: ArrowIconDirection.right,
|
||||
onTap: () {},
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
},
|
||||
verify: (game, tester) async {
|
||||
await expectLater(
|
||||
find.byGame<TestGame>(),
|
||||
matchesGoldenFile('golden/arrow_icon_right.png'),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
Loading…
Reference in new issue