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

Normalize game architecture

parent c3ed1087
Branches
Tags
1 merge request!43Resolve "Normalize game architecture"
Pipeline #5686 passed
Showing
with 531 additions and 129 deletions
...@@ -12,8 +12,4 @@ class GlobalSettingsState extends Equatable { ...@@ -12,8 +12,4 @@ class GlobalSettingsState extends Equatable {
List<dynamic> get props => <dynamic>[ List<dynamic> get props => <dynamic>[
settings, settings,
]; ];
Map<String, dynamic> get values => <String, dynamic>{
'settings': settings,
};
} }
...@@ -2,8 +2,8 @@ import 'dart:math'; ...@@ -2,8 +2,8 @@ import 'dart:math';
import 'package:petitbac/data/game_data.dart'; import 'package:petitbac/data/game_data.dart';
import 'package:petitbac/models/data/category.dart'; import 'package:petitbac/models/data/category.dart';
import 'package:petitbac/models/data/game_item.dart';
import 'package:petitbac/models/data/letter.dart'; import 'package:petitbac/models/data/letter.dart';
import 'package:petitbac/models/game/game_item.dart';
import 'package:petitbac/utils/tools.dart'; import 'package:petitbac/utils/tools.dart';
class FetchDataHelper { class FetchDataHelper {
......
...@@ -2,6 +2,7 @@ import 'dart:io'; ...@@ -2,6 +2,7 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart';
...@@ -25,8 +26,8 @@ void main() async { ...@@ -25,8 +26,8 @@ void main() async {
storageDirectory: tmpDir, storageDirectory: tmpDir,
); );
runApp( SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
EasyLocalization( .then((value) => runApp(EasyLocalization(
path: 'assets/translations', path: 'assets/translations',
supportedLocales: const <Locale>[ supportedLocales: const <Locale>[
Locale('en'), Locale('en'),
...@@ -35,8 +36,7 @@ void main() async { ...@@ -35,8 +36,7 @@ void main() async {
fallbackLocale: const Locale('en'), fallbackLocale: const Locale('en'),
useFallbackTranslations: true, useFallbackTranslations: true,
child: const MyApp(), child: const MyApp(),
), )));
);
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
...@@ -44,6 +44,11 @@ class MyApp extends StatelessWidget { ...@@ -44,6 +44,11 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<String> assets = getImagesAssets();
for (String asset in assets) {
precacheImage(AssetImage(asset), context);
}
return MultiBlocProvider( return MultiBlocProvider(
providers: [ providers: [
BlocProvider<NavCubit>(create: (context) => NavCubit()), BlocProvider<NavCubit>(create: (context) => NavCubit()),
...@@ -73,4 +78,23 @@ class MyApp extends StatelessWidget { ...@@ -73,4 +78,23 @@ class MyApp extends StatelessWidget {
), ),
); );
} }
List<String> getImagesAssets() {
final List<String> assets = [];
const List<String> gameImages = [
'button_back',
'button_delete_saved_game',
'button_resume_game',
'button_start',
'game_end',
'placeholder',
];
for (String image in gameImages) {
assets.add('assets/ui/$image.png');
}
return assets;
}
} }
import 'package:petitbac/data/fetch_data_helper.dart'; import 'package:petitbac/data/fetch_data_helper.dart';
import 'package:petitbac/models/data/category.dart'; import 'package:petitbac/models/data/category.dart';
import 'package:petitbac/models/data/game_item.dart';
import 'package:petitbac/models/data/letter.dart'; import 'package:petitbac/models/data/letter.dart';
import 'package:petitbac/models/settings_game.dart'; import 'package:petitbac/models/game/game_item.dart';
import 'package:petitbac/models/settings_global.dart'; import 'package:petitbac/models/settings/settings_game.dart';
import 'package:petitbac/models/settings/settings_global.dart';
import 'package:petitbac/utils/tools.dart'; import 'package:petitbac/utils/tools.dart';
class Game { class Game {
final List<GameItem> items;
final GameSettings gameSettings;
final GlobalSettings globalSettings;
int countdown = 0;
int position = 0;
bool isRunning = false;
bool isFinished = false;
Game({ Game({
required this.items, // Settings
required this.gameSettings, required this.gameSettings,
required this.globalSettings, required this.globalSettings,
required this.countdown,
required this.position, // State
this.isRunning = false, this.isRunning = false,
this.isStarted = false,
this.isFinished = false, this.isFinished = false,
this.animationInProgress = false,
// Base data
required this.items,
// Game data
this.position = 0,
this.countdown = 0,
}); });
factory Game.createNull() { // Settings
final GameSettings gameSettings;
final GlobalSettings globalSettings;
// State
bool isRunning;
bool isStarted;
bool isFinished;
bool animationInProgress;
// Base data
final List<GameItem> items;
// Game data
int position;
int countdown;
factory Game.createEmpty() {
return Game( return Game(
items: [],
gameSettings: GameSettings.createDefault(), gameSettings: GameSettings.createDefault(),
globalSettings: GlobalSettings.createDefault(), globalSettings: GlobalSettings.createDefault(),
countdown: 0, items: [],
position: 0,
); );
} }
...@@ -39,25 +55,25 @@ class Game { ...@@ -39,25 +55,25 @@ class Game {
GameSettings? gameSettings, GameSettings? gameSettings,
GlobalSettings? globalSettings, GlobalSettings? globalSettings,
}) { }) {
GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault(); final GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault();
GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault(); final GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
List<GameItem> items = FetchDataHelper().getRandomItems(newGameSettings.itemsCount); final List<GameItem> items =
FetchDataHelper().getRandomItems(newGameSettings.itemsCountValue);
return Game( return Game(
items: items, // Settings
gameSettings: newGameSettings, gameSettings: newGameSettings,
globalSettings: newGlobalSettings, globalSettings: newGlobalSettings,
countdown: 0, // State
position: 0,
isRunning: true, isRunning: true,
isFinished: false, isStarted: true,
// Base data
items: items,
); );
} }
void stop() { bool get canBeResumed => isStarted && !isFinished;
isRunning = false;
}
GameItem get item => items[position]; GameItem get item => items[position];
Category get category => item.category; Category get category => item.category;
...@@ -67,15 +83,18 @@ class Game { ...@@ -67,15 +83,18 @@ class Game {
printlog(''); printlog('');
printlog('## Current game dump:'); printlog('## Current game dump:');
printlog(''); printlog('');
printlog('$Game:');
printlog(' Settings');
gameSettings.dump(); gameSettings.dump();
globalSettings.dump(); globalSettings.dump();
printlog(''); printlog(' State');
printlog('items:');
printlog(items.toString());
printlog('');
printlog('Game: ');
printlog(' isRunning: $isRunning'); printlog(' isRunning: $isRunning');
printlog(' isStarted: $isStarted');
printlog(' isFinished: $isFinished'); printlog(' isFinished: $isFinished');
printlog(' animationInProgress: $animationInProgress');
printlog(' Base data');
printlog(' items: $items');
printlog(' Game data');
printlog(' position: $position'); printlog(' position: $position');
printlog(' countdown: $countdown'); printlog(' countdown: $countdown');
printlog(''); printlog('');
...@@ -88,13 +107,19 @@ class Game { ...@@ -88,13 +107,19 @@ class Game {
Map<String, dynamic>? toJson() { Map<String, dynamic>? toJson() {
return <String, dynamic>{ return <String, dynamic>{
'items': items, // Settings
'gameSettings': gameSettings, 'gameSettings': gameSettings.toJson(),
'globalSettings': globalSettings, 'globalSettings': globalSettings.toJson(),
'countdown': countdown, // State
'position': position,
'isRunning': isRunning, 'isRunning': isRunning,
'isStarted': isStarted,
'isFinished': isFinished, 'isFinished': isFinished,
'animationInProgress': animationInProgress,
// Base data
'items': items,
// Game data
'position': position,
'countdown': countdown,
}; };
} }
} }
File moved
...@@ -2,15 +2,18 @@ import 'package:petitbac/config/default_game_settings.dart'; ...@@ -2,15 +2,18 @@ import 'package:petitbac/config/default_game_settings.dart';
import 'package:petitbac/utils/tools.dart'; import 'package:petitbac/utils/tools.dart';
class GameSettings { class GameSettings {
final int itemsCount; final String itemsCount;
final int timerValue; final String timerValue;
GameSettings({ GameSettings({
required this.itemsCount, required this.itemsCount,
required this.timerValue, required this.timerValue,
}); });
static int getItemsCountValueFromUnsafe(int itemsCount) { int get itemsCountValue => DefaultGameSettings.getItemsCountValueFromCode(itemsCount);
int get timerCountValue => DefaultGameSettings.getTimerValueFromCode(timerValue);
static String getItemsCountValueFromUnsafe(String itemsCount) {
if (DefaultGameSettings.allowedItemsCountValues.contains(itemsCount)) { if (DefaultGameSettings.allowedItemsCountValues.contains(itemsCount)) {
return itemsCount; return itemsCount;
} }
...@@ -18,7 +21,7 @@ class GameSettings { ...@@ -18,7 +21,7 @@ class GameSettings {
return DefaultGameSettings.defaultItemsCountValue; return DefaultGameSettings.defaultItemsCountValue;
} }
static int getTimerValueFromUnsafe(int timerValue) { static String getTimerValueFromUnsafe(String timerValue) {
if (DefaultGameSettings.allowedTimerValues.contains(timerValue)) { if (DefaultGameSettings.allowedTimerValues.contains(timerValue)) {
return timerValue; return timerValue;
} }
...@@ -34,9 +37,10 @@ class GameSettings { ...@@ -34,9 +37,10 @@ class GameSettings {
} }
void dump() { void dump() {
printlog('Game settings: '); printlog('$GameSettings:');
printlog(' itemsCount: $itemsCount'); printlog(' ${DefaultGameSettings.parameterCodeItemsCount}: $itemsCount');
printlog(' timerValue: $timerValue'); printlog(' ${DefaultGameSettings.parameterCodeTimerValue}: $timerValue');
printlog('');
} }
@override @override
...@@ -46,8 +50,8 @@ class GameSettings { ...@@ -46,8 +50,8 @@ class GameSettings {
Map<String, dynamic>? toJson() { Map<String, dynamic>? toJson() {
return <String, dynamic>{ return <String, dynamic>{
'itemsCount': itemsCount, DefaultGameSettings.parameterCodeItemsCount: itemsCount,
'timerValue': timerValue, DefaultGameSettings.parameterCodeTimerValue: timerValue,
}; };
} }
} }
import 'package:petitbac/config/default_global_settings.dart';
import 'package:petitbac/utils/tools.dart';
class GlobalSettings {
String skin;
GlobalSettings({
required this.skin,
});
static String getSkinValueFromUnsafe(String skin) {
if (DefaultGlobalSettings.allowedSkinValues.contains(skin)) {
return skin;
}
return DefaultGlobalSettings.defaultSkinValue;
}
factory GlobalSettings.createDefault() {
return GlobalSettings(
skin: DefaultGlobalSettings.defaultSkinValue,
);
}
void dump() {
printlog('$GlobalSettings:');
printlog(' ${DefaultGlobalSettings.parameterCodeSkin}: $skin');
printlog('');
}
@override
String toString() {
return '$GlobalSettings(${toJson()})';
}
Map<String, dynamic>? toJson() {
return <String, dynamic>{
DefaultGlobalSettings.parameterCodeSkin: skin,
};
}
}
import 'package:petitbac/utils/tools.dart';
class GlobalSettings {
GlobalSettings();
factory GlobalSettings.createDefault() {
return GlobalSettings();
}
void dump() {
printlog('Global settings: ');
printlog(' (none)');
}
@override
String toString() {
return '$GlobalSettings(${toJson()})';
}
Map<String, dynamic>? toJson() {
return <String, dynamic>{};
}
}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:petitbac/cubit/game_cubit.dart';
import 'package:petitbac/models/game/game.dart';
import 'package:petitbac/ui/widgets/actions/button_game_quit.dart';
class GameEndWidget extends StatelessWidget {
const GameEndWidget({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) {
final Game currentGame = gameState.currentGame;
const Image decorationImage = Image(
image: AssetImage('assets/ui/game_end.png'),
fit: BoxFit.fill,
);
return Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Table(
defaultColumnWidth: const IntrinsicColumnWidth(),
children: [
TableRow(
children: [
const Column(
children: [decorationImage],
),
const Column(
children: [decorationImage],
),
Column(
children: [
currentGame.animationInProgress == true
? decorationImage
: const QuitGameButton()
],
),
const Column(
children: [decorationImage],
),
const Column(
children: [decorationImage],
),
],
),
],
),
);
},
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:petitbac/cubit/game_cubit.dart';
import 'package:petitbac/models/game/game.dart';
import 'package:petitbac/ui/widgets/game/game_position_indicator.dart';
class GameTopWidget extends StatelessWidget {
const GameTopWidget({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) {
final Game currentGame = gameState.currentGame;
return currentGame.gameSettings.itemsCountValue != 0
? const GamePositionIndicator()
: const SizedBox.shrink();
},
);
}
}
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AppHeader extends StatelessWidget {
const AppHeader({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.headlineMedium!.apply(fontWeightDelta: 2),
);
}
}
class AppTitle extends StatelessWidget { class AppTitle extends StatelessWidget {
const AppTitle({super.key, required this.text}); const AppTitle({super.key, required this.text});
...@@ -11,7 +26,7 @@ class AppTitle extends StatelessWidget { ...@@ -11,7 +26,7 @@ class AppTitle extends StatelessWidget {
return Text( return Text(
tr(text), tr(text),
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: Theme.of(context).textTheme.headlineLarge!.apply(fontWeightDelta: 2), style: Theme.of(context).textTheme.titleLarge!.apply(fontWeightDelta: 2),
); );
} }
} }
...@@ -2,14 +2,13 @@ import 'package:flutter/material.dart'; ...@@ -2,14 +2,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:petitbac/cubit/game_cubit.dart'; import 'package:petitbac/cubit/game_cubit.dart';
import 'package:petitbac/models/game.dart'; import 'package:petitbac/models/game/game.dart';
import 'package:petitbac/ui/widgets/game/game_countdown.dart'; import 'package:petitbac/ui/game/game_end.dart';
import 'package:petitbac/ui/widgets/game/game_position_indicator.dart'; import 'package:petitbac/ui/game/game_top.dart';
import 'package:petitbac/ui/widgets/game/widget_category.dart'; import 'package:petitbac/ui/widgets/game/game_board.dart';
import 'package:petitbac/ui/widgets/game/widget_letter.dart';
class GameWidget extends StatelessWidget { class GameLayout extends StatelessWidget {
const GameWidget({super.key}); const GameLayout({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -17,17 +16,19 @@ class GameWidget extends StatelessWidget { ...@@ -17,17 +16,19 @@ class GameWidget extends StatelessWidget {
builder: (BuildContext context, GameState gameState) { builder: (BuildContext context, GameState gameState) {
final Game currentGame = gameState.currentGame; final Game currentGame = gameState.currentGame;
return Center( return Container(
alignment: AlignmentDirectional.topCenter,
padding: const EdgeInsets.all(4),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
currentGame.gameSettings.itemsCount != 0 const GameTopWidget(),
? const GamePositionIndicator() const SizedBox(height: 8),
: const SizedBox.shrink(), const GameBoardWidget(),
const WidgetLetter(), const SizedBox(height: 8),
const GameButtonNextWithCountdown(), const Expanded(child: SizedBox.shrink()),
const WidgetCategory(), currentGame.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
], ],
), ),
); );
......
...@@ -5,11 +5,16 @@ import 'package:petitbac/config/default_game_settings.dart'; ...@@ -5,11 +5,16 @@ import 'package:petitbac/config/default_game_settings.dart';
import 'package:petitbac/config/default_global_settings.dart'; import 'package:petitbac/config/default_global_settings.dart';
import 'package:petitbac/cubit/settings_game_cubit.dart'; import 'package:petitbac/cubit/settings_game_cubit.dart';
import 'package:petitbac/cubit/settings_global_cubit.dart'; import 'package:petitbac/cubit/settings_global_cubit.dart';
import 'package:petitbac/ui/painters/parameter_painter.dart'; import 'package:petitbac/ui/parameters/parameter_image.dart';
import 'package:petitbac/ui/widgets/button_game_start_new.dart'; import 'package:petitbac/ui/parameters/parameter_painter.dart';
import 'package:petitbac/ui/widgets/actions/button_delete_saved_game.dart';
import 'package:petitbac/ui/widgets/actions/button_game_start_new.dart';
import 'package:petitbac/ui/widgets/actions/button_resume_saved_game.dart';
class Parameters extends StatelessWidget { class ParametersLayout extends StatelessWidget {
const Parameters({super.key}); const ParametersLayout({super.key, required this.canResume});
final bool canResume;
final double separatorHeight = 8.0; final double separatorHeight = 8.0;
...@@ -31,7 +36,24 @@ class Parameters extends StatelessWidget { ...@@ -31,7 +36,24 @@ class Parameters extends StatelessWidget {
} }
lines.add(SizedBox(height: separatorHeight)); lines.add(SizedBox(height: separatorHeight));
lines.add(const Expanded(child: StartNewGameButton()));
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)); lines.add(SizedBox(height: separatorHeight));
// Global settings // Global settings
...@@ -58,7 +80,7 @@ class Parameters extends StatelessWidget { ...@@ -58,7 +80,7 @@ class Parameters extends StatelessWidget {
}) { }) {
final List<Widget> parameterButtons = []; final List<Widget> parameterButtons = [];
final List<int> availableValues = isGlobal final List<String> availableValues = isGlobal
? DefaultGlobalSettings.getAvailableValues(code) ? DefaultGlobalSettings.getAvailableValues(code)
: DefaultGameSettings.getAvailableValues(code); : DefaultGameSettings.getAvailableValues(code);
...@@ -66,7 +88,7 @@ class Parameters extends StatelessWidget { ...@@ -66,7 +88,7 @@ class Parameters extends StatelessWidget {
return []; return [];
} }
for (int value in availableValues) { for (String value in availableValues) {
final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>( final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>(
builder: (BuildContext context, GameSettingsState gameSettingsState) { builder: (BuildContext context, GameSettingsState gameSettingsState) {
return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>( return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
...@@ -76,7 +98,7 @@ class Parameters extends StatelessWidget { ...@@ -76,7 +98,7 @@ class Parameters extends StatelessWidget {
final GlobalSettingsCubit globalSettingsCubit = final GlobalSettingsCubit globalSettingsCubit =
BlocProvider.of<GlobalSettingsCubit>(context); BlocProvider.of<GlobalSettingsCubit>(context);
final int currentValue = isGlobal final String currentValue = isGlobal
? globalSettingsCubit.getParameterValue(code) ? globalSettingsCubit.getParameterValue(code)
: gameSettingsCubit.getParameterValue(code); : gameSettingsCubit.getParameterValue(code);
...@@ -85,8 +107,22 @@ class Parameters extends StatelessWidget { ...@@ -85,8 +107,22 @@ class Parameters extends StatelessWidget {
final double displayWidth = MediaQuery.of(context).size.width; final double displayWidth = MediaQuery.of(context).size.width;
final double itemWidth = displayWidth / availableValues.length - 26; final double itemWidth = displayWidth / availableValues.length - 26;
final bool displayedWithAssets =
DefaultGlobalSettings.displayedWithAssets.contains(code) ||
DefaultGameSettings.displayedWithAssets.contains(code);
return TextButton( return TextButton(
child: CustomPaint( child: Container(
child: displayedWithAssets
? SizedBox.square(
dimension: itemWidth,
child: ParameterImage(
code: code,
value: value,
isSelected: isActive,
),
)
: CustomPaint(
size: Size(itemWidth, itemWidth), size: Size(itemWidth, itemWidth),
willChange: false, willChange: false,
painter: ParameterPainter( painter: ParameterPainter(
...@@ -98,9 +134,12 @@ class Parameters extends StatelessWidget { ...@@ -98,9 +134,12 @@ class Parameters extends StatelessWidget {
), ),
isComplex: true, isComplex: true,
), ),
onPressed: () => isGlobal ),
onPressed: () {
isGlobal
? globalSettingsCubit.setParameterValue(code, value) ? globalSettingsCubit.setParameterValue(code, value)
: gameSettingsCubit.setParameterValue(code, value), : gameSettingsCubit.setParameterValue(code, value);
},
); );
}, },
); );
......
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,
),
);
}
}
...@@ -3,8 +3,8 @@ import 'dart:math'; ...@@ -3,8 +3,8 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:petitbac/config/default_game_settings.dart'; import 'package:petitbac/config/default_game_settings.dart';
import 'package:petitbac/models/settings_game.dart'; import 'package:petitbac/models/settings/settings_game.dart';
import 'package:petitbac/models/settings_global.dart'; import 'package:petitbac/models/settings/settings_global.dart';
import 'package:petitbac/utils/tools.dart'; import 'package:petitbac/utils/tools.dart';
class ParameterPainter extends CustomPainter { class ParameterPainter extends CustomPainter {
...@@ -17,7 +17,7 @@ class ParameterPainter extends CustomPainter { ...@@ -17,7 +17,7 @@ class ParameterPainter extends CustomPainter {
}); });
final String code; final String code;
final int value; final String value;
final bool isSelected; final bool isSelected;
final GameSettings gameSettings; final GameSettings gameSettings;
final GlobalSettings globalSettings; final GlobalSettings globalSettings;
...@@ -60,7 +60,7 @@ class ParameterPainter extends CustomPainter { ...@@ -60,7 +60,7 @@ class ParameterPainter extends CustomPainter {
// "unknown" parameter -> simple block with text // "unknown" parameter -> simple block with text
void paintUnknownParameterItem( void paintUnknownParameterItem(
final int value, final String value,
final Canvas canvas, final Canvas canvas,
final double size, final double size,
) { ) {
...@@ -96,14 +96,14 @@ class ParameterPainter extends CustomPainter { ...@@ -96,14 +96,14 @@ class ParameterPainter extends CustomPainter {
} }
void paintItemsCountParameterItem( void paintItemsCountParameterItem(
final int value, final String value,
final Canvas canvas, final Canvas canvas,
final double size, final double size,
) { ) {
const itemCountEmoji = '💬\n'; const itemCountEmoji = '💬';
Color backgroundColor = Colors.grey; Color backgroundColor = Colors.grey;
String text = ''; String text = '$itemCountEmoji\n${DefaultGameSettings.getItemsCountValueFromCode(value)}';
switch (value) { switch (value) {
case DefaultGameSettings.itemsCountValueNoLimit: case DefaultGameSettings.itemsCountValueNoLimit:
...@@ -112,15 +112,12 @@ class ParameterPainter extends CustomPainter { ...@@ -112,15 +112,12 @@ class ParameterPainter extends CustomPainter {
break; break;
case DefaultGameSettings.itemsCountValueShort: case DefaultGameSettings.itemsCountValueShort:
backgroundColor = Colors.green; backgroundColor = Colors.green;
text = itemCountEmoji + DefaultGameSettings.itemsCountValueShort.toString();
break; break;
case DefaultGameSettings.itemsCountValueMedium: case DefaultGameSettings.itemsCountValueMedium:
backgroundColor = Colors.orange; backgroundColor = Colors.orange;
text = itemCountEmoji + DefaultGameSettings.itemsCountValueMedium.toString();
break; break;
case DefaultGameSettings.itemsCountValueLong: case DefaultGameSettings.itemsCountValueLong:
backgroundColor = Colors.red; backgroundColor = Colors.red;
text = itemCountEmoji + DefaultGameSettings.itemsCountValueLong.toString();
break; break;
default: default:
printlog('Wrong value for itemsCount parameter value: $value'); printlog('Wrong value for itemsCount parameter value: $value');
...@@ -160,14 +157,14 @@ class ParameterPainter extends CustomPainter { ...@@ -160,14 +157,14 @@ class ParameterPainter extends CustomPainter {
} }
void paintTimerParameterItem( void paintTimerParameterItem(
final int value, final String value,
final Canvas canvas, final Canvas canvas,
final double size, final double size,
) { ) {
const timerEmoji = '⏲️\n'; const timerEmoji = '⏲️';
Color backgroundColor = Colors.grey; Color backgroundColor = Colors.grey;
String text = ''; String text = '$timerEmoji\n${DefaultGameSettings.getTimerValueFromCode(value)}"';
switch (value) { switch (value) {
case DefaultGameSettings.timerValueNoTimer: case DefaultGameSettings.timerValueNoTimer:
...@@ -176,15 +173,12 @@ class ParameterPainter extends CustomPainter { ...@@ -176,15 +173,12 @@ class ParameterPainter extends CustomPainter {
break; break;
case DefaultGameSettings.timerValueLow: case DefaultGameSettings.timerValueLow:
backgroundColor = Colors.green; backgroundColor = Colors.green;
text = '$timerEmoji${DefaultGameSettings.timerValueLow}"';
break; break;
case DefaultGameSettings.timerValueMedium: case DefaultGameSettings.timerValueMedium:
backgroundColor = Colors.orange; backgroundColor = Colors.orange;
text = '$timerEmoji${DefaultGameSettings.timerValueMedium}"';
break; break;
case DefaultGameSettings.timerValueHigh: case DefaultGameSettings.timerValueHigh:
backgroundColor = Colors.red; backgroundColor = Colors.red;
text = '$timerEmoji${DefaultGameSettings.timerValueHigh}"';
break; break;
default: default:
printlog('Wrong value for itemsCount parameter value: $value'); printlog('Wrong value for itemsCount parameter value: $value');
...@@ -192,7 +186,7 @@ class ParameterPainter extends CustomPainter { ...@@ -192,7 +186,7 @@ class ParameterPainter extends CustomPainter {
final paint = Paint(); final paint = Paint();
paint.strokeJoin = StrokeJoin.round; paint.strokeJoin = StrokeJoin.round;
paint.strokeWidth = 3 / 100 * size; paint.strokeWidth = 3;
// Colored background // Colored background
paint.color = backgroundColor; paint.color = backgroundColor;
......
...@@ -2,19 +2,22 @@ import 'package:easy_localization/easy_localization.dart'; ...@@ -2,19 +2,22 @@ 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:petitbac/ui/widgets/helpers/app_header.dart'; import 'package:petitbac/ui/helpers/app_titles.dart';
class PageAbout extends StatelessWidget { class PageAbout extends StatelessWidget {
const PageAbout({super.key}); const PageAbout({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
const AppHeader(text: 'about_title'), const SizedBox(height: 8),
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(),
...@@ -32,6 +35,7 @@ class PageAbout extends StatelessWidget { ...@@ -32,6 +35,7 @@ class PageAbout extends StatelessWidget {
}, },
), ),
], ],
),
); );
} }
} }
...@@ -2,8 +2,9 @@ import 'package:flutter/material.dart'; ...@@ -2,8 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:petitbac/cubit/game_cubit.dart'; import 'package:petitbac/cubit/game_cubit.dart';
import 'package:petitbac/ui/widgets/game/game.dart'; import 'package:petitbac/models/game/game.dart';
import 'package:petitbac/ui/widgets/parameters.dart'; import 'package:petitbac/ui/layouts/game_layout.dart';
import 'package:petitbac/ui/layouts/parameters_layout.dart';
class PageGame extends StatelessWidget { class PageGame extends StatelessWidget {
const PageGame({super.key}); const PageGame({super.key});
...@@ -12,7 +13,12 @@ class PageGame extends StatelessWidget { ...@@ -12,7 +13,12 @@ class PageGame extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>( return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) { builder: (BuildContext context, GameState gameState) {
return gameState.currentGame.isRunning ? const GameWidget() : const Parameters(); 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:petitbac/ui/widgets/helpers/app_header.dart'; import 'package:petitbac/ui/helpers/app_titles.dart';
import 'package:petitbac/ui/widgets/settings/settings_form.dart'; import 'package:petitbac/ui/settings/settings_form.dart';
class PageSettings extends StatelessWidget { class PageSettings extends StatelessWidget {
const PageSettings({super.key}); const PageSettings({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const Column( return const Padding(
padding: EdgeInsets.symmetric(horizontal: 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
AppHeader(text: 'settings_title'), SizedBox(height: 8),
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:petitbac/ui/widgets/settings/theme_card.dart'; import 'package:petitbac/ui/settings/theme_card.dart';
class SettingsForm extends StatefulWidget { class SettingsForm extends StatefulWidget {
const SettingsForm({super.key}); const SettingsForm({super.key});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment