diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 8ab4149..300b679 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:hsluv/hsluv.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:obtainium/components/generated_form_modal.dart'; @@ -132,19 +133,19 @@ class GeneratedForm extends StatefulWidget { State createState() => _GeneratedFormState(); } -// Generates a random light color -// Courtesy of ChatGPT 😭 (with a bugfix 🥳) +// Generates a color in the HSLuv (Pastel) color space +// https://pub.dev/documentation/hsluv/latest/hsluv/Hsluv/hpluvToRgb.html Color generateRandomLightColor() { - // Create a random number generator - final Random random = Random(); - - // Generate random hue, saturation, and value values - final double hue = random.nextDouble() * 360; - final double saturation = 0.5 + random.nextDouble() * 0.5; - final double value = 0.9 + random.nextDouble() * 0.1; - - // Create a HSV color with the random values - return HSVColor.fromAHSV(1.0, hue, saturation, value).toColor(); + final randomSeed = Random().nextInt(120); + // https://en.wikipedia.org/wiki/Golden_angle + final goldenAngle = 180 * (3 - sqrt(5)); + // Generate next golden angle hue + final double hue = randomSeed * goldenAngle; + // Map from HPLuv color space to RGB, use constant saturation=100, lightness=70 + final List rgbValuesDbl = Hsluv.hpluvToRgb([hue, 100, 70]); + // Map RBG values from 0-1 to 0-255: + final List rgbValues = rgbValuesDbl.map((rgb) => (rgb * 255).toInt()).toList(); + return Color.fromARGB(255, rgbValues[0], rgbValues[1], rgbValues[2]); } class _GeneratedFormState extends State { @@ -368,6 +369,36 @@ class _GeneratedFormState extends State { )); }) ?? [const SizedBox.shrink()], + (values[widget.items[r][e].key] + as Map>?) + ?.values + .where((e) => e.value) + .length == 1 + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: IconButton( + onPressed: () { + setState(() { + var temp = values[widget.items[r][e].key] + as Map>; + // get selected category str where bool is true + final oldEntry = temp.entries.firstWhere((entry) => entry.value.value); + // generate new color, ensure it is not the same + int newColor = oldEntry.value.key; + while(oldEntry.value.key == newColor) { + newColor = generateRandomLightColor().value; + } + // Update entry with new color, remain selected + temp.update(oldEntry.key, (old) => MapEntry(newColor, old.value)); + values[widget.items[r][e].key] = temp; + someValueChanged(); + }); + }, + icon: const Icon(Icons.format_color_fill_rounded), + visualDensity: VisualDensity.compact, + tooltip: tr('colour'), + )) + : const SizedBox.shrink(), (values[widget.items[r][e].key] as Map>?) ?.values diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index 950d2d5..2a42376 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:obtainium/components/custom_app_bar.dart'; @@ -21,21 +19,6 @@ class SettingsPage extends StatefulWidget { State createState() => _SettingsPageState(); } -// Generates a random light color -// Courtesy of ChatGPT 😭 (with a bugfix 🥳) -Color generateRandomLightColor() { - // Create a random number generator - final Random random = Random(); - - // Generate random hue, saturation, and value values - final double hue = random.nextDouble() * 360; - final double saturation = 0.5 + random.nextDouble() * 0.5; - final double value = 0.9 + random.nextDouble() * 0.1; - - // Create a HSV color with the random values - return HSVColor.fromAHSV(1.0, hue, saturation, value).toColor(); -} - class _SettingsPageState extends State { @override Widget build(BuildContext context) { diff --git a/pubspec.lock b/pubspec.lock index 8d10c85..003eae3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -326,6 +326,14 @@ packages: url: "https://pub.dev" source: hosted version: "8.2.2" + hsluv: + dependency: "direct main" + description: + name: hsluv + sha256: f33e63b0c24ceee0f6492874424aa8edc671ef9a20cc889e4b969284d8f02eb1 + url: "https://pub.dev" + source: hosted + version: "1.1.3" html: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 67cc8bf..9f785ad 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -64,7 +64,7 @@ dependencies: android_intent_plus: ^4.0.0 flutter_markdown: ^0.6.14 flutter_archive: ^5.0.0 - + hsluv: ^1.1.3 dev_dependencies: flutter_test: