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