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 {
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<Settings, AvesColorsData>(
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,
);

View file

@ -121,7 +121,6 @@ class DataUsageDonut extends StatelessWidget {
Widget build(BuildContext context) {
final l10n = context.l10n;
final locale = l10n.localeName;
final colors = context.watch<AvesColorsData>();
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<AvesColorsData>();
Color? color;
switch (d.key) {
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/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<AvesDonut> with AutomaticKeepAliveClientMixi
return c != 0 ? c : compareAsciiUpperCase(formatKey(d1), formatKey(d2));
});
final series = [
charts.Series<AvesDonutDatum, String>(
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<Settings, bool>((v) => v.accessibilityAnimations.animate),
animationDuration: widget.animationDuration,
defaultRenderer: charts.ArcRendererConfig<String>(
arcWidth: 16,
),
return AvesColorsProvider(
allowMonochrome: false,
child: LayoutBuilder(
builder: (context, constraints) {
final series = [
charts.Series<AvesDonutDatum, String>(
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<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(
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

View file

@ -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<AvesColorsData>();
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<AvesColorsData>();
return colors.fromString(formatKey(d));
},
onTap: (d) => onFilterSelection(MimeFilter(d.key)),
);
}