From e2a96f94a02f07d2210aa52d025838defe3c782c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr> Date: Mon, 17 Feb 2025 16:30:56 +0100 Subject: [PATCH] Add colors themes --- .../metadata/android/en-US/changelogs/10.txt | 1 + .../metadata/android/fr-FR/changelogs/10.txt | 1 + lib/config/application_config.dart | 36 ++++++++ lib/config/color_theme.dart | 89 +++++++++++++++++++ lib/models/activity/activity.dart | 2 - lib/models/activity/board.dart | 4 - lib/ui/pages/game.dart | 5 -- .../parameter_painter_color_theme.dart | 55 ++++++++++++ lib/ui/widgets/game/cell.dart | 17 +--- lib/ui/widgets/game/game_board.dart | 5 ++ lib/utils/color_theme_utils.dart | 34 +++++++ pubspec.yaml | 2 +- 12 files changed, 226 insertions(+), 25 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/10.txt create mode 100644 fastlane/metadata/android/fr-FR/changelogs/10.txt create mode 100644 lib/config/color_theme.dart create mode 100644 lib/ui/parameters/parameter_painter_color_theme.dart create mode 100644 lib/utils/color_theme_utils.dart 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 0000000..4c47fc4 --- /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 0000000..d11be19 --- /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 5257853..35ce108 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 0000000..335164e --- /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 dad9137..05b6779 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 532d297..9a7bc57 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 40ec1fe..e592374 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 0000000..f0992df --- /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 08385db..d4670a4 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 50bed58..7556b29 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 0000000..e46f8da --- /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 00de7a9..80d76fd 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" -- GitLab