From 5f67bdb14883845ed8838097325f2741e8bf6e34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Fri, 15 Nov 2024 15:33:48 +0100
Subject: [PATCH] Use ActivityParameters widgets from flutter_custom_toolbox

---
 .../metadata/android/en-US/changelogs/41.txt  |   1 +
 .../metadata/android/fr-FR/changelogs/41.txt  |   1 +
 lib/common/config/activity_page.dart          |  39 +-
 lib/common/ui/pages/parameters.dart           | 171 ---------
 .../ui/parameters/parameter_painter.dart      | 348 ------------------
 .../ui/parameters/parameter_widget.dart       | 195 ----------
 lib/common/utils/color_theme_utils.dart       |  34 ++
 lib/config/application_config.dart            | 183 ++++++++-
 lib/config/color_theme.dart                   |  42 +--
 lib/config/default_activity_settings.dart     |  54 ---
 lib/config/default_global_settings.dart       |  70 ----
 lib/cubit/activity/activity_cubit.dart        |  33 +-
 .../settings/settings_activity_cubit.dart     |  73 ----
 .../settings/settings_activity_state.dart     |  15 -
 lib/cubit/settings/settings_global_cubit.dart |  71 ----
 lib/cubit/settings/settings_global_state.dart |  15 -
 lib/main.dart                                 |   9 +-
 lib/models/activity/activity.dart             |  68 ++--
 lib/models/activity/board.dart                |  10 +-
 lib/models/settings/settings_activity.dart    |  59 ---
 lib/models/settings/settings_global.dart      |  55 ---
 lib/{common/ui/nav => ui}/global_app_bar.dart |   0
 lib/{common => }/ui/pages/game.dart           |   0
 lib/ui/painters/game_board_painter.dart       |  36 +-
 .../parameter_painter_board_size.dart         |  80 ++++
 .../parameter_painter_color_theme.dart        |  55 +++
 .../parameter_painter_colors_count.dart       |  96 +++++
 .../parameter_painter_graphic_theme.dart      | 133 +++++++
 lib/ui/skeleton.dart                          |   2 +-
 lib/ui/widgets/game/board.dart                |  23 +-
 .../indicators/indicator_shuffle_button.dart  |   5 +-
 pubspec.lock                                  |   6 +-
 pubspec.yaml                                  |   4 +-
 33 files changed, 724 insertions(+), 1262 deletions(-)
 create mode 100644 fastlane/metadata/android/en-US/changelogs/41.txt
 create mode 100644 fastlane/metadata/android/fr-FR/changelogs/41.txt
 delete mode 100644 lib/common/ui/pages/parameters.dart
 delete mode 100644 lib/common/ui/parameters/parameter_painter.dart
 delete mode 100644 lib/common/ui/parameters/parameter_widget.dart
 create mode 100644 lib/common/utils/color_theme_utils.dart
 delete mode 100644 lib/config/default_activity_settings.dart
 delete mode 100644 lib/config/default_global_settings.dart
 delete mode 100644 lib/cubit/settings/settings_activity_cubit.dart
 delete mode 100644 lib/cubit/settings/settings_activity_state.dart
 delete mode 100644 lib/cubit/settings/settings_global_cubit.dart
 delete mode 100644 lib/cubit/settings/settings_global_state.dart
 delete mode 100644 lib/models/settings/settings_activity.dart
 delete mode 100644 lib/models/settings/settings_global.dart
 rename lib/{common/ui/nav => ui}/global_app_bar.dart (100%)
 rename lib/{common => }/ui/pages/game.dart (100%)
 create mode 100644 lib/ui/parameters/parameter_painter_board_size.dart
 create mode 100644 lib/ui/parameters/parameter_painter_color_theme.dart
 create mode 100644 lib/ui/parameters/parameter_painter_colors_count.dart
 create mode 100644 lib/ui/parameters/parameter_painter_graphic_theme.dart

diff --git a/fastlane/metadata/android/en-US/changelogs/41.txt b/fastlane/metadata/android/en-US/changelogs/41.txt
new file mode 100644
index 0000000..c20ed39
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/41.txt
@@ -0,0 +1 @@
+Use ActivityParameters widgets from flutter_custom_toolbox.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/41.txt b/fastlane/metadata/android/fr-FR/changelogs/41.txt
new file mode 100644
index 0000000..f732ebd
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/41.txt
@@ -0,0 +1 @@
+Utilisation des widgets ActivityParameters de flutter_custom_toolbox.
diff --git a/lib/common/config/activity_page.dart b/lib/common/config/activity_page.dart
index ecf719a..43a95dc 100644
--- a/lib/common/config/activity_page.dart
+++ b/lib/common/config/activity_page.dart
@@ -1,18 +1,20 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:jeweled/common/ui/pages/game.dart';
-import 'package:jeweled/common/ui/pages/parameters.dart';
+import 'package:jeweled/cubit/activity/activity_cubit.dart';
+import 'package:jeweled/config/application_config.dart';
+import 'package:jeweled/models/activity/activity.dart';
+import 'package:jeweled/ui/pages/game.dart';
 
 class ActivityPageItem {
   final String code;
   final Icon icon;
-  final Widget page;
+  final Widget Function({required Activity currentActivity})? builder;
 
   const ActivityPageItem({
     required this.code,
     required this.icon,
-    required this.page,
+    required this.builder,
   });
 }
 
@@ -20,20 +22,27 @@ class ActivityPage {
   static const bool displayBottomNavBar = false;
 
   static const indexHome = 0;
-  static const pageHome = ActivityPageItem(
+  static final ActivityPageItem pageHome = ActivityPageItem(
     code: 'page_home',
     icon: Icon(UniconsLine.home),
-    page: PageParameters(),
+    builder: ({required Activity currentActivity}) {
+      return PageParameters(
+        config: ApplicationConfig.config,
+        canBeResumed: currentActivity.canBeResumed,
+      );
+    },
   );
 
   static const indexGame = 1;
-  static const pageGame = ActivityPageItem(
+  static final pageGame = ActivityPageItem(
     code: 'page_game',
     icon: Icon(UniconsLine.star),
-    page: PageGame(),
+    builder: ({required Activity currentActivity}) {
+      return PageGame();
+    },
   );
 
-  static const Map<int, ActivityPageItem> items = {
+  static final Map<int, ActivityPageItem> items = {
     indexHome: pageHome,
     indexGame: pageGame,
   };
@@ -45,6 +54,16 @@ class ActivityPage {
   }
 
   static Widget getWidget(int pageIndex) {
-    return items[pageIndex]?.page ?? pageHome.page;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
+
+        if (items.keys.contains(pageIndex)) {
+          return items[pageIndex]?.builder!(currentActivity: currentActivity) ?? Text('oups');
+        } else {
+          return getWidget(defaultPageIndex);
+        }
+      },
+    );
   }
 }
diff --git a/lib/common/ui/pages/parameters.dart b/lib/common/ui/pages/parameters.dart
deleted file mode 100644
index 35e7c8f..0000000
--- a/lib/common/ui/pages/parameters.dart
+++ /dev/null
@@ -1,171 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:jeweled/common/cubit/nav/nav_cubit_pages.dart';
-import 'package:jeweled/common/ui/parameters/parameter_widget.dart';
-
-import 'package:jeweled/config/default_activity_settings.dart';
-import 'package:jeweled/config/default_global_settings.dart';
-import 'package:jeweled/cubit/activity/activity_cubit.dart';
-import 'package:jeweled/cubit/settings/settings_activity_cubit.dart';
-import 'package:jeweled/cubit/settings/settings_global_cubit.dart';
-import 'package:jeweled/models/activity/activity.dart';
-
-class PageParameters extends StatelessWidget {
-  const PageParameters({super.key});
-
-  final double separatorHeight = 8.0;
-
-  @override
-  Widget build(BuildContext context) {
-    return BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
-      builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
-        return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
-          builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
-            return BlocBuilder<ActivityCubit, ActivityState>(
-              builder: (BuildContext context, ActivityState activityState) {
-                final Activity currentActivity = activityState.currentActivity;
-
-                final List<Widget> lines = [];
-
-                // Activity settings
-                for (String code in DefaultActivitySettings.availableParameters) {
-                  lines.add(Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: buildParametersLine(
-                      code: code,
-                      isGlobal: false,
-                    ),
-                  ));
-
-                  lines.add(SizedBox(height: separatorHeight));
-                }
-
-                lines.add(Expanded(
-                  child: SizedBox(height: separatorHeight),
-                ));
-
-                if (currentActivity.canBeResumed == false) {
-                  // Start new activity
-                  lines.add(
-                    AspectRatio(
-                      aspectRatio: 3,
-                      child: ActivityButtonStartNew(
-                        onPressed: () {
-                          BlocProvider.of<ActivityCubit>(context).startNewActivity(
-                            activitySettings: activitySettingsState.settings,
-                            globalSettings: globalSettingsState.settings,
-                          );
-                          BlocProvider.of<NavCubitPage>(context).goToPageGame();
-                        },
-                      ),
-                    ),
-                  );
-                } else {
-                  // Resume activity
-                  lines.add(AspectRatio(
-                    aspectRatio: 3,
-                    child: ActivityButtonResumeSaved(
-                      onPressed: () {
-                        BlocProvider.of<ActivityCubit>(context).resumeSavedActivity();
-                        BlocProvider.of<NavCubitPage>(context).goToPageGame();
-                      },
-                    ),
-                  ));
-                  // Delete saved activity
-                  lines.add(SizedBox.square(
-                    dimension: MediaQuery.of(context).size.width / 5,
-                    child: ActivityButtonDeleteSaved(
-                      onPressed: () {
-                        BlocProvider.of<ActivityCubit>(context).deleteSavedActivity();
-                      },
-                    ),
-                  ));
-                }
-
-                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)
-        : DefaultActivitySettings.getAvailableValues(code);
-
-    if (availableValues.length <= 1) {
-      return [];
-    }
-
-    for (String value in availableValues) {
-      final Widget parameterButton = BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
-        builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
-          return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
-            builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
-              final ActivitySettingsCubit activitySettingsCubit =
-                  BlocProvider.of<ActivitySettingsCubit>(context);
-              final GlobalSettingsCubit globalSettingsCubit =
-                  BlocProvider.of<GlobalSettingsCubit>(context);
-
-              final String currentValue = isGlobal
-                  ? globalSettingsCubit.getParameterValue(code)
-                  : activitySettingsCubit.getParameterValue(code);
-
-              final bool isSelected = (value == currentValue);
-
-              final double displayWidth = MediaQuery.of(context).size.width;
-              final double itemWidth = displayWidth / availableValues.length - 4;
-
-              return SizedBox.square(
-                dimension: itemWidth,
-                child: ParameterWidget(
-                  code: code,
-                  value: value,
-                  isSelected: isSelected,
-                  size: itemWidth,
-                  activitySettings: activitySettingsState.settings,
-                  globalSettings: globalSettingsState.settings,
-                  onPressed: () {
-                    isGlobal
-                        ? globalSettingsCubit.setParameterValue(code, value)
-                        : activitySettingsCubit.setParameterValue(code, value);
-                  },
-                ),
-              );
-            },
-          );
-        },
-      );
-
-      parameterButtons.add(parameterButton);
-    }
-
-    return parameterButtons;
-  }
-}
diff --git a/lib/common/ui/parameters/parameter_painter.dart b/lib/common/ui/parameters/parameter_painter.dart
deleted file mode 100644
index bd83f24..0000000
--- a/lib/common/ui/parameters/parameter_painter.dart
+++ /dev/null
@@ -1,348 +0,0 @@
-import 'dart:math';
-import 'dart:ui' as ui;
-
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:jeweled/config/color_theme.dart';
-import 'package:jeweled/config/default_activity_settings.dart';
-import 'package:jeweled/config/default_global_settings.dart';
-import 'package:jeweled/models/settings/settings_activity.dart';
-import 'package:jeweled/models/settings/settings_global.dart';
-
-class ParameterPainter extends CustomPainter {
-  const ParameterPainter({
-    required this.code,
-    required this.value,
-    required this.activitySettings,
-    required this.globalSettings,
-  });
-
-  final String code;
-  final String value;
-  final ActivitySettings activitySettings;
-  final GlobalSettings globalSettings;
-
-  @override
-  void paint(Canvas canvas, Size size) {
-    // force square
-    final double canvasSize = min(size.width, size.height);
-
-    // content
-    switch (code) {
-      case DefaultActivitySettings.parameterCodeColorsCount:
-        paintColorsCountParameterItem(canvas, canvasSize);
-        break;
-      case DefaultActivitySettings.parameterCodeBoardSize:
-        paintBoardSizeParameterItem(canvas, canvasSize);
-        break;
-      case DefaultGlobalSettings.parameterCodeColorsTheme:
-        paintColorsThemeParameterItem(canvas, canvasSize);
-        break;
-      case DefaultGlobalSettings.parameterCodeGraphicsTheme:
-        paintGraphicThemeParameterItem(canvas, canvasSize);
-        break;
-      default:
-        printlog('Unknown parameter: $code/$value');
-        paintUnknownParameterItem(canvas, canvasSize);
-    }
-  }
-
-  @override
-  bool shouldRepaint(CustomPainter oldDelegate) {
-    return false;
-  }
-
-  // "unknown" parameter -> simple block with text
-  void paintUnknownParameterItem(
-    final Canvas canvas,
-    final double size,
-  ) {
-    final paint = Paint();
-    paint.strokeJoin = StrokeJoin.round;
-    paint.strokeWidth = 3;
-
-    final textSpan = TextSpan(
-      text: '$code\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 paintBoardSizeParameterItem(
-    final Canvas canvas,
-    final double size,
-  ) {
-    int gridWidth = 1;
-
-    switch (value) {
-      case DefaultActivitySettings.boardSizeValueSmall:
-        gridWidth = 2;
-        break;
-      case DefaultActivitySettings.boardSizeValueMedium:
-        gridWidth = 3;
-        break;
-      case DefaultActivitySettings.boardSizeValueLarge:
-        gridWidth = 4;
-        break;
-      case DefaultActivitySettings.boardSizeValueExtraLarge:
-        gridWidth = 5;
-        break;
-      default:
-        printlog('Wrong value for boardSize parameter value: $value');
-    }
-
-    final paint = Paint();
-    paint.strokeJoin = StrokeJoin.round;
-    paint.strokeWidth = 3 / 100 * size;
-
-    // Mini grid
-    final borderColor = Colors.grey.shade800;
-
-    final double cellSize = size / 7;
-    final double origin = (size - 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(ColorTheme.getColorCode(col + row * gridWidth, globalSettings.colorsTheme));
-
-        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);
-      }
-    }
-  }
-
-  void paintColorsCountParameterItem(
-    final Canvas canvas,
-    final double size,
-  ) {
-    final paint = Paint();
-    paint.strokeJoin = StrokeJoin.round;
-    paint.strokeWidth = 3;
-
-    // Colors preview
-    const List<Offset> positions = [
-      Offset(0, 0),
-      Offset(1, 0),
-      Offset(2, 0),
-      Offset(2, 1),
-      Offset(2, 2),
-      Offset(1, 2),
-      Offset(0, 2),
-      Offset(0, 1),
-    ];
-
-    final double padding = 4 / 100 * size;
-    final double margin = 3 / 100 * size;
-    final double width = ((size - 2 * padding) / 3) - 2 * margin;
-
-    final colorsCount = int.parse(value);
-
-    for (int colorIndex = 0; colorIndex < colorsCount; colorIndex++) {
-      final Offset position = positions[colorIndex];
-
-      final Offset topLeft = Offset(padding + margin + position.dx * (width + 2 * margin),
-          padding + margin + position.dy * (width + 2 * margin));
-
-      final Offset bottomRight = topLeft + Offset(width, width);
-
-      final squareColor =
-          Color(ColorTheme.getColorCode(colorIndex, globalSettings.colorsTheme));
-      paint.color = squareColor;
-      paint.style = PaintingStyle.fill;
-      canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
-
-      final borderColor = squareColor.darken(20);
-      paint.color = borderColor;
-      paint.style = PaintingStyle.stroke;
-      canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
-    }
-
-    // centered text value
-    final textSpan = TextSpan(
-      text: value.toString(),
-      style: TextStyle(
-        color: Colors.black,
-        fontSize: size / 4,
-        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 paintColorsThemeParameterItem(
-    final Canvas canvas,
-    final double size,
-  ) {
-    const int gridWidth = 4;
-
-    final paint = Paint();
-    paint.strokeJoin = StrokeJoin.round;
-    paint.strokeWidth = 3 / 100 * size;
-
-    // Mini grid
-    final borderColor = Colors.grey.shade800;
-
-    final double cellSize = size / gridWidth;
-    final double origin = (size - 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(ColorTheme.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);
-      }
-    }
-  }
-
-  void paintGraphicThemeParameterItem(
-    final Canvas canvas,
-    final double size,
-  ) {
-    final paint = Paint();
-    paint.strokeJoin = StrokeJoin.round;
-    paint.strokeWidth = 3;
-
-    // cells preview
-    const List<Offset> positions = [
-      Offset(0, 0),
-      Offset(1, 0),
-      Offset(2, 0),
-      Offset(2, 1),
-      Offset(2, 2),
-      Offset(1, 2),
-      Offset(0, 2),
-      Offset(0, 1),
-    ];
-
-    final double padding = 5 / 100 * size;
-    final double width = (size - 2 * padding) / 3;
-
-    bool drawBorder = false;
-    bool gradientColor = false;
-    List<String> contentStrings = [];
-
-    switch (value) {
-      case DefaultGlobalSettings.graphicThemeSolidBackground:
-        break;
-      case DefaultGlobalSettings.graphicThemeGradientAndBorder:
-        drawBorder = true;
-        gradientColor = true;
-        break;
-      case DefaultGlobalSettings.graphicThemeEmojis:
-        contentStrings = DefaultGlobalSettings.graphicThemeContentEmojiStrings;
-        break;
-      case DefaultGlobalSettings.graphicThemePatterns:
-        contentStrings = DefaultGlobalSettings.graphicThemeContentPatternStrings;
-        break;
-      default:
-        printlog('Wrong value for colorsCount parameter value: $value');
-    }
-
-    for (int itemValue = 0; itemValue < positions.length; itemValue++) {
-      final Offset position = positions[itemValue];
-
-      final Offset topLeft =
-          Offset(padding + position.dx * width, padding + position.dy * width);
-      final Offset bottomRight = topLeft + Offset(width, width);
-
-      final Rect itemBox = Rect.fromPoints(topLeft, bottomRight);
-      final itemColor = ColorTheme.getColor(itemValue, globalSettings.colorsTheme);
-
-      paint.color = itemColor;
-      paint.style = PaintingStyle.fill;
-      canvas.drawRect(itemBox, paint);
-
-      // gradient background
-      if (gradientColor) {
-        paint.shader = ui.Gradient.linear(itemBox.topLeft, itemBox.bottomCenter, [
-          itemColor.lighten(10),
-          itemColor.darken(10),
-        ]);
-        paint.style = PaintingStyle.fill;
-        canvas.drawRect(itemBox, paint);
-      }
-
-      // cell border
-      if (drawBorder) {
-        final paintBorder = Paint();
-        paintBorder.color = itemColor.darken(20);
-        paintBorder.style = PaintingStyle.stroke;
-        paintBorder.strokeWidth = 2;
-
-        canvas.drawRect(itemBox, paintBorder);
-      }
-
-      // centered text value
-      if (contentStrings.isNotEmpty) {
-        final textSpan = TextSpan(
-          text: contentStrings[itemValue],
-          style: TextStyle(
-            color: Colors.black,
-            fontSize: width / 2,
-            fontWeight: FontWeight.bold,
-          ),
-        );
-        final textPainter = TextPainter(
-          text: textSpan,
-          textDirection: TextDirection.ltr,
-          textAlign: TextAlign.center,
-        );
-        textPainter.layout();
-        textPainter.paint(
-          canvas,
-          Offset(
-            topLeft.dx + (width - textPainter.width) * 0.5,
-            topLeft.dy + (width - textPainter.height) * 0.5,
-          ),
-        );
-      }
-    }
-  }
-}
diff --git a/lib/common/ui/parameters/parameter_widget.dart b/lib/common/ui/parameters/parameter_widget.dart
deleted file mode 100644
index ed48652..0000000
--- a/lib/common/ui/parameters/parameter_widget.dart
+++ /dev/null
@@ -1,195 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:jeweled/common/ui/parameters/parameter_painter.dart';
-
-import 'package:jeweled/config/default_activity_settings.dart';
-import 'package:jeweled/config/default_global_settings.dart';
-import 'package:jeweled/models/settings/settings_activity.dart';
-import 'package:jeweled/models/settings/settings_global.dart';
-
-class ParameterWidget extends StatelessWidget {
-  const ParameterWidget({
-    super.key,
-    required this.code,
-    required this.value,
-    required this.isSelected,
-    required this.size,
-    required this.activitySettings,
-    required this.globalSettings,
-    required this.onPressed,
-  });
-
-  final String code;
-  final String value;
-  final bool isSelected;
-  final double size;
-  final ActivitySettings activitySettings;
-  final GlobalSettings globalSettings;
-  final VoidCallback onPressed;
-
-  static const Color buttonColorActive = Colors.blue;
-  static const Color buttonColorInactive = Colors.white;
-  static const double buttonBorderWidth = 4.0;
-  static const double buttonBorderRadius = 12.0;
-
-  @override
-  Widget build(BuildContext context) {
-    Widget content = const SizedBox.shrink();
-
-    switch (code) {
-      case DefaultActivitySettings.parameterCodeColorsCount:
-        content = getColorsCountParameterItem();
-        break;
-      case DefaultActivitySettings.parameterCodeBoardSize:
-        content = getBoardSizeParameterItem();
-        break;
-      case DefaultGlobalSettings.parameterCodeColorsTheme:
-        content = getColorsThemeParameterItem();
-        break;
-      case DefaultGlobalSettings.parameterCodeGraphicsTheme:
-        content = getGraphicsThemeParameterItem();
-        break;
-      default:
-        printlog('Unknown parameter: $code/$value');
-        content = getUnknownParameterItem();
-    }
-
-    final Color buttonColor = isSelected ? buttonColorActive : buttonColorInactive;
-
-    return Container(
-      decoration: BoxDecoration(
-        color: buttonColor,
-        borderRadius: BorderRadius.circular(buttonBorderRadius),
-        border: Border.all(
-          color: buttonColor,
-          width: buttonBorderWidth,
-        ),
-      ),
-      child: content,
-    );
-  }
-
-  // "unknown" parameter -> simple block with text
-  Widget getUnknownParameterItem() {
-    return StyledButton.text(
-      caption: '$code / $value',
-      color: Colors.grey,
-      onPressed: null,
-    );
-  }
-
-  Widget getColorsCountParameterItem() {
-    Color backgroundColor = Colors.grey;
-
-    switch (value) {
-      case DefaultActivitySettings.colorsCountValueLow:
-        backgroundColor = Colors.green;
-        break;
-      case DefaultActivitySettings.colorsCountValueMedium:
-        backgroundColor = Colors.orange;
-        break;
-      case DefaultActivitySettings.colorsCountValueHigh:
-        backgroundColor = Colors.red;
-        break;
-      case DefaultActivitySettings.colorsCountValueVeryHigh:
-        backgroundColor = Colors.purple;
-        break;
-      default:
-        printlog('Wrong value for colorsCount parameter value: $value');
-    }
-
-    return StyledButton(
-      color: backgroundColor,
-      onPressed: onPressed,
-      child: CustomPaint(
-        size: Size(size, size),
-        willChange: false,
-        painter: ParameterPainter(
-          code: code,
-          value: value,
-          activitySettings: activitySettings,
-          globalSettings: globalSettings,
-        ),
-        isComplex: true,
-      ),
-    );
-  }
-
-  Widget getBoardSizeParameterItem() {
-    Color backgroundColor = Colors.grey;
-
-    switch (value) {
-      case DefaultActivitySettings.boardSizeValueSmall:
-        backgroundColor = Colors.green;
-        break;
-      case DefaultActivitySettings.boardSizeValueMedium:
-        backgroundColor = Colors.orange;
-        break;
-      case DefaultActivitySettings.boardSizeValueLarge:
-        backgroundColor = Colors.red;
-        break;
-      case DefaultActivitySettings.boardSizeValueExtraLarge:
-        backgroundColor = Colors.purple;
-        break;
-      default:
-        printlog('Wrong value for boardSize parameter value: $value');
-    }
-
-    return StyledButton(
-      color: backgroundColor,
-      onPressed: onPressed,
-      child: CustomPaint(
-        size: Size(size, size),
-        willChange: false,
-        painter: ParameterPainter(
-          code: code,
-          value: value,
-          activitySettings: activitySettings,
-          globalSettings: globalSettings,
-        ),
-        isComplex: true,
-      ),
-    );
-  }
-
-  Widget getColorsThemeParameterItem() {
-    Color backgroundColor = Colors.grey;
-
-    return StyledButton(
-      color: backgroundColor,
-      onPressed: onPressed,
-      child: CustomPaint(
-        size: Size(size, size),
-        willChange: false,
-        painter: ParameterPainter(
-          code: code,
-          value: value,
-          activitySettings: activitySettings,
-          globalSettings: globalSettings,
-        ),
-        isComplex: true,
-      ),
-    );
-  }
-
-  Widget getGraphicsThemeParameterItem() {
-    Color backgroundColor = Colors.grey;
-
-    return StyledButton(
-      color: backgroundColor,
-      onPressed: onPressed,
-      child: CustomPaint(
-        size: Size(size, size),
-        willChange: false,
-        painter: ParameterPainter(
-          code: code,
-          value: value,
-          activitySettings: activitySettings,
-          globalSettings: globalSettings,
-        ),
-        isComplex: true,
-      ),
-    );
-  }
-}
diff --git a/lib/common/utils/color_theme_utils.dart b/lib/common/utils/color_theme_utils.dart
new file mode 100644
index 0000000..6c25c9f
--- /dev/null
+++ b/lib/common/utils/color_theme_utils.dart
@@ -0,0 +1,34 @@
+import 'package:flutter/material.dart';
+
+import 'package:jeweled/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/lib/config/application_config.dart b/lib/config/application_config.dart
index 8c9cd93..a945ec4 100644
--- a/lib/config/application_config.dart
+++ b/lib/config/application_config.dart
@@ -1,3 +1,184 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:jeweled/common/cubit/nav/nav_cubit_pages.dart';
+
+import 'package:jeweled/cubit/activity/activity_cubit.dart';
+
+import 'package:jeweled/ui/parameters/parameter_painter_board_size.dart';
+import 'package:jeweled/ui/parameters/parameter_painter_colors_count.dart';
+import 'package:jeweled/ui/parameters/parameter_painter_color_theme.dart';
+import 'package:jeweled/ui/parameters/parameter_painter_graphic_theme.dart';
+
 class ApplicationConfig {
-  static const String appTitle = 'Jeweled';
+  // known parameters
+  static const String parameterCodeColorTheme = 'global.colorTheme';
+  static const String parameterCodeGraphicsTheme = 'global.graphicTheme';
+  static const String parameterCodeBoardSize = 'activity.boardSize';
+  static const String parameterCodeColorsCount = 'activity.colorsCount';
+
+  // colors theme values
+  static const String colorThemeGothicBit = 'gothic-bit';
+  static const String colorThemeSweethope = 'sweethope';
+  static const String colorThemeNostalgicDreams = 'nostalgic-dreams';
+  static const String colorThemeArjibi8 = 'arjibi8';
+
+  // graphic theme values
+  static const String graphicThemeSolidBackground = 'SolidBackground';
+  static const String graphicThemeGradientAndBorder = 'GradientAndBorder';
+  static const String graphicThemeEmojis = 'Emojis';
+  static const String graphicThemePatterns = 'Patterns';
+
+  // board size values
+  static const String boardSizeValueSmall = '6';
+  static const String boardSizeValueMedium = '10';
+  static const String boardSizeValueLarge = '14';
+  static const String boardSizeValueExtraLarge = '18';
+
+  // colors count values
+  static const String colorsCountValueLow = '5';
+  static const String colorsCountValueMedium = '6';
+  static const String colorsCountValueHigh = '7';
+  static const String colorsCountValueVeryHigh = '8';
+
+  static int blockMinimumCellsCount = 3;
+
+  static final ApplicationConfigDefinition config = ApplicationConfigDefinition(
+    appTitle: 'Jeweled',
+    activitySettings: [
+      // board size
+      ApplicationSettingsParameter(
+        code: parameterCodeBoardSize,
+        values: [
+          ApplicationSettingsParameterItemValue(
+            value: boardSizeValueSmall,
+            color: Colors.green,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: boardSizeValueMedium,
+            color: Colors.orange,
+            isDefault: true,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: boardSizeValueLarge,
+            color: Colors.red,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: boardSizeValueExtraLarge,
+            color: Colors.purple,
+          ),
+        ],
+        customPainter: (context, value) {
+          return ParameterPainterBoardSize(value: value, context: context);
+        },
+      ),
+
+      // colors count
+      ApplicationSettingsParameter(
+        code: parameterCodeColorsCount,
+        values: [
+          ApplicationSettingsParameterItemValue(
+            value: colorsCountValueLow,
+            color: Colors.green,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: colorsCountValueMedium,
+            color: Colors.orange,
+            isDefault: true,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: colorsCountValueHigh,
+            color: Colors.red,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: colorsCountValueVeryHigh,
+            color: Colors.purple,
+          ),
+        ],
+        customPainter: (context, value) {
+          return ParameterPainterColorsCount(value: value, context: context);
+        },
+      ),
+
+      // colors theme
+      ApplicationSettingsParameter(
+        code: parameterCodeColorTheme,
+        displayedOnTop: false,
+        values: [
+          ApplicationSettingsParameterItemValue(
+            value: colorThemeGothicBit,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: colorThemeSweethope,
+            isDefault: true,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: colorThemeNostalgicDreams,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: colorThemeArjibi8,
+          ),
+        ],
+        customPainter: (context, value) {
+          return ParameterPainterColorTheme(value: value, context: context);
+        },
+      ),
+
+      // graphics theme
+      ApplicationSettingsParameter(
+        code: parameterCodeGraphicsTheme,
+        displayedOnTop: false,
+        values: [
+          ApplicationSettingsParameterItemValue(
+            value: graphicThemeSolidBackground,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: graphicThemeGradientAndBorder,
+            isDefault: true,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: graphicThemeEmojis,
+          ),
+          ApplicationSettingsParameterItemValue(
+            value: graphicThemePatterns,
+          ),
+        ],
+        customPainter: (context, value) {
+          return ParameterPainterGraphicTheme(value: value, context: context);
+        },
+      ),
+    ],
+    startNewActivity: (BuildContext context) {
+      BlocProvider.of<ActivityCubit>(context).startNewActivity(context);
+      BlocProvider.of<NavCubitPage>(context).goToPageGame();
+    },
+    deleteCurrentActivity: (BuildContext context) {
+      BlocProvider.of<ActivityCubit>(context).deleteSavedActivity();
+    },
+    resumeActivity: (BuildContext context) {
+      BlocProvider.of<ActivityCubit>(context).resumeSavedActivity();
+      BlocProvider.of<NavCubitPage>(context).goToPageGame();
+    },
+  );
+
+  static const List<String> graphicThemeContentEmojiStrings = [
+    '🍏',
+    '🤍',
+    '🦋',
+    '🐞',
+    '⭐',
+    '🍄',
+    '🍒',
+    '🐤',
+  ];
+  static const List<String> graphicThemeContentPatternStrings = [
+    '✖',
+    '✚',
+    '▲',
+    '■',
+    '●',
+    '◆',
+    '━',
+    '⧧',
+  ];
 }
diff --git a/lib/config/color_theme.dart b/lib/config/color_theme.dart
index c2d0f8f..6963600 100644
--- a/lib/config/color_theme.dart
+++ b/lib/config/color_theme.dart
@@ -1,12 +1,12 @@
-import 'package:flutter/material.dart';
+import 'package:jeweled/config/application_config.dart';
 
 class ColorTheme {
-  static Map<String, List<int>> itemColors = {
+  static const Map<String, List<int>> colorThemes = {
     // legacy
     // 0:[0x9D9D9D,0xFFFFFF,0xBE2633,0xE06F8B,0x493C2B,0xA46422,0xEB8931,0xF7E26B,0x2F484E,0x44891A,0xA3CE27,0x1B2632,0x005784,0x31A2F2,0xB2DCEF,],
 
     // https://lospec.com/palette-list/gothic-bit
-    'gothic-bit': [
+    ApplicationConfig.colorThemeGothicBit: [
       0x0e0e12,
       0x1a1a24,
       0x333346,
@@ -18,7 +18,7 @@ class ColorTheme {
     ],
 
     // https://lospec.com/palette-list/sweethope
-    'sweethope': [
+    ApplicationConfig.colorThemeSweethope: [
       0x615e85,
       0x9c8dc2,
       0xd9a3cd,
@@ -30,7 +30,7 @@ class ColorTheme {
     ],
 
     // https://lospec.com/palette-list/nostalgic-dreams
-    'nostalgic-dreams': [
+    ApplicationConfig.colorThemeNostalgicDreams: [
       0xd9af80,
       0xb07972,
       0x524352,
@@ -42,7 +42,7 @@ class ColorTheme {
     ],
 
     // https://lospec.com/palette-list/arjibi8
-    'arjibi8': [
+    ApplicationConfig.colorThemeArjibi8: [
       0x8bc7bf,
       0x5796a1,
       0x524bb3,
@@ -69,33 +69,5 @@ class ColorTheme {
     // 9:[0x111323,0x374566,0x50785d,0x8497b3,0xe8dcd8,0xcfb463,0xb35447,0x692e4b,],
   };
 
-  static int defaultItemColor = 0x808080;
-
-  static int getColorsCount(String colorsTheme) {
-    if (itemColors.containsKey(colorsTheme) && null != itemColors[colorsTheme]) {
-      List<int> skinColors = itemColors[colorsTheme] ?? [];
-
-      return skinColors.length;
-    }
-
-    return 0;
-  }
-
-  static int getColorCode(int? value, String colorsTheme) {
-    if (value != null &&
-        itemColors.containsKey(colorsTheme) &&
-        null != itemColors[colorsTheme]) {
-      List<int> skinColors = itemColors[colorsTheme] ?? [];
-      return (skinColors[value % getColorsCount(colorsTheme)]) | 0xFF000000;
-    }
-    return defaultItemColor | 0xFF000000;
-  }
-
-  static Color getColor(int? value, String colorsTheme) {
-    return Color(getColorCode(value, colorsTheme));
-  }
-
-  static Color getBorderColor() {
-    return Colors.grey;
-  }
+  static const int defaultThemeColor = 0x808080;
 }
diff --git a/lib/config/default_activity_settings.dart b/lib/config/default_activity_settings.dart
deleted file mode 100644
index 5439a6c..0000000
--- a/lib/config/default_activity_settings.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-class DefaultActivitySettings {
-  // available game parameters codes
-  static const String parameterCodeBoardSize = 'boardSize';
-  static const String parameterCodeColorsCount = 'colorsCount';
-  static const List<String> availableParameters = [
-    parameterCodeBoardSize,
-    parameterCodeColorsCount,
-  ];
-
-  // board size: available values
-  static const String boardSizeValueSmall = '6';
-  static const String boardSizeValueMedium = '10';
-  static const String boardSizeValueLarge = '14';
-  static const String boardSizeValueExtraLarge = '18';
-  static const List<String> allowedBoardSizeValues = [
-    boardSizeValueSmall,
-    boardSizeValueMedium,
-    boardSizeValueLarge,
-    boardSizeValueExtraLarge,
-  ];
-  // board size: default value
-  static const String defaultBoardSizeValue = boardSizeValueMedium;
-
-  // colors count: available values
-  static const String colorsCountValueLow = '5';
-  static const String colorsCountValueMedium = '6';
-  static const String colorsCountValueHigh = '7';
-  static const String colorsCountValueVeryHigh = '8';
-  static const List<String> allowedColorsCountValues = [
-    colorsCountValueLow,
-    colorsCountValueMedium,
-    colorsCountValueHigh,
-    colorsCountValueVeryHigh,
-  ];
-  // colors count: default value
-  static const String defaultColorsCountValue = colorsCountValueMedium;
-
-  // available values from parameter code
-  static List<String> getAvailableValues(String parameterCode) {
-    switch (parameterCode) {
-      case parameterCodeBoardSize:
-        return DefaultActivitySettings.allowedBoardSizeValues;
-      case parameterCodeColorsCount:
-        return DefaultActivitySettings.allowedColorsCountValues;
-    }
-
-    printlog('Did not find any available value for game parameter "$parameterCode".');
-    return [];
-  }
-
-  static int blockMinimumCellsCount = 3;
-}
diff --git a/lib/config/default_global_settings.dart b/lib/config/default_global_settings.dart
deleted file mode 100644
index 0d768ba..0000000
--- a/lib/config/default_global_settings.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-class DefaultGlobalSettings {
-  // available global parameters codes
-  static const String parameterCodeColorsTheme = 'colorsTheme';
-  static const String parameterCodeGraphicsTheme = 'graphicTheme';
-  static const List<String> availableParameters = [
-    parameterCodeColorsTheme,
-    parameterCodeGraphicsTheme,
-  ];
-
-  static const String colorThemeGothicBit = 'gothic-bit';
-  static const String colorThemeSweethope = 'sweethope';
-  static const String colorThemeNostalgicDreams = 'nostalgic-dreams';
-  static const String colorThemeArjibi8 = 'arjibi8';
-  static const String defaultColorsThemeValue = colorThemeSweethope;
-  static const List<String> allowedColorsThemeValues = [
-    colorThemeGothicBit,
-    colorThemeSweethope,
-    colorThemeNostalgicDreams,
-    colorThemeArjibi8,
-  ];
-
-  static const String graphicThemeSolidBackground = 'SolidBackground';
-  static const String graphicThemeGradientAndBorder = 'GradientAndBorder';
-  static const String graphicThemeEmojis = 'Emojis';
-  static const String graphicThemePatterns = 'Patterns';
-  static const List<String> allowedGraphicThemeValues = [
-    graphicThemeSolidBackground,
-    graphicThemeGradientAndBorder,
-    graphicThemeEmojis,
-    graphicThemePatterns,
-  ];
-
-  static const String defaultGraphicThemeValue = graphicThemeSolidBackground;
-
-  static const List<String> graphicThemeContentEmojiStrings = [
-    '🍏',
-    '🤍',
-    '🦋',
-    '🐞',
-    '⭐',
-    '🍄',
-    '🍒',
-    '🐤',
-  ];
-  static const List<String> graphicThemeContentPatternStrings = [
-    '✖',
-    '✚',
-    '▲',
-    '■',
-    '●',
-    '◆',
-    '━',
-    '⧧',
-  ];
-
-  // available values from parameter code
-  static List<String> getAvailableValues(String parameterCode) {
-    switch (parameterCode) {
-      case parameterCodeColorsTheme:
-        return DefaultGlobalSettings.allowedColorsThemeValues;
-      case parameterCodeGraphicsTheme:
-        return DefaultGlobalSettings.allowedGraphicThemeValues;
-    }
-
-    printlog('Did not find any available value for global parameter "$parameterCode".');
-    return [];
-  }
-}
diff --git a/lib/cubit/activity/activity_cubit.dart b/lib/cubit/activity/activity_cubit.dart
index 55b5ba4..ed4ccb2 100644
--- a/lib/cubit/activity/activity_cubit.dart
+++ b/lib/cubit/activity/activity_cubit.dart
@@ -1,11 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:jeweled/config/default_activity_settings.dart';
+import 'package:jeweled/config/application_config.dart';
 import 'package:jeweled/models/activity/cell_location.dart';
 import 'package:jeweled/models/activity/activity.dart';
-import 'package:jeweled/models/settings/settings_activity.dart';
-import 'package:jeweled/models/settings/settings_global.dart';
 
 part 'activity_state.dart';
 
@@ -25,7 +23,6 @@ class ActivityCubit extends HydratedCubit<ActivityState> {
     final Activity activity = Activity(
       // Settings
       activitySettings: state.currentActivity.activitySettings,
-      globalSettings: state.currentActivity.globalSettings,
       // State
       isRunning: state.currentActivity.isRunning,
       isStarted: state.currentActivity.isStarted,
@@ -44,13 +41,13 @@ class ActivityCubit extends HydratedCubit<ActivityState> {
     updateState(activity);
   }
 
-  void startNewActivity({
-    required ActivitySettings activitySettings,
-    required GlobalSettings globalSettings,
-  }) {
+  void startNewActivity(BuildContext context) {
+    final ActivitySettingsCubit activitySettingsCubit =
+        BlocProvider.of<ActivitySettingsCubit>(context);
+
     final Activity newActivity = Activity.createNew(
-      activitySettings: activitySettings,
-      globalSettings: globalSettings,
+      // Settings
+      activitySettings: activitySettingsCubit.state.settings,
     );
 
     newActivity.dump();
@@ -59,6 +56,10 @@ class ActivityCubit extends HydratedCubit<ActivityState> {
     postAnimate();
   }
 
+  bool canBeResumed() {
+    return state.currentActivity.canBeResumed;
+  }
+
   void quitActivity() {
     state.currentActivity.isRunning = false;
     refresh();
@@ -101,15 +102,17 @@ class ActivityCubit extends HydratedCubit<ActivityState> {
     refresh();
   }
 
-  void shuffleColors(final String colorsTheme) {
-    state.currentActivity.shuffleColorsAgain(colorsTheme);
+  void shuffleColors(final String colorTheme) {
+    state.currentActivity.shuffleColorsAgain(colorTheme);
   }
 
   moveCellsDown() {
     final Activity currentActivity = state.currentActivity;
 
-    final int boardSizeHorizontal = currentActivity.activitySettings.boardSizeValue;
-    final int boardSizeVertical = currentActivity.activitySettings.boardSizeValue;
+    final int boardSizeHorizontal =
+        currentActivity.activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+    final int boardSizeVertical =
+        currentActivity.activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
 
     for (int row = 0; row < boardSizeVertical; row++) {
       for (int col = 0; col < boardSizeHorizontal; col++) {
@@ -148,7 +151,7 @@ class ActivityCubit extends HydratedCubit<ActivityState> {
 
     if (cellValue != null) {
       List<CellLocation> blockCells = currentActivity.getSiblingCells(tappedCellLocation, []);
-      if (blockCells.length >= DefaultActivitySettings.blockMinimumCellsCount) {
+      if (blockCells.length >= ApplicationConfig.blockMinimumCellsCount) {
         deleteBlock(blockCells);
         increaseMovesCount();
         increaseScore(getScoreFromBlock(blockCells.length));
diff --git a/lib/cubit/settings/settings_activity_cubit.dart b/lib/cubit/settings/settings_activity_cubit.dart
deleted file mode 100644
index 338113b..0000000
--- a/lib/cubit/settings/settings_activity_cubit.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:jeweled/config/default_activity_settings.dart';
-import 'package:jeweled/models/settings/settings_activity.dart';
-
-part 'settings_activity_state.dart';
-
-class ActivitySettingsCubit extends HydratedCubit<ActivitySettingsState> {
-  ActivitySettingsCubit()
-      : super(ActivitySettingsState(settings: ActivitySettings.createDefault()));
-
-  void setValues({
-    String? boardSize,
-    String? colorsCount,
-  }) {
-    emit(
-      ActivitySettingsState(
-        settings: ActivitySettings(
-          boardSize: boardSize ?? state.settings.boardSize,
-          colorsCount: colorsCount ?? state.settings.colorsCount,
-        ),
-      ),
-    );
-  }
-
-  String getParameterValue(String code) {
-    switch (code) {
-      case DefaultActivitySettings.parameterCodeBoardSize:
-        return ActivitySettings.getBoardSizeValueFromUnsafe(state.settings.boardSize);
-      case DefaultActivitySettings.parameterCodeColorsCount:
-        return ActivitySettings.getColorsCountValueFromUnsafe(state.settings.colorsCount);
-    }
-
-    return '';
-  }
-
-  void setParameterValue(String code, String value) {
-    final String boardSize = code == DefaultActivitySettings.parameterCodeBoardSize
-        ? value
-        : getParameterValue(DefaultActivitySettings.parameterCodeBoardSize);
-    final String colorsCount = code == DefaultActivitySettings.parameterCodeColorsCount
-        ? value
-        : getParameterValue(DefaultActivitySettings.parameterCodeColorsCount);
-
-    setValues(
-      boardSize: boardSize,
-      colorsCount: colorsCount,
-    );
-  }
-
-  @override
-  ActivitySettingsState? fromJson(Map<String, dynamic> json) {
-    final String boardSize = json[DefaultActivitySettings.parameterCodeBoardSize] as String;
-    final String colorsCount =
-        json[DefaultActivitySettings.parameterCodeColorsCount] as String;
-
-    return ActivitySettingsState(
-      settings: ActivitySettings(
-        boardSize: boardSize,
-        colorsCount: colorsCount,
-      ),
-    );
-  }
-
-  @override
-  Map<String, dynamic>? toJson(ActivitySettingsState state) {
-    return <String, dynamic>{
-      DefaultActivitySettings.parameterCodeBoardSize: state.settings.boardSize,
-      DefaultActivitySettings.parameterCodeColorsCount: state.settings.colorsCount,
-    };
-  }
-}
diff --git a/lib/cubit/settings/settings_activity_state.dart b/lib/cubit/settings/settings_activity_state.dart
deleted file mode 100644
index 2b2de42..0000000
--- a/lib/cubit/settings/settings_activity_state.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-part of 'settings_activity_cubit.dart';
-
-@immutable
-class ActivitySettingsState extends Equatable {
-  const ActivitySettingsState({
-    required this.settings,
-  });
-
-  final ActivitySettings settings;
-
-  @override
-  List<dynamic> get props => <dynamic>[
-        settings,
-      ];
-}
diff --git a/lib/cubit/settings/settings_global_cubit.dart b/lib/cubit/settings/settings_global_cubit.dart
deleted file mode 100644
index 61d5504..0000000
--- a/lib/cubit/settings/settings_global_cubit.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:jeweled/config/default_global_settings.dart';
-import 'package:jeweled/models/settings/settings_global.dart';
-
-part 'settings_global_state.dart';
-
-class GlobalSettingsCubit extends HydratedCubit<GlobalSettingsState> {
-  GlobalSettingsCubit() : super(GlobalSettingsState(settings: GlobalSettings.createDefault()));
-
-  void setValues({
-    String? colorsTheme,
-    String? graphicTheme,
-  }) {
-    emit(
-      GlobalSettingsState(
-        settings: GlobalSettings(
-          colorsTheme: colorsTheme ?? state.settings.colorsTheme,
-          graphicTheme: graphicTheme ?? state.settings.graphicTheme,
-        ),
-      ),
-    );
-  }
-
-  String getParameterValue(String code) {
-    switch (code) {
-      case DefaultGlobalSettings.parameterCodeColorsTheme:
-        return GlobalSettings.getColorsThemeValueFromUnsafe(state.settings.colorsTheme);
-      case DefaultGlobalSettings.parameterCodeGraphicsTheme:
-        return GlobalSettings.getGraphicThemeValueFromUnsafe(state.settings.graphicTheme);
-    }
-    return '';
-  }
-
-  void setParameterValue(String code, String value) {
-    final String colorsTheme = code == DefaultGlobalSettings.parameterCodeColorsTheme
-        ? value
-        : getParameterValue(DefaultGlobalSettings.parameterCodeColorsTheme);
-    final String graphicTheme = code == DefaultGlobalSettings.parameterCodeGraphicsTheme
-        ? value
-        : getParameterValue(DefaultGlobalSettings.parameterCodeGraphicsTheme);
-
-    setValues(
-      colorsTheme: colorsTheme,
-      graphicTheme: graphicTheme,
-    );
-  }
-
-  @override
-  GlobalSettingsState? fromJson(Map<String, dynamic> json) {
-    final String colorsTheme = json[DefaultGlobalSettings.parameterCodeColorsTheme] as String;
-    final String graphicTheme =
-        json[DefaultGlobalSettings.parameterCodeGraphicsTheme] as String;
-
-    return GlobalSettingsState(
-      settings: GlobalSettings(
-        colorsTheme: colorsTheme,
-        graphicTheme: graphicTheme,
-      ),
-    );
-  }
-
-  @override
-  Map<String, dynamic>? toJson(GlobalSettingsState state) {
-    return <String, dynamic>{
-      DefaultGlobalSettings.parameterCodeColorsTheme: state.settings.colorsTheme,
-      DefaultGlobalSettings.parameterCodeGraphicsTheme: state.settings.graphicTheme,
-    };
-  }
-}
diff --git a/lib/cubit/settings/settings_global_state.dart b/lib/cubit/settings/settings_global_state.dart
deleted file mode 100644
index ebcddd7..0000000
--- a/lib/cubit/settings/settings_global_state.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-part of 'settings_global_cubit.dart';
-
-@immutable
-class GlobalSettingsState extends Equatable {
-  const GlobalSettingsState({
-    required this.settings,
-  });
-
-  final GlobalSettings settings;
-
-  @override
-  List<dynamic> get props => <dynamic>[
-        settings,
-      ];
-}
diff --git a/lib/main.dart b/lib/main.dart
index a1a19cc..6e7f804 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -9,8 +9,6 @@ import 'package:jeweled/common/cubit/nav/nav_cubit_screens.dart';
 
 import 'package:jeweled/config/application_config.dart';
 import 'package:jeweled/cubit/activity/activity_cubit.dart';
-import 'package:jeweled/cubit/settings/settings_activity_cubit.dart';
-import 'package:jeweled/cubit/settings/settings_global_cubit.dart';
 import 'package:jeweled/ui/skeleton.dart';
 
 void main() async {
@@ -61,17 +59,14 @@ class MyApp extends StatelessWidget {
         BlocProvider<ActivityCubit>(
           create: (context) => ActivityCubit(),
         ),
-        BlocProvider<GlobalSettingsCubit>(
-          create: (context) => GlobalSettingsCubit(),
-        ),
         BlocProvider<ActivitySettingsCubit>(
-          create: (context) => ActivitySettingsCubit(),
+          create: (context) => ActivitySettingsCubit(appConfig: ApplicationConfig.config),
         ),
       ],
       child: BlocBuilder<ApplicationThemeModeCubit, ApplicationThemeModeState>(
         builder: (BuildContext context, ApplicationThemeModeState state) {
           return MaterialApp(
-            title: ApplicationConfig.appTitle,
+            title: ApplicationConfig.config.appTitle,
             home: const SkeletonScreen(),
 
             // Theme stuff
diff --git a/lib/models/activity/activity.dart b/lib/models/activity/activity.dart
index c955f3a..c19a101 100644
--- a/lib/models/activity/activity.dart
+++ b/lib/models/activity/activity.dart
@@ -2,19 +2,16 @@ import 'dart:math';
 
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:jeweled/config/color_theme.dart';
-import 'package:jeweled/config/default_global_settings.dart';
+import 'package:jeweled/common/utils/color_theme_utils.dart';
+import 'package:jeweled/config/application_config.dart';
 import 'package:jeweled/models/activity/board.dart';
 import 'package:jeweled/models/activity/cell.dart';
 import 'package:jeweled/models/activity/cell_location.dart';
-import 'package:jeweled/models/settings/settings_activity.dart';
-import 'package:jeweled/models/settings/settings_global.dart';
 
 class Activity {
   Activity({
     // Settings
     required this.activitySettings,
-    required this.globalSettings,
 
     // State
     this.isRunning = false,
@@ -34,7 +31,6 @@ class Activity {
 
   // Settings
   final ActivitySettings activitySettings;
-  final GlobalSettings globalSettings;
 
   // State
   bool isRunning;
@@ -54,33 +50,32 @@ class Activity {
   factory Activity.createEmpty() {
     return Activity(
       // Settings
-      activitySettings: ActivitySettings.createDefault(),
-      globalSettings: GlobalSettings.createDefault(),
+      activitySettings: ActivitySettings.createDefault(appConfig: ApplicationConfig.config),
       // Base data
       board: Board.createEmpty(),
       // Game data
-      shuffledColors: shuffleColors(DefaultGlobalSettings.defaultColorsThemeValue),
+      shuffledColors: shuffleColors(ApplicationConfig.config
+          .getFromCode(ApplicationConfig.parameterCodeGraphicsTheme)
+          .defaultValue),
     );
   }
 
   factory Activity.createNew({
     ActivitySettings? activitySettings,
-    GlobalSettings? globalSettings,
   }) {
-    final ActivitySettings newActivitySettings =
-        activitySettings ?? ActivitySettings.createDefault();
-    final GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
+    final ActivitySettings newActivitySettings = activitySettings ??
+        ActivitySettings.createDefault(appConfig: ApplicationConfig.config);
 
     return Activity(
       // Settings
       activitySettings: newActivitySettings,
-      globalSettings: newGlobalSettings,
       // State
       isRunning: true,
       // Base data
       board: Board.createRandom(newActivitySettings),
       // Game data
-      shuffledColors: shuffleColors(newGlobalSettings.colorsTheme),
+      shuffledColors:
+          shuffleColors(newActivitySettings.get(ApplicationConfig.parameterCodeColorTheme)),
     );
   }
 
@@ -88,16 +83,16 @@ class Activity {
 
   bool get gameWon => isRunning && isStarted && isFinished;
 
-  static List<int> shuffleColors(final String colorsTheme) {
+  static List<int> shuffleColors(final String colorTheme) {
     List<int> values =
-        List<int>.generate(ColorTheme.getColorsCount(colorsTheme), (i) => i + 1);
+        List<int>.generate(ColorThemeUtils.getColorsCount(colorTheme), (i) => i + 1);
     values.shuffle();
 
     return values;
   }
 
-  void shuffleColorsAgain(final String colorsTheme) {
-    shuffledColors = shuffleColors(colorsTheme);
+  void shuffleColorsAgain(final String colorTheme) {
+    shuffledColors = shuffleColors(colorTheme);
   }
 
   Cell getCell(CellLocation cellLocation) {
@@ -133,8 +128,10 @@ class Activity {
     final CellLocation referenceCellLocation,
     List<CellLocation> siblingCells,
   ) {
-    final int boardSizeHorizontal = activitySettings.boardSizeValue;
-    final int boardSizeVertical = activitySettings.boardSizeValue;
+    final int boardSizeHorizontal =
+        activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+    final int boardSizeVertical =
+        activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
 
     final int? referenceValue = getCellValue(referenceCellLocation);
 
@@ -170,8 +167,10 @@ class Activity {
   }
 
   List<List<CellLocation>> getAvailableBlocks(final Activity activity) {
-    final int boardSizeHorizontal = activity.activitySettings.boardSizeValue;
-    final int boardSizeVertical = activity.activitySettings.boardSizeValue;
+    final int boardSizeHorizontal =
+        activity.activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+    final int boardSizeVertical =
+        activity.activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
 
     final List<List<CellLocation>> blocks = [];
 
@@ -203,8 +202,10 @@ class Activity {
   }
 
   bool hasAtLeastOneAvailableBlock() {
-    final int boardSizeHorizontal = activitySettings.boardSizeValue;
-    final int boardSizeVertical = activitySettings.boardSizeValue;
+    final int boardSizeHorizontal =
+        activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+    final int boardSizeVertical =
+        activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
 
     for (int row = 0; row < boardSizeVertical; row++) {
       for (int col = 0; col < boardSizeHorizontal; col++) {
@@ -224,7 +225,7 @@ class Activity {
   }
 
   bool isInBoard(CellLocation cell) {
-    final int boardSize = activitySettings.boardSizeValue;
+    final int boardSize = activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
 
     if (cell.row > 0 && cell.row < boardSize && cell.col > 0 && cell.col < boardSize) {
       return true;
@@ -240,14 +241,16 @@ class Activity {
     final List<int> values = [];
 
     // All eligible values (twice)
-    final int maxValue = activitySettings.colorsCountValue;
+    final int maxValue = activitySettings.getAsInt(ApplicationConfig.parameterCodeColorsCount);
     for (int i = 1; i <= maxValue; i++) {
       values.add(i);
       values.add(i);
     }
 
     // Add values of current col (twice)
-    for (int r = 0; r <= activitySettings.boardSizeValue; r++) {
+    for (int r = 0;
+        r <= activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+        r++) {
       if (isInBoard(CellLocation.go(r, col))) {
         final int? value = getCellValue(CellLocation.go(r, col));
         if (value != null) {
@@ -260,12 +263,15 @@ class Activity {
     // Add values of sibling cols (twice for top rows)
     for (int deltaCol = -1; deltaCol <= 1; deltaCol++) {
       final int c = col + deltaCol;
-      for (int r = 0; r < activitySettings.boardSizeValue; r++) {
+      for (int r = 0;
+          r < activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+          r++) {
         if (isInBoard(CellLocation.go(r, c))) {
           final int? value = getCellValue(CellLocation.go(r, c));
           if (value != null) {
             values.add(value);
-            if (row < activitySettings.boardSizeValue / 3) {
+            if (row <
+                activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize) / 3) {
               values.add(value);
             }
           }
@@ -298,7 +304,6 @@ class Activity {
     printlog('$Activity:');
     printlog('  Settings');
     activitySettings.dump();
-    globalSettings.dump();
     printlog('  State');
     printlog('    isRunning: $isRunning');
     printlog('    isStarted: $isStarted');
@@ -323,7 +328,6 @@ class Activity {
     return <String, dynamic>{
       // Settings
       'activitySettings': activitySettings.toJson(),
-      'globalSettings': globalSettings.toJson(),
       // State
       'isRunning': isRunning,
       'isStarted': isStarted,
diff --git a/lib/models/activity/board.dart b/lib/models/activity/board.dart
index af933d1..c665610 100644
--- a/lib/models/activity/board.dart
+++ b/lib/models/activity/board.dart
@@ -1,9 +1,9 @@
 import 'dart:math';
 
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+import 'package:jeweled/config/application_config.dart';
 
 import 'package:jeweled/models/activity/cell.dart';
-import 'package:jeweled/models/settings/settings_activity.dart';
 
 class Board {
   final List<List<Cell>> cells;
@@ -17,9 +17,11 @@ class Board {
   }
 
   factory Board.createRandom(ActivitySettings activitySettings) {
-    final int boardSizeHorizontal = activitySettings.boardSizeValue;
-    final int boardSizeVertical = activitySettings.boardSizeValue;
-    final int maxValue = activitySettings.colorsCountValue;
+    final int boardSizeHorizontal =
+        activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+    final int boardSizeVertical =
+        activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+    final int maxValue = activitySettings.getAsInt(ApplicationConfig.parameterCodeColorsCount);
 
     final rand = Random();
 
diff --git a/lib/models/settings/settings_activity.dart b/lib/models/settings/settings_activity.dart
deleted file mode 100644
index 106c7a1..0000000
--- a/lib/models/settings/settings_activity.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:jeweled/config/default_activity_settings.dart';
-
-class ActivitySettings {
-  final String boardSize;
-  final String colorsCount;
-
-  ActivitySettings({
-    required this.boardSize,
-    required this.colorsCount,
-  });
-
-  // Getters to convert String to int
-  int get boardSizeValue => int.parse(boardSize);
-  int get colorsCountValue => int.parse(colorsCount);
-
-  static String getBoardSizeValueFromUnsafe(String size) {
-    if (DefaultActivitySettings.allowedBoardSizeValues.contains(size)) {
-      return size;
-    }
-
-    return DefaultActivitySettings.defaultBoardSizeValue;
-  }
-
-  static String getColorsCountValueFromUnsafe(String colorsCount) {
-    if (DefaultActivitySettings.allowedColorsCountValues.contains(colorsCount)) {
-      return colorsCount;
-    }
-
-    return DefaultActivitySettings.defaultColorsCountValue;
-  }
-
-  factory ActivitySettings.createDefault() {
-    return ActivitySettings(
-      boardSize: DefaultActivitySettings.defaultBoardSizeValue,
-      colorsCount: DefaultActivitySettings.defaultColorsCountValue,
-    );
-  }
-
-  void dump() {
-    printlog('$ActivitySettings:');
-    printlog('  ${DefaultActivitySettings.parameterCodeBoardSize}: $boardSize');
-    printlog('  ${DefaultActivitySettings.parameterCodeColorsCount}: $colorsCount');
-    printlog('');
-  }
-
-  @override
-  String toString() {
-    return '$ActivitySettings(${toJson()})';
-  }
-
-  Map<String, dynamic>? toJson() {
-    return <String, dynamic>{
-      DefaultActivitySettings.parameterCodeBoardSize: boardSize,
-      DefaultActivitySettings.parameterCodeColorsCount: colorsCount,
-    };
-  }
-}
diff --git a/lib/models/settings/settings_global.dart b/lib/models/settings/settings_global.dart
deleted file mode 100644
index a79ed5c..0000000
--- a/lib/models/settings/settings_global.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:jeweled/config/default_global_settings.dart';
-
-class GlobalSettings {
-  final String colorsTheme;
-  final String graphicTheme;
-
-  GlobalSettings({
-    required this.colorsTheme,
-    required this.graphicTheme,
-  });
-
-  static String getColorsThemeValueFromUnsafe(String colorsTheme) {
-    if (DefaultGlobalSettings.allowedColorsThemeValues.contains(colorsTheme)) {
-      return colorsTheme;
-    }
-
-    return DefaultGlobalSettings.defaultColorsThemeValue;
-  }
-
-  static String getGraphicThemeValueFromUnsafe(String graphicTheme) {
-    if (DefaultGlobalSettings.allowedGraphicThemeValues.contains(graphicTheme)) {
-      return graphicTheme;
-    }
-
-    return DefaultGlobalSettings.defaultGraphicThemeValue;
-  }
-
-  factory GlobalSettings.createDefault() {
-    return GlobalSettings(
-      colorsTheme: DefaultGlobalSettings.defaultColorsThemeValue,
-      graphicTheme: DefaultGlobalSettings.defaultGraphicThemeValue,
-    );
-  }
-
-  void dump() {
-    printlog('$GlobalSettings:');
-    printlog('  ${DefaultGlobalSettings.parameterCodeColorsTheme}: $colorsTheme');
-    printlog('  ${DefaultGlobalSettings.parameterCodeGraphicsTheme}: $graphicTheme');
-    printlog('');
-  }
-
-  @override
-  String toString() {
-    return '$GlobalSettings(${toJson()})';
-  }
-
-  Map<String, dynamic>? toJson() {
-    return <String, dynamic>{
-      DefaultGlobalSettings.parameterCodeColorsTheme: colorsTheme,
-      DefaultGlobalSettings.parameterCodeGraphicsTheme: graphicTheme,
-    };
-  }
-}
diff --git a/lib/common/ui/nav/global_app_bar.dart b/lib/ui/global_app_bar.dart
similarity index 100%
rename from lib/common/ui/nav/global_app_bar.dart
rename to lib/ui/global_app_bar.dart
diff --git a/lib/common/ui/pages/game.dart b/lib/ui/pages/game.dart
similarity index 100%
rename from lib/common/ui/pages/game.dart
rename to lib/ui/pages/game.dart
diff --git a/lib/ui/painters/game_board_painter.dart b/lib/ui/painters/game_board_painter.dart
index 989a114..82c9f58 100644
--- a/lib/ui/painters/game_board_painter.dart
+++ b/lib/ui/painters/game_board_painter.dart
@@ -4,8 +4,8 @@ import 'dart:ui' as ui;
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:jeweled/config/color_theme.dart';
-import 'package:jeweled/config/default_global_settings.dart';
+import 'package:jeweled/common/utils/color_theme_utils.dart';
+import 'package:jeweled/config/application_config.dart';
 import 'package:jeweled/models/activity/cell_location.dart';
 import 'package:jeweled/models/activity/activity.dart';
 
@@ -20,7 +20,8 @@ class GameBoardPainter extends CustomPainter {
 
   @override
   void paint(Canvas canvas, Size size) {
-    String graphicTheme = activity.globalSettings.graphicTheme;
+    String graphicTheme =
+        activity.activitySettings.get(ApplicationConfig.parameterCodeGraphicsTheme);
 
     final double canvasSize = min(size.width, size.height);
 
@@ -28,14 +29,14 @@ class GameBoardPainter extends CustomPainter {
     const double boardBorderWidth = 3;
 
     switch (graphicTheme) {
-      case DefaultGlobalSettings.graphicThemeSolidBackground:
+      case ApplicationConfig.graphicThemeSolidBackground:
         drawBoard(
           canvas: canvas,
           canvasSize: canvasSize,
           activity: activity,
         );
         break;
-      case DefaultGlobalSettings.graphicThemeGradientAndBorder:
+      case ApplicationConfig.graphicThemeGradientAndBorder:
         drawBoard(
           canvas: canvas,
           canvasSize: canvasSize,
@@ -45,20 +46,20 @@ class GameBoardPainter extends CustomPainter {
           gradientTo: 10,
         );
         break;
-      case DefaultGlobalSettings.graphicThemeEmojis:
+      case ApplicationConfig.graphicThemeEmojis:
         drawBoard(
           canvas: canvas,
           canvasSize: canvasSize,
           activity: activity,
-          contentStrings: DefaultGlobalSettings.graphicThemeContentEmojiStrings,
+          contentStrings: ApplicationConfig.graphicThemeContentEmojiStrings,
         );
         break;
-      case DefaultGlobalSettings.graphicThemePatterns:
+      case ApplicationConfig.graphicThemePatterns:
         drawBoard(
           canvas: canvas,
           canvasSize: canvasSize,
           activity: activity,
-          contentStrings: DefaultGlobalSettings.graphicThemeContentPatternStrings,
+          contentStrings: ApplicationConfig.graphicThemeContentPatternStrings,
         );
         break;
 
@@ -67,7 +68,7 @@ class GameBoardPainter extends CustomPainter {
 
     // board borders
     final boardPaintBorder = Paint();
-    boardPaintBorder.color = ColorTheme.getBorderColor();
+    boardPaintBorder.color = ColorThemeUtils.getDefaultBorderColor();
     boardPaintBorder.strokeWidth = boardBorderWidth;
     boardPaintBorder.strokeCap = StrokeCap.round;
 
@@ -97,9 +98,12 @@ class GameBoardPainter extends CustomPainter {
     double borderWidth = 0,
     List<String>? contentStrings,
   }) {
-    final int cellsCountHorizontal = activity.activitySettings.boardSizeValue;
-    final int cellsCountVertical = activity.activitySettings.boardSizeValue;
-    final String colorsTheme = activity.globalSettings.colorsTheme;
+    final int cellsCountHorizontal =
+        activity.activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+    final int cellsCountVertical =
+        activity.activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize);
+    final String colorTheme =
+        activity.activitySettings.get(ApplicationConfig.parameterCodeColorTheme);
 
     final double size = canvasSize / max(cellsCountHorizontal, cellsCountVertical);
 
@@ -120,7 +124,7 @@ class GameBoardPainter extends CustomPainter {
             y: y,
             cellSize: size,
             cellValue: cellValue,
-            colorsTheme: colorsTheme,
+            colorTheme: colorTheme,
             overlapping: overlapping,
             gradientFrom: gradientFrom,
             gradientTo: gradientTo,
@@ -138,14 +142,14 @@ class GameBoardPainter extends CustomPainter {
     required double y,
     required double cellSize,
     required int cellValue,
-    required String colorsTheme,
+    required String colorTheme,
     required double overlapping,
     required int gradientFrom,
     required int gradientTo,
     required double borderWidth,
     required List<String>? contentStrings,
   }) {
-    final Color baseColor = ColorTheme.getColor(cellValue, colorsTheme);
+    final Color baseColor = ColorThemeUtils.getColor(cellValue, colorTheme);
 
     final paint = Paint();
 
diff --git a/lib/ui/parameters/parameter_painter_board_size.dart b/lib/ui/parameters/parameter_painter_board_size.dart
new file mode 100644
index 0000000..51d6c5a
--- /dev/null
+++ b/lib/ui/parameters/parameter_painter_board_size.dart
@@ -0,0 +1,80 @@
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:jeweled/common/utils/color_theme_utils.dart';
+import 'package:jeweled/config/application_config.dart';
+
+class ParameterPainterBoardSize extends CustomPainter {
+  const ParameterPainterBoardSize({
+    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);
+
+    final ActivitySettings activitySettings =
+        BlocProvider.of<ActivitySettingsCubit>(context).state.settings;
+
+    int gridWidth = 1;
+
+    switch (value) {
+      case ApplicationConfig.boardSizeValueSmall:
+        gridWidth = 2;
+        break;
+      case ApplicationConfig.boardSizeValueMedium:
+        gridWidth = 3;
+        break;
+      case ApplicationConfig.boardSizeValueLarge:
+        gridWidth = 4;
+        break;
+      case ApplicationConfig.boardSizeValueExtraLarge:
+        gridWidth = 5;
+        break;
+      default:
+        printlog('Wrong value for boardSize parameter value: $value');
+    }
+
+    final paint = Paint();
+    paint.strokeJoin = StrokeJoin.round;
+    paint.strokeWidth = 3 / 100 * canvasSize;
+
+    // Mini grid
+    final borderColor = Colors.grey.shade800;
+
+    final double cellSize = canvasSize / 7;
+    final double origin = (canvasSize - gridWidth * cellSize) / 2;
+
+    final String colorTheme = activitySettings.get(ApplicationConfig.parameterCodeColorTheme);
+
+    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, colorTheme));
+
+        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/parameters/parameter_painter_color_theme.dart b/lib/ui/parameters/parameter_painter_color_theme.dart
new file mode 100644
index 0000000..e1f65dd
--- /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:jeweled/common/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/parameters/parameter_painter_colors_count.dart b/lib/ui/parameters/parameter_painter_colors_count.dart
new file mode 100644
index 0000000..753f933
--- /dev/null
+++ b/lib/ui/parameters/parameter_painter_colors_count.dart
@@ -0,0 +1,96 @@
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:jeweled/common/utils/color_theme_utils.dart';
+import 'package:jeweled/config/application_config.dart';
+
+class ParameterPainterColorsCount extends CustomPainter {
+  const ParameterPainterColorsCount({
+    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);
+
+    final ActivitySettings activitySettings =
+        BlocProvider.of<ActivitySettingsCubit>(context).state.settings;
+
+    final paint = Paint();
+    paint.strokeJoin = StrokeJoin.round;
+    paint.strokeWidth = 3;
+
+    // Colors preview
+    const List<Offset> positions = [
+      Offset(0, 0),
+      Offset(1, 0),
+      Offset(2, 0),
+      Offset(2, 1),
+      Offset(2, 2),
+      Offset(1, 2),
+      Offset(0, 2),
+      Offset(0, 1),
+    ];
+
+    final double padding = 4 / 100 * canvasSize;
+    final double margin = 3 / 100 * canvasSize;
+    final double width = ((canvasSize - 2 * padding) / 3) - 2 * margin;
+
+    final colorsCount = int.parse(value);
+
+    for (int colorIndex = 0; colorIndex < colorsCount; colorIndex++) {
+      final Offset position = positions[colorIndex];
+
+      final Offset topLeft = Offset(padding + margin + position.dx * (width + 2 * margin),
+          padding + margin + position.dy * (width + 2 * margin));
+
+      final Offset bottomRight = topLeft + Offset(width, width);
+
+      final squareColor = Color(ColorThemeUtils.getColorCode(
+          colorIndex, activitySettings.get(ApplicationConfig.parameterCodeColorTheme)));
+      paint.color = squareColor;
+      paint.style = PaintingStyle.fill;
+      canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
+
+      final borderColor = squareColor.darken(20);
+      paint.color = borderColor;
+      paint.style = PaintingStyle.stroke;
+      canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
+    }
+
+    // centered text value
+    final textSpan = TextSpan(
+      text: value.toString(),
+      style: TextStyle(
+        color: Colors.black,
+        fontSize: canvasSize / 4,
+        fontWeight: FontWeight.bold,
+      ),
+    );
+    final textPainter = TextPainter(
+      text: textSpan,
+      textDirection: TextDirection.ltr,
+      textAlign: TextAlign.center,
+    );
+    textPainter.layout();
+    textPainter.paint(
+      canvas,
+      Offset(
+        (canvasSize - textPainter.width) * 0.5,
+        (canvasSize - textPainter.height) * 0.5,
+      ),
+    );
+  }
+
+  @override
+  bool shouldRepaint(CustomPainter oldDelegate) {
+    return false;
+  }
+}
diff --git a/lib/ui/parameters/parameter_painter_graphic_theme.dart b/lib/ui/parameters/parameter_painter_graphic_theme.dart
new file mode 100644
index 0000000..73ec570
--- /dev/null
+++ b/lib/ui/parameters/parameter_painter_graphic_theme.dart
@@ -0,0 +1,133 @@
+import 'dart:math';
+import 'dart:ui' as ui;
+
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:jeweled/common/utils/color_theme_utils.dart';
+import 'package:jeweled/config/application_config.dart';
+
+class ParameterPainterGraphicTheme extends CustomPainter {
+  const ParameterPainterGraphicTheme({
+    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);
+
+    final ActivitySettings activitySettings =
+        BlocProvider.of<ActivitySettingsCubit>(context).state.settings;
+
+    final paint = Paint();
+    paint.strokeJoin = StrokeJoin.round;
+    paint.strokeWidth = 3;
+
+    // cells preview
+    const List<Offset> positions = [
+      Offset(0, 0),
+      Offset(1, 0),
+      Offset(2, 0),
+      Offset(2, 1),
+      Offset(2, 2),
+      Offset(1, 2),
+      Offset(0, 2),
+      Offset(0, 1),
+    ];
+
+    final double padding = 5 / 100 * canvasSize;
+    final double width = (canvasSize - 2 * padding) / 3;
+
+    bool drawBorder = false;
+    bool gradientColor = false;
+    List<String> contentStrings = [];
+
+    switch (value) {
+      case ApplicationConfig.graphicThemeSolidBackground:
+        break;
+      case ApplicationConfig.graphicThemeGradientAndBorder:
+        drawBorder = true;
+        gradientColor = true;
+        break;
+      case ApplicationConfig.graphicThemeEmojis:
+        contentStrings = ApplicationConfig.graphicThemeContentEmojiStrings;
+        break;
+      case ApplicationConfig.graphicThemePatterns:
+        contentStrings = ApplicationConfig.graphicThemeContentPatternStrings;
+        break;
+      default:
+        printlog('Wrong value for colorsCount parameter value: $value');
+    }
+
+    for (int itemValue = 0; itemValue < positions.length; itemValue++) {
+      final Offset position = positions[itemValue];
+
+      final Offset topLeft =
+          Offset(padding + position.dx * width, padding + position.dy * width);
+      final Offset bottomRight = topLeft + Offset(width, width);
+
+      final Rect itemBox = Rect.fromPoints(topLeft, bottomRight);
+      final itemColor = ColorThemeUtils.getColor(
+          itemValue, activitySettings.get(ApplicationConfig.parameterCodeColorTheme));
+
+      paint.color = itemColor;
+      paint.style = PaintingStyle.fill;
+      canvas.drawRect(itemBox, paint);
+
+      // gradient background
+      if (gradientColor) {
+        paint.shader = ui.Gradient.linear(itemBox.topLeft, itemBox.bottomCenter, [
+          itemColor.lighten(10),
+          itemColor.darken(10),
+        ]);
+        paint.style = PaintingStyle.fill;
+        canvas.drawRect(itemBox, paint);
+      }
+
+      // cell border
+      if (drawBorder) {
+        final paintBorder = Paint();
+        paintBorder.color = itemColor.darken(20);
+        paintBorder.style = PaintingStyle.stroke;
+        paintBorder.strokeWidth = 2;
+
+        canvas.drawRect(itemBox, paintBorder);
+      }
+
+      // centered text value
+      if (contentStrings.isNotEmpty) {
+        final textSpan = TextSpan(
+          text: contentStrings[itemValue],
+          style: TextStyle(
+            color: Colors.black,
+            fontSize: width / 2,
+            fontWeight: FontWeight.bold,
+          ),
+        );
+        final textPainter = TextPainter(
+          text: textSpan,
+          textDirection: TextDirection.ltr,
+          textAlign: TextAlign.center,
+        );
+        textPainter.layout();
+        textPainter.paint(
+          canvas,
+          Offset(
+            topLeft.dx + (width - textPainter.width) * 0.5,
+            topLeft.dy + (width - textPainter.height) * 0.5,
+          ),
+        );
+      }
+    }
+  }
+
+  @override
+  bool shouldRepaint(CustomPainter oldDelegate) {
+    return false;
+  }
+}
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
index d778b51..5f1e2c9 100644
--- a/lib/ui/skeleton.dart
+++ b/lib/ui/skeleton.dart
@@ -4,7 +4,7 @@ import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:jeweled/common/config/activity_page.dart';
 import 'package:jeweled/common/config/screen.dart';
 import 'package:jeweled/common/cubit/nav/nav_cubit_screens.dart';
-import 'package:jeweled/common/ui/nav/global_app_bar.dart';
+import 'package:jeweled/ui/global_app_bar.dart';
 import 'package:jeweled/common/ui/nav/bottom_nav_bar.dart';
 
 class SkeletonScreen extends StatelessWidget {
diff --git a/lib/ui/widgets/game/board.dart b/lib/ui/widgets/game/board.dart
index e1c4ffa..deff530 100644
--- a/lib/ui/widgets/game/board.dart
+++ b/lib/ui/widgets/game/board.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+import 'package:jeweled/config/application_config.dart';
 
 import 'package:jeweled/cubit/activity/activity_cubit.dart';
 import 'package:jeweled/models/activity/cell_location.dart';
@@ -57,7 +58,8 @@ class _BoardWidget extends State<BoardWidget> with TickerProviderStateMixin {
             if (status == AnimationStatus.completed) {
               activityCubit.postAnimate();
 
-              resetAnimations(currentActivity.activitySettings.boardSizeValue);
+              resetAnimations(currentActivity.activitySettings
+                  .getAsInt(ApplicationConfig.parameterCodeBoardSize));
               setState(() {});
 
               controller.dispose();
@@ -66,9 +68,9 @@ class _BoardWidget extends State<BoardWidget> with TickerProviderStateMixin {
 
     // Count translation length for each cell to move
     final List<List<int>> stepsDownCounts = List.generate(
-      currentActivity.activitySettings.boardSizeValue,
+      currentActivity.activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize),
       (i) => List.generate(
-        currentActivity.activitySettings.boardSizeValue,
+        currentActivity.activitySettings.getAsInt(ApplicationConfig.parameterCodeBoardSize),
         (i) => 0,
       ),
     );
@@ -105,7 +107,8 @@ class _BoardWidget extends State<BoardWidget> with TickerProviderStateMixin {
           final Activity currentActivity = activityState.currentActivity;
 
           if (animations.isEmpty) {
-            resetAnimations(currentActivity.activitySettings.boardSizeValue);
+            resetAnimations(currentActivity.activitySettings
+                .getAsInt(ApplicationConfig.parameterCodeBoardSize));
           }
 
           return GestureDetector(
@@ -122,10 +125,14 @@ class _BoardWidget extends State<BoardWidget> with TickerProviderStateMixin {
               if (!animationInProgress) {
                 final double xTap = details.localPosition.dx;
                 final double yTap = details.localPosition.dy;
-                final int col =
-                    xTap ~/ (displayWidth / currentActivity.activitySettings.boardSizeValue);
-                final int row =
-                    yTap ~/ (displayWidth / currentActivity.activitySettings.boardSizeValue);
+                final int col = xTap ~/
+                    (displayWidth /
+                        currentActivity.activitySettings
+                            .getAsInt(ApplicationConfig.parameterCodeBoardSize));
+                final int row = yTap ~/
+                    (displayWidth /
+                        currentActivity.activitySettings
+                            .getAsInt(ApplicationConfig.parameterCodeBoardSize));
 
                 animateCells(BlocProvider.of<ActivityCubit>(context)
                     .tapOnCell(CellLocation.go(row, col)));
diff --git a/lib/ui/widgets/indicators/indicator_shuffle_button.dart b/lib/ui/widgets/indicators/indicator_shuffle_button.dart
index 63f2063..898866e 100644
--- a/lib/ui/widgets/indicators/indicator_shuffle_button.dart
+++ b/lib/ui/widgets/indicators/indicator_shuffle_button.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+import 'package:jeweled/config/application_config.dart';
 
 import 'package:jeweled/cubit/activity/activity_cubit.dart';
 import 'package:jeweled/models/activity/activity.dart';
@@ -22,8 +23,8 @@ class ShuffleButton extends StatelessWidget {
         outlineColor: outlineColor,
       ),
       onPressed: () {
-        BlocProvider.of<ActivityCubit>(context)
-            .shuffleColors(activity.globalSettings.colorsTheme);
+        BlocProvider.of<ActivityCubit>(context).shuffleColors(
+            activity.activitySettings.get(ApplicationConfig.parameterCodeColorTheme));
       },
     );
   }
diff --git a/pubspec.lock b/pubspec.lock
index 1896dfc..0d7744c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -122,11 +122,11 @@ packages:
     dependency: "direct main"
     description:
       path: "."
-      ref: "0.4.0"
-      resolved-ref: eb9c090bd00d73324eab8737f74b3339cc24c9e8
+      ref: "0.5.0"
+      resolved-ref: b8164a50489ba981ea57d9f02e2334f09cb8c6a7
       url: "https://git.harrault.fr/android/flutter-toolbox.git"
     source: git
-    version: "0.4.0"
+    version: "0.5.0"
   flutter_lints:
     dependency: "direct dev"
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index ddbb3e5..d8e41a3 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: Jeweled Game
 
 publish_to: "none"
 
-version: 0.4.2+40
+version: 0.5.0+41
 
 environment:
   sdk: "^3.0.0"
@@ -16,7 +16,7 @@ dependencies:
   flutter_custom_toolbox:
     git:
       url: https://git.harrault.fr/android/flutter-toolbox.git
-      ref: 0.4.0
+      ref: 0.5.0
 
   # specific
   # (none)
-- 
GitLab