fixed donut colors in monochrome mode

This commit is contained in:
Thibault Deckers 2023-08-19 23:09:19 +02:00
parent ca6ff7550c
commit 7f4aac2ca7
4 changed files with 114 additions and 102 deletions

View file

@ -18,10 +18,12 @@ class AColors {
} }
class AvesColorsProvider extends StatelessWidget { class AvesColorsProvider extends StatelessWidget {
final bool allowMonochrome;
final Widget child; final Widget child;
const AvesColorsProvider({ const AvesColorsProvider({
super.key, super.key,
this.allowMonochrome = true,
required this.child, required this.child,
}); });
@ -30,12 +32,14 @@ class AvesColorsProvider extends StatelessWidget {
return ProxyProvider<Settings, AvesColorsData>( return ProxyProvider<Settings, AvesColorsData>(
update: (context, settings, __) { update: (context, settings, __) {
final isDark = Theme.of(context).brightness == Brightness.dark; final isDark = Theme.of(context).brightness == Brightness.dark;
switch (settings.themeColorMode) { var mode = settings.themeColorMode;
case AvesThemeColorMode.monochrome: if (!allowMonochrome && mode == AvesThemeColorMode.monochrome) {
return isDark ? _MonochromeOnDark() : _MonochromeOnLight(); mode = AvesThemeColorMode.polychrome;
case AvesThemeColorMode.polychrome:
return isDark ? NeonOnDark() : PastelOnLight();
} }
return switch (mode) {
AvesThemeColorMode.monochrome => isDark ? _MonochromeOnDark() : _MonochromeOnLight(),
AvesThemeColorMode.polychrome => isDark ? NeonOnDark() : PastelOnLight(),
};
}, },
child: child, child: child,
); );

View file

@ -121,7 +121,6 @@ class DataUsageDonut extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = context.l10n; final l10n = context.l10n;
final locale = l10n.localeName; final locale = l10n.localeName;
final colors = context.watch<AvesColorsData>();
return AvesDonut( return AvesDonut(
title: Text(title), title: Text(title),
@ -148,7 +147,8 @@ class DataUsageDonut extends StatelessWidget {
} }
}, },
formatValue: (v) => formatFileSize(locale, v, round: 0), formatValue: (v) => formatFileSize(locale, v, round: 0),
colorize: (d) { colorize: (context, d) {
final colors = context.read<AvesColorsData>();
Color? color; Color? color;
switch (d.key) { switch (d.key) {
case flutter: case flutter:

View file

@ -2,6 +2,7 @@ import 'dart:math';
import 'package:aves/model/settings/enums/accessibility_animations.dart'; import 'package:aves/model/settings/enums/accessibility_animations.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/colors.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:charts_flutter/flutter.dart' as charts; import 'package:charts_flutter/flutter.dart' as charts;
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
@ -11,7 +12,7 @@ import 'package:provider/provider.dart';
typedef DatumKeyFormatter = String Function(AvesDonutDatum d); typedef DatumKeyFormatter = String Function(AvesDonutDatum d);
typedef DatumValueFormatter = String Function(int 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); typedef DatumCallback = void Function(AvesDonutDatum d);
class AvesDonut extends StatefulWidget { class AvesDonut extends StatefulWidget {
@ -69,102 +70,107 @@ class _AvesDonutState extends State<AvesDonut> with AutomaticKeepAliveClientMixi
return c != 0 ? c : compareAsciiUpperCase(formatKey(d1), formatKey(d2)); return c != 0 ? c : compareAsciiUpperCase(formatKey(d1), formatKey(d2));
}); });
final series = [ return AvesColorsProvider(
charts.Series<AvesDonutDatum, String>( allowMonochrome: false,
id: 'type', child: LayoutBuilder(
colorFn: (d, i) => charts.ColorUtil.fromDartColor(colorize(d)), builder: (context, constraints) {
domainFn: (d, i) => formatKey(d), final series = [
measureFn: (d, i) => d.value, charts.Series<AvesDonutDatum, String>(
data: seriesData, id: 'type',
labelAccessorFn: (d, _) => '${formatKey(d)}: ${d.value}', colorFn: (d, i) => charts.ColorUtil.fromDartColor(colorize(context, d)),
), domainFn: (d, i) => formatKey(d),
]; measureFn: (d, i) => d.value,
data: seriesData,
return LayoutBuilder(builder: (context, constraints) { labelAccessorFn: (d, _) => '${formatKey(d)}: ${d.value}',
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<Settings, bool>((v) => v.accessibilityAnimations.animate),
animationDuration: widget.animationDuration,
defaultRenderer: charts.ArcRendererConfig<String>(
arcWidth: 16,
),
), ),
Center( ];
child: Column(
mainAxisSize: MainAxisSize.min, final textScaleFactor = MediaQuery.textScaleFactorOf(context);
children: [ final minWidth = avesDonutMinWidth * textScaleFactor;
widget.title, final availableWidth = constraints.maxWidth;
Text( final dim = max(minWidth, availableWidth / (availableWidth > 4 * minWidth ? 4 : (availableWidth > 2 * minWidth ? 2 : 1)));
formatValue(sum),
textAlign: TextAlign.center, final donut = SizedBox(
width: dim,
height: dim,
child: Stack(
children: [
charts.PieChart(
series,
animate: context.select<Settings, bool>((v) => v.accessibilityAnimations.animate),
animationDuration: widget.animationDuration,
defaultRenderer: charts.ArcRendererConfig<String>(
arcWidth: 16,
), ),
], ),
), Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
widget.title,
Text(
formatValue(sum),
textAlign: TextAlign.center,
),
],
),
),
],
), ),
], );
), final onTap = widget.onTap;
); final legend = SizedBox(
final onTap = widget.onTap; width: dim,
final legend = SizedBox( child: Column(
width: dim, mainAxisAlignment: MainAxisAlignment.center,
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, children: seriesData
crossAxisAlignment: CrossAxisAlignment.start, .map((d) => InkWell(
children: seriesData onTap: onTap != null ? () => onTap(d) : null,
.map((d) => InkWell( borderRadius: const BorderRadius.all(Radius.circular(123)),
onTap: onTap != null ? () => onTap(d) : null, child: Row(
borderRadius: const BorderRadius.all(Radius.circular(123)), mainAxisSize: MainAxisSize.min,
child: Row( children: [
mainAxisSize: MainAxisSize.min, Icon(AIcons.disc, color: colorize(context, d)),
children: [ const SizedBox(width: 8),
Icon(AIcons.disc, color: colorize(d)), Flexible(
const SizedBox(width: 8), child: Text(
Flexible( formatKey(d),
child: Text( overflow: TextOverflow.fade,
formatKey(d), softWrap: false,
overflow: TextOverflow.fade, maxLines: 1,
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( .toList(),
formatValue(d.value), ),
style: TextStyle( );
color: Theme.of(context).textTheme.bodySmall!.color, final children = [
), donut,
), legend,
const SizedBox(width: 4), ];
], return availableWidth > minWidth * 2
), ? Row(
)) mainAxisSize: MainAxisSize.min,
.toList(), children: children,
), )
); : Column(
final children = [ mainAxisSize: MainAxisSize.min,
donut, children: children,
legend, );
]; },
return availableWidth > minWidth * 2 ),
? Row( );
mainAxisSize: MainAxisSize.min,
children: children,
)
: Column(
mainAxisSize: MainAxisSize.min,
children: children,
);
});
} }
@override @override

View file

@ -26,7 +26,6 @@ class MimeDonut extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName; final locale = context.l10n.localeName;
final numberFormat = NumberFormat.decimalPattern(locale); final numberFormat = NumberFormat.decimalPattern(locale);
final colors = context.watch<AvesColorsData>();
String formatKey(d) => MimeUtils.displayType(d.key); String formatKey(d) => MimeUtils.displayType(d.key);
return AvesDonut( return AvesDonut(
@ -35,7 +34,10 @@ class MimeDonut extends StatelessWidget {
animationDuration: animationDuration, animationDuration: animationDuration,
formatKey: formatKey, formatKey: formatKey,
formatValue: numberFormat.format, formatValue: numberFormat.format,
colorize: (d) => colors.fromString(formatKey(d)), colorize: (context, d) {
final colors = context.read<AvesColorsData>();
return colors.fromString(formatKey(d));
},
onTap: (d) => onFilterSelection(MimeFilter(d.key)), onTap: (d) => onFilterSelection(MimeFilter(d.key)),
); );
} }