Skip to content
Snippets Groups Projects
Commit 12181a5d authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Merge branch '76-normalize-game-architecture' into 'master'

Resolve "Normalize game architecture"

Closes #76

See merge request !77
parents 5ba8b349 2921cc1c
No related branches found
No related tags found
1 merge request!77Resolve "Normalize game architecture"
Pipeline #5802 passed
Showing
with 609 additions and 334 deletions
import 'package:flutter/material.dart';
import 'package:wordguessing/data/fetch_data_helper.dart';
import 'package:wordguessing/models/word.dart';
import 'package:wordguessing/provider/data.dart';
import 'package:wordguessing/ui/games/abstract_game.dart';
class GamePickWordPage extends GameAbstract {
const GamePickWordPage({super.key});
@override
void pickData(Data myProvider) {
Word word;
int attempts = 0;
do {
final List<Word> words = FetchDataHelper().getWords(myProvider.lang, countWords);
word = words.take(1).toList()[0];
if ((words.length >= countWords) && !myProvider.isRecentlyPicked(word.key)) {
myProvider.updateWord(word);
myProvider.updateOtherWords(words.skip(1).toList());
myProvider.updateImages([word]);
}
attempts++;
} while (myProvider.word != word && attempts < 10);
}
Widget buildImageContainer(String image) {
const double imageSize = 130;
String imageAsset = 'assets/placeholder.png';
if (image != '') {
imageAsset = 'assets/images/$image';
}
return Container(
margin: const EdgeInsets.all(2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: Colors.blue.shade200,
width: 8,
),
),
child: Image(
image: AssetImage(imageAsset),
width: imageSize,
height: imageSize,
fit: BoxFit.fill,
),
);
}
Widget buildImageItemsBlock(Word? currentWord) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildImageContainer(currentWord?.images[0] ?? ''),
buildImageContainer(currentWord?.images[1] ?? ''),
],
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildImageContainer(currentWord?.images[2] ?? ''),
buildImageContainer(currentWord?.images[3] ?? ''),
],
)
],
);
}
Widget buildTextContainer(Data myProvider, Word word) {
return Container(
margin: const EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.blue[800],
borderRadius: BorderRadius.circular(6),
border: Border.all(
color: Colors.white,
width: 6,
),
),
child: TextButton(
style: TextButton.styleFrom(
padding: const EdgeInsets.all(15),
),
child: Text(
word.text,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
onPressed: () {
checkWord(myProvider, word);
},
),
);
}
Widget buildTextItemsBlock(Data myProvider) {
Word? word = myProvider.word;
List<Word> otherWords = myProvider.otherWords;
if ((word == null) || (otherWords.length != (countWords - 1))) {
return const Column();
}
List<Word> words = [
word,
otherWords[0],
otherWords[1],
otherWords[2],
];
words.sort((a, b) => a.key.compareTo(b.key));
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildTextContainer(myProvider, words[0]),
const SizedBox(width: 10),
buildTextContainer(myProvider, words[1]),
],
),
const SizedBox(height: 5),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildTextContainer(myProvider, words[2]),
const SizedBox(width: 10),
buildTextContainer(myProvider, words[3]),
],
)
],
);
}
@override
List<Widget> buildPageContent(Data myProvider) {
return <Widget>[
(myProvider.images.isNotEmpty)
? buildImageItemsBlock(myProvider.images[0])
: const SizedBox.shrink(),
const SizedBox(height: 2),
((myProvider.word == null) || (myProvider.word?.key == ''))
? buildStartGameBlock(myProvider)
: buildScoreContainer(myProvider),
const SizedBox(height: 2),
buildTextItemsBlock(myProvider),
];
}
}
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wordguessing/provider/data.dart';
class GameSelector extends StatelessWidget {
const GameSelector({super.key});
@override
Widget build(BuildContext context) {
final Data myProvider = Provider.of<Data>(context);
Widget buildMenuItemContainer(String code, Color color) {
const double imageSize = 150;
final String imageAsset = 'assets/menu/$code.png';
return Container(
margin: const EdgeInsets.all(2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: color,
width: 12,
),
),
child: GestureDetector(
child: Image(
image: AssetImage(imageAsset),
width: imageSize,
height: imageSize,
fit: BoxFit.fill,
),
onTap: () {
myProvider.resetGame();
switch (code) {
case 'game-pick-word':
myProvider.updateGameType(GameType.pickWord);
break;
case 'game-pick-image':
myProvider.updateGameType(GameType.pickImage);
break;
default:
}
},
),
);
}
Widget content = Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
buildMenuItemContainer('game-pick-word', Colors.pink),
buildMenuItemContainer('game-pick-image', Colors.yellow),
],
),
);
return content;
}
}
...@@ -8,16 +8,25 @@ class AppHeader extends StatelessWidget { ...@@ -8,16 +8,25 @@ class AppHeader extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Text(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
tr(text), tr(text),
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2), style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
), );
], }
}
class AppTitle extends StatelessWidget {
const AppTitle({super.key, required this.text});
final String text;
@override
Widget build(BuildContext context) {
return Text(
tr(text),
textAlign: TextAlign.start,
style: Theme.of(context).textTheme.titleLarge!.apply(fontWeightDelta: 2),
); );
} }
} }
import 'package:flutter/material.dart';
import 'package:wordguessing/utils/color_extensions.dart';
class OutlinedText extends StatelessWidget {
const OutlinedText({
super.key,
required this.text,
required this.fontSize,
required this.textColor,
this.outlineColor,
});
final String text;
final double fontSize;
final Color textColor;
final Color? outlineColor;
@override
Widget build(BuildContext context) {
final double delta = fontSize / 30;
return Text(
text,
style: TextStyle(
inherit: true,
fontSize: fontSize,
fontWeight: FontWeight.w600,
color: textColor,
shadows: [
Shadow(
offset: Offset(-delta, -delta),
color: outlineColor ?? textColor.darken(),
),
Shadow(
offset: Offset(delta, -delta),
color: outlineColor ?? textColor.darken(),
),
Shadow(
offset: Offset(delta, delta),
color: outlineColor ?? textColor.darken(),
),
Shadow(
offset: Offset(-delta, delta),
color: outlineColor ?? textColor.darken(),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wordguessing/cubit/game_cubit.dart';
import 'package:wordguessing/models/game/game.dart';
import 'package:wordguessing/ui/game/game_end.dart';
import 'package:wordguessing/ui/game/game_top.dart';
import 'package:wordguessing/ui/widgets/game/game_board.dart';
class GameLayout extends StatelessWidget {
const GameLayout({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) {
final Game currentGame = gameState.currentGame;
return Container(
alignment: AlignmentDirectional.topCenter,
padding: const EdgeInsets.all(4),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const GameTopWidget(),
const SizedBox(height: 8),
const GameBoardWidget(),
const Expanded(child: SizedBox.shrink()),
currentGame.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
],
),
);
},
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wordguessing/config/default_game_settings.dart';
import 'package:wordguessing/config/default_global_settings.dart';
import 'package:wordguessing/cubit/settings_game_cubit.dart';
import 'package:wordguessing/cubit/settings_global_cubit.dart';
import 'package:wordguessing/ui/parameters/parameter_image.dart';
import 'package:wordguessing/ui/parameters/parameter_painter.dart';
import 'package:wordguessing/ui/widgets/actions/button_delete_saved_game.dart';
import 'package:wordguessing/ui/widgets/actions/button_game_start_new.dart';
import 'package:wordguessing/ui/widgets/actions/button_resume_saved_game.dart';
class ParametersLayout extends StatelessWidget {
const ParametersLayout({super.key, required this.canResume});
final bool canResume;
final double separatorHeight = 8.0;
@override
Widget build(BuildContext context) {
final List<Widget> lines = [];
// Game settings
for (String code in DefaultGameSettings.availableParameters) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
code: code,
isGlobal: false,
),
));
lines.add(SizedBox(height: separatorHeight));
}
lines.add(SizedBox(height: separatorHeight));
if (canResume == false) {
// Start new game
lines.add(const Expanded(
child: StartNewGameButton(),
));
} else {
// Resume game
lines.add(const Expanded(
child: ResumeSavedGameButton(),
));
// Delete saved game
lines.add(SizedBox.square(
dimension: MediaQuery.of(context).size.width / 4,
child: const DeleteSavedGameButton(),
));
}
lines.add(SizedBox(height: separatorHeight));
// Global settings
for (String code in DefaultGlobalSettings.availableParameters) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
code: code,
isGlobal: true,
),
));
lines.add(SizedBox(height: separatorHeight));
}
return Column(
children: lines,
);
}
List<Widget> buildParametersLine({
required String code,
required bool isGlobal,
}) {
final List<Widget> parameterButtons = [];
final List<String> availableValues = isGlobal
? DefaultGlobalSettings.getAvailableValues(code)
: DefaultGameSettings.getAvailableValues(code);
if (availableValues.length <= 1) {
return [];
}
for (String value in availableValues) {
final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>(
builder: (BuildContext context, GameSettingsState gameSettingsState) {
return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
final GameSettingsCubit gameSettingsCubit =
BlocProvider.of<GameSettingsCubit>(context);
final GlobalSettingsCubit globalSettingsCubit =
BlocProvider.of<GlobalSettingsCubit>(context);
final String currentValue = isGlobal
? globalSettingsCubit.getParameterValue(code)
: gameSettingsCubit.getParameterValue(code);
final bool isActive = (value == currentValue);
final double displayWidth = MediaQuery.of(context).size.width;
final double itemWidth = displayWidth / availableValues.length - 26;
final bool displayedWithAssets =
DefaultGlobalSettings.displayedWithAssets.contains(code) ||
DefaultGameSettings.displayedWithAssets.contains(code);
return TextButton(
child: Container(
child: displayedWithAssets
? SizedBox.square(
dimension: itemWidth,
child: ParameterImage(
code: code,
value: value,
isSelected: isActive,
),
)
: CustomPaint(
size: Size(itemWidth, itemWidth),
willChange: false,
painter: ParameterPainter(
code: code,
value: value,
isSelected: isActive,
gameSettings: gameSettingsState.settings,
globalSettings: globalSettingsState.settings,
),
isComplex: true,
),
),
onPressed: () {
isGlobal
? globalSettingsCubit.setParameterValue(code, value)
: gameSettingsCubit.setParameterValue(code, value);
},
);
},
);
},
);
parameterButtons.add(parameterButton);
}
return parameterButtons;
}
}
import 'package:flutter/material.dart';
class ParameterImage extends StatelessWidget {
const ParameterImage({
super.key,
required this.code,
required this.value,
required this.isSelected,
});
final String code;
final String value;
final bool isSelected;
static const Color buttonBackgroundColor = Colors.white;
static const Color buttonBorderColorActive = Colors.blue;
static const Color buttonBorderColorInactive = Colors.white;
static const double buttonBorderWidth = 8.0;
static const double buttonBorderRadius = 8.0;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: buttonBackgroundColor,
borderRadius: BorderRadius.circular(buttonBorderRadius),
border: Border.all(
color: isSelected ? buttonBorderColorActive : buttonBorderColorInactive,
width: buttonBorderWidth,
),
),
child: Image(
image: AssetImage('assets/ui/${code}_$value.png'),
fit: BoxFit.fill,
),
);
}
}
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:wordguessing/config/default_game_settings.dart';
import 'package:wordguessing/models/settings/settings_game.dart';
import 'package:wordguessing/models/settings/settings_global.dart';
import 'package:wordguessing/utils/tools.dart';
class ParameterPainter extends CustomPainter {
const ParameterPainter({
required this.code,
required this.value,
required this.isSelected,
required this.gameSettings,
required this.globalSettings,
});
final String code;
final String value;
final bool isSelected;
final GameSettings gameSettings;
final GlobalSettings globalSettings;
@override
void paint(Canvas canvas, Size size) {
// force square
final double canvasSize = min(size.width, size.height);
const Color borderColorEnabled = Colors.blue;
const Color borderColorDisabled = Colors.white;
// "enabled/disabled" border
final paint = Paint();
paint.style = PaintingStyle.stroke;
paint.color = isSelected ? borderColorEnabled : borderColorDisabled;
paint.strokeJoin = StrokeJoin.round;
paint.strokeWidth = 10;
canvas.drawRect(
Rect.fromPoints(const Offset(0, 0), Offset(canvasSize, canvasSize)), paint);
// content
switch (code) {
case DefaultGameSettings.parameterCodeLangValue:
paintLangParameterItem(value, canvas, canvasSize);
break;
default:
printlog('Unknown parameter: $code/$value');
paintUnknownParameterItem(value, canvas, canvasSize);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
// "unknown" parameter -> simple block with text
void paintUnknownParameterItem(
final String value,
final Canvas canvas,
final double size,
) {
final paint = Paint();
paint.strokeJoin = StrokeJoin.round;
paint.strokeWidth = 3;
paint.color = Colors.grey;
paint.style = PaintingStyle.fill;
canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
final textSpan = TextSpan(
text: '?\n$value',
style: const TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.bold,
),
);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
);
textPainter.layout();
textPainter.paint(
canvas,
Offset(
(size - textPainter.width) * 0.5,
(size - textPainter.height) * 0.5,
),
);
}
void paintLangParameterItem(
final String value,
final Canvas canvas,
final double size,
) {
Color backgroundColor = Colors.grey;
String text = '';
switch (value) {
case DefaultGameSettings.langValueFr:
text = '🇫🇷';
backgroundColor = Colors.teal;
break;
case DefaultGameSettings.langValueEn:
text = '🇬🇧';
backgroundColor = Colors.teal;
break;
default:
printlog('Wrong value for lang parameter value: $value');
}
final paint = Paint();
paint.strokeJoin = StrokeJoin.round;
paint.strokeWidth = 3;
// Colored background
paint.color = backgroundColor;
paint.style = PaintingStyle.fill;
canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
// centered text value
final textSpan = TextSpan(
text: text,
style: TextStyle(
color: Colors.black,
fontSize: size / 2.6,
fontWeight: FontWeight.bold,
),
);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
);
textPainter.layout();
textPainter.paint(
canvas,
Offset(
(size - textPainter.width) * 0.5,
(size - textPainter.height) * 0.5,
),
);
}
}
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wordguessing/provider/data.dart';
import 'package:wordguessing/ui/games/game_pick_image.dart';
import 'package:wordguessing/ui/games/game_pick_word.dart';
import 'package:wordguessing/ui/games/game_selector.dart';
class GamePage extends StatelessWidget {
const GamePage({super.key});
@override
Widget build(BuildContext context) {
final Data myProvider = Provider.of<Data>(context);
switch (myProvider.gameType) {
case GameType.pickImage:
return const GamePickImagePage();
case GameType.pickWord:
return const GamePickWordPage();
default:
return const GameSelector();
}
}
}
...@@ -2,10 +2,10 @@ import 'package:easy_localization/easy_localization.dart'; ...@@ -2,10 +2,10 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:wordguessing/ui/widgets/header_app.dart'; import 'package:wordguessing/ui/helpers/app_titles.dart';
class AboutPage extends StatelessWidget { class PageAbout extends StatelessWidget {
const AboutPage({super.key}); const PageAbout({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -17,7 +17,7 @@ class AboutPage extends StatelessWidget { ...@@ -17,7 +17,7 @@ class AboutPage extends StatelessWidget {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
const SizedBox(height: 8), const SizedBox(height: 8),
const AppHeader(text: 'about_title'), const AppTitle(text: 'about_title'),
const Text('about_content').tr(), const Text('about_content').tr(),
FutureBuilder<PackageInfo>( FutureBuilder<PackageInfo>(
future: PackageInfo.fromPlatform(), future: PackageInfo.fromPlatform(),
......
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wordguessing/cubit/game_cubit.dart';
import 'package:wordguessing/models/game/game.dart';
import 'package:wordguessing/ui/layouts/game_layout.dart';
import 'package:wordguessing/ui/layouts/parameters_layout.dart';
class PageGame extends StatelessWidget {
const PageGame({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) {
final Game currentGame = gameState.currentGame;
return currentGame.isRunning
? const GameLayout()
: ParametersLayout(canResume: currentGame.canBeResumed);
},
);
}
}
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:wordguessing/ui/widgets/header_app.dart'; import 'package:wordguessing/ui/helpers/app_titles.dart';
import 'package:wordguessing/ui/widgets/settings/settings_form.dart'; import 'package:wordguessing/ui/settings/settings_form.dart';
class SettingsPage extends StatelessWidget { class PageSettings extends StatelessWidget {
const SettingsPage({super.key}); const PageSettings({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -16,7 +16,7 @@ class SettingsPage extends StatelessWidget { ...@@ -16,7 +16,7 @@ class SettingsPage extends StatelessWidget {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
SizedBox(height: 8), SizedBox(height: 8),
AppHeader(text: 'settings_title'), AppTitle(text: 'settings_title'),
SizedBox(height: 8), SizedBox(height: 8),
SettingsForm(), SettingsForm(),
], ],
......
...@@ -2,7 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; ...@@ -2,7 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:unicons/unicons.dart'; import 'package:unicons/unicons.dart';
import 'package:wordguessing/ui/widgets/settings/theme_card.dart'; import 'package:wordguessing/ui/settings/theme_card.dart';
class SettingsForm extends StatefulWidget { class SettingsForm extends StatefulWidget {
const SettingsForm({super.key}); const SettingsForm({super.key});
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_swipe/flutter_swipe.dart';
import 'package:provider/provider.dart';
import 'package:wordguessing/config/menu.dart'; import 'package:wordguessing/config/menu.dart';
import 'package:wordguessing/cubit/bottom_nav_cubit.dart'; import 'package:wordguessing/cubit/nav_cubit.dart';
import 'package:wordguessing/provider/data.dart'; import 'package:wordguessing/ui/widgets/global_app_bar.dart';
import 'package:wordguessing/ui/widgets/app_bar.dart';
import 'package:wordguessing/ui/widgets/bottom_nav_bar.dart';
class SkeletonScreen extends StatefulWidget { class SkeletonScreen extends StatelessWidget {
const SkeletonScreen({super.key}); const SkeletonScreen({super.key});
@override
State<SkeletonScreen> createState() => _SkeletonScreenState();
}
class _SkeletonScreenState extends State<SkeletonScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Data myProvider = Provider.of<Data>(context);
return Scaffold( return Scaffold(
appBar: const GlobalAppBar(),
extendBodyBehindAppBar: false, extendBodyBehindAppBar: false,
appBar: StandardAppBar(myProvider: myProvider), body: Material(
body: Swiper( color: Theme.of(context).colorScheme.surface,
itemCount: Menu.itemsCount, child: BlocBuilder<NavCubit, int>(
itemBuilder: (BuildContext context, int index) { builder: (BuildContext context, int pageIndex) {
return Menu.getPageWidget(index); return Padding(
}, padding: const EdgeInsets.only(
pagination: SwiperPagination( top: 8,
margin: const EdgeInsets.all(0), left: 2,
builder: SwiperCustomPagination( right: 2,
builder: (BuildContext context, SwiperPluginConfig config) {
return BottomNavBar(swipeController: config.controller);
},
),
), ),
onIndexChanged: (newPageIndex) { child: Menu.getPageWidget(pageIndex),
BlocProvider.of<BottomNavCubit>(context).updateIndex(newPageIndex); );
}, },
outer: true,
loop: false,
), ),
backgroundColor: Theme.of(context).colorScheme.background, ),
backgroundColor: Theme.of(context).colorScheme.surface,
); );
} }
} }
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wordguessing/cubit/game_cubit.dart';
class DeleteSavedGameButton extends StatelessWidget {
const DeleteSavedGameButton({super.key});
@override
Widget build(BuildContext context) {
return TextButton(
child: const Image(
image: AssetImage('assets/ui/button_delete_saved_game.png'),
fit: BoxFit.fill,
),
onPressed: () {
BlocProvider.of<GameCubit>(context).deleteSavedGame();
},
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wordguessing/cubit/game_cubit.dart';
class QuitGameButton extends StatelessWidget {
const QuitGameButton({super.key});
@override
Widget build(BuildContext context) {
return TextButton(
child: const Image(
image: AssetImage('assets/ui/button_back.png'),
fit: BoxFit.fill,
),
onPressed: () {
BlocProvider.of<GameCubit>(context).quitGame();
},
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wordguessing/cubit/game_cubit.dart';
import 'package:wordguessing/cubit/settings_game_cubit.dart';
import 'package:wordguessing/cubit/settings_global_cubit.dart';
class StartNewGameButton extends StatelessWidget {
const StartNewGameButton({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameSettingsCubit, GameSettingsState>(
builder: (BuildContext context, GameSettingsState gameSettingsState) {
return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
return TextButton(
child: const Image(
image: AssetImage('assets/ui/button_start.png'),
fit: BoxFit.fill,
),
onPressed: () {
BlocProvider.of<GameCubit>(context).startNewGame(
gameSettings: gameSettingsState.settings,
globalSettings: globalSettingsState.settings,
);
},
);
},
);
},
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wordguessing/cubit/game_cubit.dart';
class ResumeSavedGameButton extends StatelessWidget {
const ResumeSavedGameButton({super.key});
@override
Widget build(BuildContext context) {
return TextButton(
child: const Image(
image: AssetImage('assets/ui/button_resume_game.png'),
fit: BoxFit.fill,
),
onPressed: () {
BlocProvider.of<GameCubit>(context).resumeSavedGame();
},
);
}
}
import 'package:flutter/material.dart';
import 'package:wordguessing/provider/data.dart';
import 'package:wordguessing/ui/widgets/header_app.dart';
class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
const StandardAppBar({super.key, required this.myProvider});
final Data myProvider;
@override
Widget build(BuildContext context) {
final List<Widget> menuActions = [];
if (myProvider.gameType != null) {
menuActions.add(
IconButton(
icon: const Icon(Icons.loop),
onPressed: () => myProvider.resetGame(),
),
);
}
return AppBar(
title: const AppHeader(text: 'app_name'),
actions: menuActions,
);
}
@override
Size get preferredSize => const Size.fromHeight(50);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment