-
Notifications
You must be signed in to change notification settings - Fork 1
/
bar_signal_strength_indicator_style.dart
110 lines (93 loc) · 3.35 KB
/
bar_signal_strength_indicator_style.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import 'package:flutter/material.dart';
import 'package:signal_strength_indicator/src/style/signal_strength_indicator_style.dart';
import 'package:signal_strength_indicator/src/util.dart';
class BarSignalStrengthIndicatorStyle extends SignalStrengthIndicatorStyle {
final int barCount;
final double spacing;
final Radius radius;
final Map<num, Color> levels;
final bool bevelled;
const BarSignalStrengthIndicatorStyle({
this.barCount = 3,
this.spacing,
this.levels,
this.bevelled,
Radius radius,
num value,
num minValue,
num maxValue,
Color activeColor,
Color inactiveColor,
double size,
EdgeInsets margin,
}) : radius = radius ?? Radius.zero,
super(
value: value,
minValue: minValue,
maxValue: maxValue,
activeColor: activeColor,
inactiveColor: inactiveColor,
size: size,
margin: margin,
);
@override
CustomPainter get painter => _BarSignalStrengthIndicatorPainter(this);
}
class _BarSignalStrengthIndicatorPainter extends CustomPainter {
final BarSignalStrengthIndicatorStyle style;
const _BarSignalStrengthIndicatorPainter(this.style);
@override
void paint(Canvas canvas, Size size) {
final w = size.width;
final h = size.height;
final barCount = style.barCount;
final barWidth = w / barCount;
final spacing = style.spacing * barWidth;
final barWidthTotal = barWidth - spacing * ((barCount - 1) / barCount);
final value = normalizeValue(style.value, style.minValue, style.maxValue);
final Map<num, Color> thresholds = style.levels ?? {};
// remove thresholds where value is out of range
thresholds
.removeWhere((key, _) => key < style.minValue || key > style.maxValue);
// when there are no threshold or number of thresholds does not correspond
// with number of bars, use (create) 'default' thresholds
if (thresholds.isEmpty || thresholds.keys.length != barCount) {
thresholds.clear();
for (var i = 0; i < barCount; i++) {
thresholds.addAll({i / barCount: style.activeColor});
}
}
final keys = thresholds.keys.toList()..sort();
final key = keys.lastWhere((t) => t < value, orElse: () => keys.first);
final Paint activeBarPaint = Paint()..color = thresholds[key];
final Paint inactiveBarPaint = Paint()..color = style.inactiveColor;
// draw bars
for (var i = 1; i <= barCount; i++) {
final barHeight = h * (i / barCount);
final left = (i - 1) * (barWidthTotal + spacing);
final top = h - barHeight;
final paint = value > keys[i - 1] ? activeBarPaint : inactiveBarPaint;
Path bar;
if (style.bevelled) {
final prevBarHeight = (i == 1) ? 0 : (h * ((i - 1) / barCount));
bar = Path()
..moveTo(left, top + barHeight - prevBarHeight)
..lineTo(left + barWidthTotal, top + (spacing * 0.75))
..lineTo(left + barWidthTotal, top + barHeight)
..lineTo(left, top + barHeight)
..close();
} else {
final rrect = RRect.fromRectAndRadius(
Rect.fromLTWH(left, top, barWidthTotal, barHeight),
style.radius,
);
bar = Path()..addRRect(rrect);
}
canvas.drawPath(bar, paint);
}
}
@override
bool shouldRepaint(_BarSignalStrengthIndicatorPainter oldDelegate) {
return false;
}
}