// ignore_for_file: public_member_api_docs import 'dart:async'; import 'package:flutter/material.dart'; import 'package:pinball/gen/gen.dart'; import 'package:pinball/l10n/l10n.dart'; import 'package:pinball_ui/pinball_ui.dart'; import 'package:platform_helper/platform_helper.dart'; enum Control { left, right, down, a, d, s, space, } extension on Control { bool get isArrow => isDown || isRight || isLeft; bool get isDown => this == Control.down; bool get isRight => this == Control.right; bool get isLeft => this == Control.left; bool get isSpace => this == Control.space; String getCharacter(BuildContext context) { switch (this) { case Control.a: return 'A'; case Control.d: return 'D'; case Control.down: return '>'; // Will be rotated case Control.left: return '<'; case Control.right: return '>'; case Control.s: return 'S'; case Control.space: return context.l10n.space; } } } Future showHowToPlayDialog(BuildContext context) { return showDialog( context: context, barrierDismissible: false, builder: (_) => HowToPlayDialog(), ); } class HowToPlayDialog extends StatefulWidget { HowToPlayDialog({ Key? key, @visibleForTesting PlatformHelper? platformHelper, }) : platformHelper = platformHelper ?? PlatformHelper(), super(key: key); final PlatformHelper platformHelper; @override State createState() => _HowToPlayDialogState(); } class _HowToPlayDialogState extends State { late Timer closeTimer; @override void initState() { super.initState(); closeTimer = Timer(const Duration(seconds: 3), () { if (mounted) { Navigator.of(context).pop(); } }); } @override void dispose() { closeTimer.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final isMobile = widget.platformHelper.isMobile; final l10n = context.l10n; return PinballDialog( title: l10n.howToPlay, subtitle: l10n.tipsForFlips, child: isMobile ? const _MobileBody() : const _DesktopBody(), ); } } class _MobileBody extends StatelessWidget { const _MobileBody({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final paddingWidth = MediaQuery.of(context).size.width * 0.15; final paddingHeight = MediaQuery.of(context).size.height * 0.075; return FittedBox( child: Padding( padding: EdgeInsets.symmetric( horizontal: paddingWidth, ), child: Column( children: [ const _MobileLaunchControls(), SizedBox(height: paddingHeight), const _MobileFlipperControls(), ], ), ), ); } } class _MobileLaunchControls extends StatelessWidget { const _MobileLaunchControls({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final l10n = context.l10n; final headline3 = Theme.of(context) .textTheme .headline3! .copyWith(color: PinballColors.white); return Column( children: [ Text(l10n.tapAndHoldRocket, style: headline3), Text.rich( TextSpan( children: [ TextSpan(text: '${l10n.to} ', style: headline3), TextSpan( text: l10n.launch, style: headline3.copyWith(color: PinballColors.blue), ), ], ), ), ], ); } } class _MobileFlipperControls extends StatelessWidget { const _MobileFlipperControls({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final l10n = context.l10n; final headline3 = Theme.of(context) .textTheme .headline3! .copyWith(color: PinballColors.white); return Column( children: [ Text(l10n.tapLeftRightScreen, style: headline3), Text.rich( TextSpan( children: [ TextSpan(text: '${l10n.to} ', style: headline3), TextSpan( text: l10n.flip, style: headline3.copyWith(color: PinballColors.orange), ), ], ), ), ], ); } } class _DesktopBody extends StatelessWidget { const _DesktopBody({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return ListView( children: const [ SizedBox(height: 16), _DesktopLaunchControls(), SizedBox(height: 16), _DesktopFlipperControls(), ], ); } } class _DesktopLaunchControls extends StatelessWidget { const _DesktopLaunchControls({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final l10n = context.l10n; return Column( children: [ Text( l10n.launchControls, style: Theme.of(context).textTheme.headline4, ), const SizedBox(height: 10), Wrap( children: const [ _KeyButton(control: Control.down), SizedBox(width: 10), _KeyButton(control: Control.space), SizedBox(width: 10), _KeyButton(control: Control.s), ], ) ], ); } } class _DesktopFlipperControls extends StatelessWidget { const _DesktopFlipperControls({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final l10n = context.l10n; return Column( children: [ Text( l10n.flipperControls, style: Theme.of(context).textTheme.subtitle2, ), const SizedBox(height: 10), Column( children: [ Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: const [ _KeyButton(control: Control.left), SizedBox(width: 20), _KeyButton(control: Control.right), ], ), const SizedBox(height: 8), Wrap( children: const [ _KeyButton(control: Control.a), SizedBox(width: 20), _KeyButton(control: Control.d), ], ) ], ) ], ); } } class _KeyButton extends StatelessWidget { const _KeyButton({Key? key, required this.control}) : super(key: key); final Control control; @override Widget build(BuildContext context) { final textTheme = Theme.of(context).textTheme; final textStyle = control.isArrow ? textTheme.headline1 : textTheme.headline3; const height = 60.0; final width = control.isSpace ? height * 2.83 : height; return DecoratedBox( decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fill, image: AssetImage( control.isSpace ? Assets.images.components.space.keyName : Assets.images.components.key.keyName, ), ), ), child: SizedBox( width: width, height: height, child: Center( child: RotatedBox( quarterTurns: control.isDown ? 1 : 0, child: Text( control.getCharacter(context), style: textStyle?.copyWith(color: PinballColors.white), ), ), ), ), ); } }