diff --git a/fastlane/metadata/android/en-US/changelogs/10.txt b/fastlane/metadata/android/en-US/changelogs/10.txt new file mode 100644 index 0000000000000000000000000000000000000000..4c47fc4c8c7acbc1585fafff9964e9181d18f750 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/10.txt @@ -0,0 +1 @@ +Add colors themes. diff --git a/fastlane/metadata/android/fr-FR/changelogs/10.txt b/fastlane/metadata/android/fr-FR/changelogs/10.txt new file mode 100644 index 0000000000000000000000000000000000000000..d11be194cfa475fa94c3db92e674a3f4992aec0a --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/10.txt @@ -0,0 +1 @@ +Ajout de thèmes de couleurs. diff --git a/lib/config/application_config.dart b/lib/config/application_config.dart index 5257853f454cebad3d87955b4d50628c7478e3ac..35ce108c17ee3c4782987dbb678f35d9f42a2fb6 100644 --- a/lib/config/application_config.dart +++ b/lib/config/application_config.dart @@ -6,6 +6,7 @@ import 'package:suguru/cubit/activity/activity_cubit.dart'; import 'package:suguru/ui/pages/game.dart'; import 'package:suguru/ui/parameters/parameter_painter_board_size.dart'; +import 'package:suguru/ui/parameters/parameter_painter_color_theme.dart'; import 'package:suguru/ui/parameters/parameter_painter_difficulty_level.dart'; class ApplicationConfig { @@ -25,6 +26,14 @@ class ApplicationConfig { static const String parameterCodeSkin = 'global.skin'; static const String skinValueDigits = 'digits'; + // activity parameter: colors theme values + static const String parameterCodeColorTheme = 'global.colorTheme'; + static const String colorThemeLegacy = 'legacy'; + static const String colorThemeWeb = 'web'; + static const String colorThemeSweethope = 'sweethope'; + static const String colorThemeNostalgicDreams = 'nostalgic-dreams'; + static const String colorThemeArjibi8 = 'arjibi8'; + static const int defaultTipCountDownValueInSeconds = 20; // activity pages @@ -106,6 +115,33 @@ class ApplicationConfig { ), ), ), + + // colors theme + ApplicationSettingsParameter( + code: parameterCodeColorTheme, + displayedOnTop: false, + values: [ + ApplicationSettingsParameterItemValue( + value: colorThemeWeb, + isDefault: true, + ), + ApplicationSettingsParameterItemValue( + value: colorThemeLegacy, + ), + ApplicationSettingsParameterItemValue( + value: colorThemeSweethope, + ), + ApplicationSettingsParameterItemValue( + value: colorThemeNostalgicDreams, + ), + ApplicationSettingsParameterItemValue( + value: colorThemeArjibi8, + ), + ], + customPainter: (context, value) { + return ParameterPainterColorTheme(value: value, context: context); + }, + ), ], startNewActivity: (BuildContext context) { BlocProvider.of<ActivityCubit>(context).startNewActivity(context); diff --git a/lib/config/color_theme.dart b/lib/config/color_theme.dart new file mode 100644 index 0000000000000000000000000000000000000000..335164e24eae6ed88e828ecc5e3aa189c10ff788 --- /dev/null +++ b/lib/config/color_theme.dart @@ -0,0 +1,89 @@ +import 'package:suguru/config/application_config.dart'; + +class ColorTheme { + static const Map<String, List<int>> colorThemes = { + // legacy + ApplicationConfig.colorThemeLegacy: [ + 0x9D9D9D, + 0xFFFFFF, + 0xBE2633, + 0xE06F8B, + 0x493C2B, + 0xA46422, + 0xEB8931, + 0xF7E26B, + 0x2F484E, + 0x44891A, + 0xA3CE27, + 0x1B2632, + 0x005784, + 0x31A2F2, + 0xB2DCEF, + ], + + ApplicationConfig.colorThemeWeb: [ + 0xbe7f51, + 0x50728b, + 0xae706f, + 0x916187, + 0xe18a2b, + 0x88776d, + 0xd4be1e, + 0xba963a, + 0xa29a5c, + ], + + // https://lospec.com/palette-list/sweethope + ApplicationConfig.colorThemeSweethope: [ + 0x615e85, + 0x9c8dc2, + 0xd9a3cd, + 0xebc3a7, + 0xe0e0dc, + 0xa3d1af, + 0x90b4de, + 0x717fb0, + ], + + // https://lospec.com/palette-list/nostalgic-dreams + ApplicationConfig.colorThemeNostalgicDreams: [ + 0xd9af80, + 0xb07972, + 0x524352, + 0x686887, + 0x7f9bb0, + 0xbfd4b0, + 0x90b870, + 0x628c70, + ], + + // https://lospec.com/palette-list/arjibi8 + ApplicationConfig.colorThemeArjibi8: [ + 0x8bc7bf, + 0x5796a1, + 0x524bb3, + 0x471b6e, + 0x702782, + 0xb0455a, + 0xde8b6f, + 0xebd694, + ], + + // https://lospec.com/palette-list/kotomasho-8 + // 5:[0x40263e,0x5979a6,0x84c2a3,0xefe8c3,0xefefef,0xcbc7d6,0xd06060,0x773971,], + + // https://lospec.com/palette-list/desatur8 + // 6:[0xf0f0eb,0xffff8f,0x7be098,0x849ad8,0xe8b382,0xd8828e,0xa776c1,0x545155,], + + // https://lospec.com/palette-list/purplemorning8 + // 7:[0x211d38,0x2e2a4f,0x3b405e,0x60556e,0x9a6278,0xc7786f,0xcfa98a,0xcdd4a5,], + + // https://lospec.com/palette-list/cold-war-8 + // 8:[0x332422,0xc95b40,0xff9b5e,0xfcdf76,0x4c2f7f,0x3a66ad,0x39cec2,0xfafff9,], + + // https://lospec.com/palette-list/low-8 + // 9:[0x111323,0x374566,0x50785d,0x8497b3,0xe8dcd8,0xcfb463,0xb35447,0x692e4b,], + }; + + static const int defaultThemeColor = 0x808080; +} diff --git a/lib/models/activity/activity.dart b/lib/models/activity/activity.dart index dad9137d909461073c3b38ddbabfa004288a5992..05b67799cb64b32bd9f1bc288eba0f54cc915f60 100644 --- a/lib/models/activity/activity.dart +++ b/lib/models/activity/activity.dart @@ -138,8 +138,6 @@ class Activity { } void updateConflictsInBoard() { - final BoardCells cells = board.cells; - // reset conflict states for (CellLocation location in board.getCellLocations()) { boardConflicts[location.row][location.col] = 0; diff --git a/lib/models/activity/board.dart b/lib/models/activity/board.dart index 532d297dc79d846f6754b20879a59018b5ecfc27..9a7bc578cd51dc2d2ab94c9231e1b5c06ea29849 100644 --- a/lib/models/activity/board.dart +++ b/lib/models/activity/board.dart @@ -104,10 +104,6 @@ class Board { final Board solvedBoard = SuguruSolver.resolve(this); solvedCells = solvedBoard.cells; - - // FIXME: for debug only - // to start with a board (almost) automatically solved - // cells = solvedCells; } int get boardSizeVertical => cells.length; diff --git a/lib/ui/pages/game.dart b/lib/ui/pages/game.dart index 40ec1fe78b48e0825d90ca2ad3432eadd89ed83e..e5923741d7b97df1d7ad59937dabe6d6dd5a1a47 100644 --- a/lib/ui/pages/game.dart +++ b/lib/ui/pages/game.dart @@ -29,11 +29,6 @@ class PageGame extends StatelessWidget { const GameBoardWidget(), const SizedBox(height: 8), const GameBottomWidget(), - // StyledButton.text( - // onPressed: () => SuguruSolver.checkAllTemplates(), - // caption: '[debug] test all templates', - // color: Colors.red, - // ), const Expanded(child: SizedBox.shrink()), currentActivity.isFinished ? const GameEndWidget() : const SizedBox.shrink(), ], diff --git a/lib/ui/parameters/parameter_painter_color_theme.dart b/lib/ui/parameters/parameter_painter_color_theme.dart new file mode 100644 index 0000000000000000000000000000000000000000..f0992df5e56ae47d54db2d74346b2d5b986270ea --- /dev/null +++ b/lib/ui/parameters/parameter_painter_color_theme.dart @@ -0,0 +1,55 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import 'package:suguru/utils/color_theme_utils.dart'; + +class ParameterPainterColorTheme extends CustomPainter { + const ParameterPainterColorTheme({ + required this.context, + required this.value, + }); + + final BuildContext context; + final String value; + + @override + void paint(Canvas canvas, Size size) { + // force square + final double canvasSize = min(size.width, size.height); + + const int gridWidth = 4; + + final paint = Paint(); + paint.strokeJoin = StrokeJoin.round; + paint.strokeWidth = 3 / 100 * canvasSize; + + // Mini grid + final borderColor = Colors.grey.shade800; + + final double cellSize = canvasSize / gridWidth; + final double origin = (canvasSize - gridWidth * cellSize) / 2; + + for (int row = 0; row < gridWidth; row++) { + for (int col = 0; col < gridWidth; col++) { + final Offset topLeft = Offset(origin + col * cellSize, origin + row * cellSize); + final Offset bottomRight = topLeft + Offset(cellSize, cellSize); + + final squareColor = Color(ColorThemeUtils.getColorCode(col + row * gridWidth, value)); + + paint.color = squareColor; + paint.style = PaintingStyle.fill; + canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint); + + paint.color = borderColor; + paint.style = PaintingStyle.stroke; + canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint); + } + } + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) { + return false; + } +} diff --git a/lib/ui/widgets/game/cell.dart b/lib/ui/widgets/game/cell.dart index 08385db862b7f9c526b51e88d06547080ac1e550..d4670a4c305dc0f1e724f09525cf7991c2f6c91e 100644 --- a/lib/ui/widgets/game/cell.dart +++ b/lib/ui/widgets/game/cell.dart @@ -6,11 +6,13 @@ import 'package:suguru/config/application_config.dart'; import 'package:suguru/cubit/activity/activity_cubit.dart'; import 'package:suguru/models/activity/cell.dart'; import 'package:suguru/models/activity/activity.dart'; +import 'package:suguru/utils/color_theme_utils.dart'; class CellWidget extends StatelessWidget { const CellWidget({ super.key, required this.cell, + required this.theme, required this.hasBlockBorderTop, required this.hasBlockBorderLeft, required this.hasBlockBorderBottom, @@ -18,6 +20,7 @@ class CellWidget extends StatelessWidget { }); final Cell cell; + final String theme; final bool hasBlockBorderTop; final bool hasBlockBorderLeft; final bool hasBlockBorderBottom; @@ -76,20 +79,8 @@ class CellWidget extends StatelessWidget { } Color getBaseColorFromBlockId(String blockId) { - const List<Color> paletteColors = [ - Color.fromRGBO(0xbe, 0x7f, 0x51, 1), - Color.fromRGBO(0x50, 0x72, 0x8b, 1), - Color.fromRGBO(0xae, 0x70, 0x6f, 1), - Color.fromRGBO(0x91, 0x61, 0x87, 1), - Color.fromRGBO(0xe1, 0x8a, 0x2b, 1), - Color.fromRGBO(0x88, 0x77, 0x6d, 1), - Color.fromRGBO(0xd4, 0xbe, 0x1e, 1), - Color.fromRGBO(0xba, 0x96, 0x3a, 1), - Color.fromRGBO(0xa2, 0x9a, 0x5c, 1), - ]; - final int blockIdValue = blockId.codeUnits.first - 'A'.codeUnits.first; - return paletteColors[blockIdValue % paletteColors.length].lighten(20); + return ColorThemeUtils.getColor(blockIdValue, theme).lighten(20); } // Compute cell background color, from cell state diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart index 50bed58b7220dcb4c21a9203598d24d08b5e8ae2..7556b29a00be88a7f6dd0a91f2083b5339fd0e56 100644 --- a/lib/ui/widgets/game/game_board.dart +++ b/lib/ui/widgets/game/game_board.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart'; +import 'package:suguru/config/application_config.dart'; import 'package:suguru/cubit/activity/activity_cubit.dart'; import 'package:suguru/models/activity/cell_location.dart'; import 'package:suguru/models/activity/activity.dart'; @@ -21,6 +22,9 @@ class GameBoardWidget extends StatelessWidget { final double width = size.width; final double height = size.height; + final String theme = + currentActivity.activitySettings.get(ApplicationConfig.parameterCodeColorTheme); + final Container board = Container( margin: const EdgeInsets.all(2), padding: const EdgeInsets.all(2), @@ -47,6 +51,7 @@ class GameBoardWidget extends StatelessWidget { children: [ CellWidget( cell: currentActivity.board.get(CellLocation.go(row, col)), + theme: theme, hasBlockBorderBottom: currentActivity.board .get(CellLocation.go(row, col)) .blockId != diff --git a/lib/utils/color_theme_utils.dart b/lib/utils/color_theme_utils.dart new file mode 100644 index 0000000000000000000000000000000000000000..e46f8da5ef49bf2100bd3481dccd7f5c79be8917 --- /dev/null +++ b/lib/utils/color_theme_utils.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +import 'package:suguru/config/color_theme.dart'; + +class ColorThemeUtils { + static int getColorsCount(String colorTheme) { + if (ColorTheme.colorThemes.containsKey(colorTheme) && + null != ColorTheme.colorThemes[colorTheme]) { + List<int> colors = ColorTheme.colorThemes[colorTheme] ?? []; + + return colors.length; + } + + return 0; + } + + static int getColorCode(int? value, String colorTheme) { + if (value != null && + ColorTheme.colorThemes.containsKey(colorTheme) && + null != ColorTheme.colorThemes[colorTheme]) { + List<int> skinColors = ColorTheme.colorThemes[colorTheme] ?? []; + return (skinColors[value % getColorsCount(colorTheme)]) | 0xFF000000; + } + return ColorTheme.defaultThemeColor | 0xFF000000; + } + + static Color getColor(int? value, String colorTheme) { + return Color(getColorCode(value, colorTheme)); + } + + static Color getDefaultBorderColor() { + return Colors.grey; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 00de7a94e06cb198aee9db577798aabcc9cf1623..80d76fd9eb0cca3688c1a5ad137153c0483321d5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A suguru game application. publish_to: "none" -version: 0.1.0+9 +version: 0.1.1+10 environment: sdk: "^3.0.0"