From d2150320fae66c316968fa1a390c468b5c6a8903 Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sat, 22 Jul 2023 14:25:38 +1000 Subject: [PATCH 1/4] Add dependency: hsluv --- pubspec.lock | 8 ++++++++ pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) 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: From 852decbe7d25627c1869cbb6db03d48fbf34db5f Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sat, 22 Jul 2023 14:26:19 +1000 Subject: [PATCH 2/4] Remove redundant `generateRandomLightColor()` --- lib/pages/settings.dart | 17 ----------------- 1 file changed, 17 deletions(-) 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) { From b27bdc63c1787b88351772906838dfe82495b22b Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sat, 22 Jul 2023 14:27:48 +1000 Subject: [PATCH 3/4] Make colors more accessible Using a combination of the HSLuv (Pastel) color space and incrementing by the Golden Angle --- lib/components/generated_form.dart | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 8ab4149..761d6bc 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 { From e4b26be01f362d394b104e0aefd01c42656ca993 Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sat, 22 Jul 2023 17:46:08 +1000 Subject: [PATCH 4/4] Add color button to Category editor Prevent randomly picking the same color --- lib/components/generated_form.dart | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 761d6bc..300b679 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -369,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