Commit a9b26a5

derdilla <derdilla06@gmail.com>
2023-05-03 17:03:26
FEAT: make colors customizable
1 parent 279c8ab
lib/components/complex_settings.dart
@@ -0,0 +1,52 @@
+import 'package:blood_pressure_app/model/settings.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
+import 'package:settings_ui/settings_ui.dart';
+
+class ColorSelectionTile {
+  final ValueChanged<ColorSwatch?>? onMainColorChanged;
+  final MaterialColor initialColor;
+  final Widget title;
+
+  const ColorSelectionTile({required this.title, required this.onMainColorChanged, required this.initialColor});
+
+
+  SettingsTile build(BuildContext context) {
+    return SettingsTile(
+      leading: Container(
+        width: 25.0,
+        height: 25.0,
+        decoration: BoxDecoration(
+          color: initialColor,
+          shape: BoxShape.circle,
+        ),
+      ),
+      title: title,
+      onPressed: (context) {
+        showDialog(
+          context: context,
+          builder: (_) {
+            return AlertDialog(
+              contentPadding: const EdgeInsets.all(6.0),
+              title: const Text('select color'),
+              content: MaterialColorPicker(
+                selectedColor: initialColor,
+                onMainColorChange: (color) {
+                  onMainColorChanged?.call(color);
+                  Navigator.of(context).pop();
+                },
+              ),
+              actions: [
+                TextButton(
+                  onPressed: Navigator.of(context).pop,
+                  child: const Text('CLOSE'),
+                ),
+              ],
+            );
+          },
+        );
+      },
+    );
+  }
+
+}
\ No newline at end of file
lib/components/measurement_graph.dart
@@ -11,10 +11,6 @@ import 'package:blood_pressure_app/model/settings.dart';
 class _LineChart extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    const pulseColor = Colors.red;
-    const diaColor = Colors.green;
-    const sysColor = Colors.teal;
-
     return Stack(
       children: [
         Align(
@@ -102,14 +98,14 @@ class _LineChart extends StatelessWidget {
                                             // high blood pressure marking acordning to https://www.texasheart.org/heart-health/heart-information-center/topics/high-blood-pressure-hypertension/
                                             LineChartBarData(
                                                 spots: pulseSpots,
-                                                color: pulseColor,
+                                                color: settings.pulColor,
                                                 barWidth: 4,
                                                 isCurved: true,
                                                 preventCurveOverShooting: true
                                             ),
                                             LineChartBarData(
                                                 spots: diastolicSpots,
-                                                color: diaColor,
+                                                color: settings.diaColor,
                                                 barWidth: 4,
                                                 isCurved: true,
                                                 preventCurveOverShooting: true,
@@ -122,7 +118,7 @@ class _LineChart extends StatelessWidget {
                                             ),
                                             LineChartBarData(
                                                 spots: systolicSpots,
-                                                color: sysColor,
+                                                color: settings.sysColor,
                                                 barWidth: 4,
                                                 isCurved: true,
                                                 preventCurveOverShooting: true,
lib/components/measurement_list.dart
@@ -1,4 +1,5 @@
 import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/settings.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import 'package:intl/intl.dart';
@@ -20,7 +21,6 @@ class MeasurementList extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    // TODO: implement build
     return Container(
         child: Column(
           children: [
@@ -90,53 +90,56 @@ class MeasurementList extends StatelessWidget {
 
 
   Widget buildTableHeader(BuildContext context) {
-    return Container(
-      child: Column (
-        children: [
-          const SizedBox(height: 15 ),
-          Row(
-          children: [
-            Expanded(
-              flex: _sideFlex,
-              child: SizedBox(),
-            ),
-            Expanded(
-                flex: _tableElementsSizes[0],
-                child: Text("time", style: TextStyle(fontWeight: FontWeight.bold))
-            ),
-            Expanded(
-                flex: _tableElementsSizes[1],
-                child: Text("sys",
-                    style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).primaryColor))
-            ),
-            Expanded(
-                flex: _tableElementsSizes[2],
-                child: const Text("dia",
-                    style: TextStyle(fontWeight: FontWeight.bold, color: Colors.green))
+    return Consumer<Settings>(
+        builder: (context, settings, child) {
+          return Container(
+            child: Column (
+                children: [
+                  const SizedBox(height: 15 ),
+                  Row(
+                    children: [
+                      Expanded(
+                        flex: _sideFlex,
+                        child: SizedBox(),
+                      ),
+                      Expanded(
+                          flex: _tableElementsSizes[0],
+                          child: const Text("time", style: TextStyle(fontWeight: FontWeight.bold))
+                      ),
+                      Expanded(
+                          flex: _tableElementsSizes[1],
+                          child: Text("sys",
+                              style: TextStyle(fontWeight: FontWeight.bold, color: settings.sysColor))
+                      ),
+                      Expanded(
+                          flex: _tableElementsSizes[2],
+                          child: Text("dia",
+                              style: TextStyle(fontWeight: FontWeight.bold, color: settings.diaColor))
+                      ),
+                      Expanded(
+                          flex: _tableElementsSizes[3],
+                          child: Text("pul",
+                              style: TextStyle(fontWeight: FontWeight.bold, color: settings.pulColor))
+                      ),
+                      Expanded(
+                          flex: _tableElementsSizes[4],
+                          child: const Text("notes", style: TextStyle(fontWeight: FontWeight.bold))
+                      ),
+                      Expanded(
+                        flex: _sideFlex,
+                        child: SizedBox(),
+                      ),
+                    ],
+                  ),
+                  Divider(
+                    height: 20,
+                    thickness: 2,
+                    color: Theme.of(context).primaryColor,
+                  )
+                ]
             ),
-            Expanded(
-                flex: _tableElementsSizes[3],
-                child: const Text("pul",
-                    style: TextStyle(fontWeight: FontWeight.bold, color: Colors.red))
-            ),
-            Expanded(
-                flex: _tableElementsSizes[4],
-                child: Text("notes", style: TextStyle(fontWeight: FontWeight.bold))
-            ),
-            Expanded(
-              flex: _sideFlex,
-              child: SizedBox(),
-            ),
-          ],
-          ),
-          Divider(
-            height: 20,
-            thickness: 2,
-            color: Theme.of(context).primaryColor,
-          )
-        ]
-      ),
-    );
+          );
+        });
   }
 }
 
lib/model/settings.dart
@@ -20,6 +20,10 @@ class Settings extends ChangeNotifier {
   late DateTime _graphEnd;
   late bool _followSystemDarkMode;
   late bool _darkMode;
+  late MaterialColor _accentColor;
+  late MaterialColor _sysColor;
+  late MaterialColor _diaColor;
+  late MaterialColor _pulColor;
 
   Settings._create();
   Future<void> _asyncInit() async {
@@ -61,14 +65,44 @@ class Settings extends ChangeNotifier {
     var pGraphEnd = _getSetting('_graphEnd');
     var pFollowSystemDarkMode = _getSetting('_followSystemDarkMode');
     var pDarkMode = _getSetting('_darkMode');
+    var pAccentColor = _getSetting('_accentColor');
+    var pSysColor = _getSetting('_sysColor');
+    var pDiaColor = _getSetting('_diaColor');
+    var pPulColor = _getSetting('_pulColor');
     // var ...
 
     _graphStepSize = (await pGraphStepSize as int?) ?? TimeStep.day;
     _graphStart = DateTime.fromMillisecondsSinceEpoch((await pGraphStart as int?) ?? -1);
     _graphEnd = DateTime.fromMillisecondsSinceEpoch((await pGraphEnd as int?) ?? -1);
     _followSystemDarkMode = ((await pFollowSystemDarkMode as int?) ?? "1") == "1" ? true : false;
-    _darkMode = ((await pDarkMode as int?) ?? "1") == "1" ? true : false;
+    _darkMode = ((await pDarkMode as int?) ?? 1) == 1 ? true : false;
+    _accentColor = createMaterialColor(await pAccentColor as int? ?? 0xFF009688);
+    _sysColor = createMaterialColor(await pSysColor as int? ?? 0xFF009688);
+    _diaColor = createMaterialColor(await pDiaColor as int? ?? 0xFF4CAF50);
+    _pulColor = createMaterialColor(await pPulColor as int? ?? 0xFFF44336);
     // ...
+    return;
+  }
+
+  MaterialColor createMaterialColor(int value) {
+    final color = Color(value);
+    List strengths = <double>[.05];
+    Map<int, Color> swatch = {};
+    final int r = color.red, g = color.green, b = color.blue;
+
+    for (int i = 1; i < 10; i++) {
+      strengths.add(0.1 * i);
+    }
+    for (var strength in strengths) {
+      final double ds = 0.5 - strength;
+      swatch[(strength * 1000).round()] = Color.fromRGBO(
+        r + ((ds < 0 ? r : (255 - r)) * ds).round(),
+        g + ((ds < 0 ? g : (255 - g)) * ds).round(),
+        b + ((ds < 0 ? b : (255 - b)) * ds).round(),
+        1,
+      );
+    }
+    return MaterialColor(value, swatch);
   }
 
   int get graphStepSize {
@@ -102,7 +136,7 @@ class Settings extends ChangeNotifier {
   }
   set followSystemDarkMode(bool newSetting) {
     _followSystemDarkMode = newSetting;
-    _saveSetting('_followSystemDarkMode', newSetting ? 1 : 0);
+    _saveSetting('_followSystemDarkMode', newSetting ? "1" : "0");
     notifyListeners();
   }
   bool get darkMode {
@@ -113,6 +147,38 @@ class Settings extends ChangeNotifier {
     _saveSetting('_darkMode', newSetting ? 1 : 0);
     notifyListeners();
   }
+  MaterialColor get accentColor {
+    return _accentColor;
+  }
+  set accentColor(MaterialColor newColor) {
+    _accentColor = newColor;
+    _saveSetting('_accentColor', newColor.value);
+    notifyListeners();
+  }
+  MaterialColor get diaColor {
+    return _diaColor;
+  }
+  set diaColor(MaterialColor newColor) {
+    _diaColor = newColor;
+    _saveSetting('_diaColor', newColor.value);
+    notifyListeners();
+  }
+  MaterialColor get sysColor {
+    return _sysColor;
+  }
+  set sysColor(MaterialColor newColor) {
+    _sysColor = newColor;
+    _saveSetting('_sysColor', newColor.value);
+    notifyListeners();
+  }
+  MaterialColor get pulColor {
+    return _pulColor;
+  }
+  set pulColor(MaterialColor newColor) {
+    _pulColor = newColor;
+    _saveSetting('_pulColor', newColor.value);
+    notifyListeners();
+  }
 
 }
 
lib/screens/settings.dart
@@ -1,7 +1,9 @@
+import 'package:blood_pressure_app/components/complex_settings.dart';
 import 'package:blood_pressure_app/model/settings.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import 'package:settings_ui/settings_ui.dart';
+import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
 
 class SettingsScreen extends StatelessWidget {
   const SettingsScreen({super.key});
@@ -17,7 +19,7 @@ class SettingsScreen extends StatelessWidget {
           builder: (context, settings, child) {
             return SettingsList(sections: [
               SettingsSection(
-                  title: const Text('common'),
+                  title: const Text('theme'),
                   tiles: <SettingsTile>[
                     SettingsTile.switchTile(
                         initialValue: settings.followSystemDarkMode,
@@ -28,7 +30,7 @@ class SettingsScreen extends StatelessWidget {
                         title: const Text('follow system dark mode')
                     ),
                     SettingsTile.switchTile(
-                        initialValue: (() {
+                      initialValue: (() {
                           if (settings.followSystemDarkMode) {
                             return MediaQuery.of(context).platformBrightness == Brightness.dark;
                           }
@@ -38,9 +40,30 @@ class SettingsScreen extends StatelessWidget {
                           settings.darkMode = value;
                         },
                       leading: const Icon(Icons.dark_mode),
-                        title: const Text('enable dark mode'),
+                      title: const Text('enable dark mode'),
                       enabled: !settings.followSystemDarkMode,
                     ),
+                    //settings.accentColor = settings.createMaterialColor((color ?? Colors.teal).value);
+                    ColorSelectionTile(
+                        onMainColorChanged: (color) => settings.accentColor = settings.createMaterialColor((color ?? Colors.teal).value),
+                        initialColor: settings.accentColor,
+                        title: const Text('theme color')
+                    ).build(context),
+                    ColorSelectionTile(
+                        onMainColorChanged: (color) => settings.sysColor = settings.createMaterialColor((color ?? Colors.green).value),
+                        initialColor: settings.sysColor,
+                        title: const Text('systolic color')
+                    ).build(context),
+                    ColorSelectionTile(
+                        onMainColorChanged: (color) => settings.diaColor = settings.createMaterialColor((color ?? Colors.teal).value),
+                        initialColor: settings.diaColor,
+                        title: const Text('diastolic color')
+                    ).build(context),
+                    ColorSelectionTile(
+                        onMainColorChanged: (color) => settings.pulColor = settings.createMaterialColor((color ?? Colors.red).value),
+                        initialColor: settings.pulColor,
+                        title: const Text('pulse color')
+                    ).build(context),
                   ]
               )
             ]);
lib/main.dart
@@ -51,12 +51,12 @@ class AppRoot extends StatelessWidget {
           return MaterialApp(
             title: 'Blood Pressure App',
             theme: ThemeData(
-                primaryColor: Colors.teal
+                primaryColor: settings.accentColor
             ),
             darkTheme: ThemeData(
                 brightness: Brightness.dark,
                 canvasColor: Colors.black,
-                primaryColor: Colors.teal.shade400,
+                primaryColor: settings.accentColor.shade400,
                 iconTheme: const IconThemeData(color: Colors.black)
             ),
             themeMode:  mode,
pubspec.lock
@@ -126,6 +126,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.0.1"
+  flutter_material_color_picker:
+    dependency: "direct main"
+    description:
+      name: flutter_material_color_picker
+      sha256: "64432c3b13bbcc6f428bae9d2e75b1b3da1e6f3219979e08a3bd9f176781d9f2"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.0+2"
   flutter_test:
     dependency: "direct dev"
     description: flutter
pubspec.yaml
@@ -43,6 +43,7 @@ dependencies:
   file_saver: ^0.2.1
   share_plus: ^4.5.3
   settings_ui: ^2.0.2
+  flutter_material_color_picker: ^1.1.0+2
 
 dev_dependencies:
   flutter_test: