From 7f4aac2ca72caf13b63ec72bc36cf1f83b4ac270 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sat, 19 Aug 2023 23:09:19 +0200 Subject: [PATCH] fixed donut colors in monochrome mode --- lib/theme/colors.dart | 14 +- lib/widgets/about/data_usage.dart | 4 +- lib/widgets/common/identity/aves_donut.dart | 192 ++++++++++---------- lib/widgets/stats/mime_donut.dart | 6 +- 4 files changed, 114 insertions(+), 102 deletions(-) diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 95ec57532..c57ed4b1b 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -18,10 +18,12 @@ class AColors { } class AvesColorsProvider extends StatelessWidget { + final bool allowMonochrome; final Widget child; const AvesColorsProvider({ super.key, + this.allowMonochrome = true, required this.child, }); @@ -30,12 +32,14 @@ class AvesColorsProvider extends StatelessWidget { return ProxyProvider( update: (context, settings, __) { final isDark = Theme.of(context).brightness == Brightness.dark; - switch (settings.themeColorMode) { - case AvesThemeColorMode.monochrome: - return isDark ? _MonochromeOnDark() : _MonochromeOnLight(); - case AvesThemeColorMode.polychrome: - return isDark ? NeonOnDark() : PastelOnLight(); + var mode = settings.themeColorMode; + if (!allowMonochrome && mode == AvesThemeColorMode.monochrome) { + mode = AvesThemeColorMode.polychrome; } + return switch (mode) { + AvesThemeColorMode.monochrome => isDark ? _MonochromeOnDark() : _MonochromeOnLight(), + AvesThemeColorMode.polychrome => isDark ? NeonOnDark() : PastelOnLight(), + }; }, child: child, ); diff --git a/lib/widgets/about/data_usage.dart b/lib/widgets/about/data_usage.dart index 3d7beeea7..a522355cc 100644 --- a/lib/widgets/about/data_usage.dart +++ b/lib/widgets/about/data_usage.dart @@ -121,7 +121,6 @@ class DataUsageDonut extends StatelessWidget { Widget build(BuildContext context) { final l10n = context.l10n; final locale = l10n.localeName; - final colors = context.watch(); return AvesDonut( title: Text(title), @@ -148,7 +147,8 @@ class DataUsageDonut extends StatelessWidget { } }, formatValue: (v) => formatFileSize(locale, v, round: 0), - colorize: (d) { + colorize: (context, d) { + final colors = context.read(); Color? color; switch (d.key) { case flutter: diff --git a/lib/widgets/common/identity/aves_donut.dart b/lib/widgets/common/identity/aves_donut.dart index 46f7f9208..ab587a730 100644 --- a/lib/widgets/common/identity/aves_donut.dart +++ b/lib/widgets/common/identity/aves_donut.dart @@ -2,6 +2,7 @@ import 'dart:math'; import 'package:aves/model/settings/enums/accessibility_animations.dart'; import 'package:aves/model/settings/settings.dart'; +import 'package:aves/theme/colors.dart'; import 'package:aves/theme/icons.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:collection/collection.dart'; @@ -11,7 +12,7 @@ import 'package:provider/provider.dart'; typedef DatumKeyFormatter = String Function(AvesDonutDatum d); typedef DatumValueFormatter = String Function(int d); -typedef DatumColorizer = Color Function(AvesDonutDatum d); +typedef DatumColorizer = Color Function(BuildContext context, AvesDonutDatum d); typedef DatumCallback = void Function(AvesDonutDatum d); class AvesDonut extends StatefulWidget { @@ -69,102 +70,107 @@ class _AvesDonutState extends State with AutomaticKeepAliveClientMixi return c != 0 ? c : compareAsciiUpperCase(formatKey(d1), formatKey(d2)); }); - final series = [ - charts.Series( - id: 'type', - colorFn: (d, i) => charts.ColorUtil.fromDartColor(colorize(d)), - domainFn: (d, i) => formatKey(d), - measureFn: (d, i) => d.value, - data: seriesData, - labelAccessorFn: (d, _) => '${formatKey(d)}: ${d.value}', - ), - ]; - - return LayoutBuilder(builder: (context, constraints) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final minWidth = avesDonutMinWidth * textScaleFactor; - final availableWidth = constraints.maxWidth; - final dim = max(minWidth, availableWidth / (availableWidth > 4 * minWidth ? 4 : (availableWidth > 2 * minWidth ? 2 : 1))); - - final donut = SizedBox( - width: dim, - height: dim, - child: Stack( - children: [ - charts.PieChart( - series, - animate: context.select((v) => v.accessibilityAnimations.animate), - animationDuration: widget.animationDuration, - defaultRenderer: charts.ArcRendererConfig( - arcWidth: 16, - ), + return AvesColorsProvider( + allowMonochrome: false, + child: LayoutBuilder( + builder: (context, constraints) { + final series = [ + charts.Series( + id: 'type', + colorFn: (d, i) => charts.ColorUtil.fromDartColor(colorize(context, d)), + domainFn: (d, i) => formatKey(d), + measureFn: (d, i) => d.value, + data: seriesData, + labelAccessorFn: (d, _) => '${formatKey(d)}: ${d.value}', ), - Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - widget.title, - Text( - formatValue(sum), - textAlign: TextAlign.center, + ]; + + final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final minWidth = avesDonutMinWidth * textScaleFactor; + final availableWidth = constraints.maxWidth; + final dim = max(minWidth, availableWidth / (availableWidth > 4 * minWidth ? 4 : (availableWidth > 2 * minWidth ? 2 : 1))); + + final donut = SizedBox( + width: dim, + height: dim, + child: Stack( + children: [ + charts.PieChart( + series, + animate: context.select((v) => v.accessibilityAnimations.animate), + animationDuration: widget.animationDuration, + defaultRenderer: charts.ArcRendererConfig( + arcWidth: 16, ), - ], - ), + ), + Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + widget.title, + Text( + formatValue(sum), + textAlign: TextAlign.center, + ), + ], + ), + ), + ], ), - ], - ), - ); - final onTap = widget.onTap; - final legend = SizedBox( - width: dim, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: seriesData - .map((d) => InkWell( - onTap: onTap != null ? () => onTap(d) : null, - borderRadius: const BorderRadius.all(Radius.circular(123)), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(AIcons.disc, color: colorize(d)), - const SizedBox(width: 8), - Flexible( - child: Text( - formatKey(d), - overflow: TextOverflow.fade, - softWrap: false, - maxLines: 1, - ), + ); + final onTap = widget.onTap; + final legend = SizedBox( + width: dim, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: seriesData + .map((d) => InkWell( + onTap: onTap != null ? () => onTap(d) : null, + borderRadius: const BorderRadius.all(Radius.circular(123)), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(AIcons.disc, color: colorize(context, d)), + const SizedBox(width: 8), + Flexible( + child: Text( + formatKey(d), + overflow: TextOverflow.fade, + softWrap: false, + maxLines: 1, + ), + ), + const SizedBox(width: 8), + Text( + formatValue(d.value), + style: TextStyle( + color: Theme.of(context).textTheme.bodySmall!.color, + ), + ), + const SizedBox(width: 4), + ], ), - const SizedBox(width: 8), - Text( - formatValue(d.value), - style: TextStyle( - color: Theme.of(context).textTheme.bodySmall!.color, - ), - ), - const SizedBox(width: 4), - ], - ), - )) - .toList(), - ), - ); - final children = [ - donut, - legend, - ]; - return availableWidth > minWidth * 2 - ? Row( - mainAxisSize: MainAxisSize.min, - children: children, - ) - : Column( - mainAxisSize: MainAxisSize.min, - children: children, - ); - }); + )) + .toList(), + ), + ); + final children = [ + donut, + legend, + ]; + return availableWidth > minWidth * 2 + ? Row( + mainAxisSize: MainAxisSize.min, + children: children, + ) + : Column( + mainAxisSize: MainAxisSize.min, + children: children, + ); + }, + ), + ); } @override diff --git a/lib/widgets/stats/mime_donut.dart b/lib/widgets/stats/mime_donut.dart index 0c2de30e4..4e0fdc4a5 100644 --- a/lib/widgets/stats/mime_donut.dart +++ b/lib/widgets/stats/mime_donut.dart @@ -26,7 +26,6 @@ class MimeDonut extends StatelessWidget { Widget build(BuildContext context) { final locale = context.l10n.localeName; final numberFormat = NumberFormat.decimalPattern(locale); - final colors = context.watch(); String formatKey(d) => MimeUtils.displayType(d.key); return AvesDonut( @@ -35,7 +34,10 @@ class MimeDonut extends StatelessWidget { animationDuration: animationDuration, formatKey: formatKey, formatValue: numberFormat.format, - colorize: (d) => colors.fromString(formatKey(d)), + colorize: (context, d) { + final colors = context.read(); + return colors.fromString(formatKey(d)); + }, onTap: (d) => onFilterSelection(MimeFilter(d.key)), ); }