Line data Source code
1 : // Copyright 2023 The terCAD team. All rights reserved.
2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
3 :
4 : import 'package:material_ui/material_ui.dart';
5 :
6 : class DotsIndicatorDecoration extends Decoration {
7 : final PageController controller;
8 : final int itemCount;
9 : final Color color;
10 : final double dotSize;
11 : final double _spacing;
12 :
13 1 : const DotsIndicatorDecoration({
14 : required this.controller,
15 : required this.itemCount,
16 : required this.color,
17 : required this.dotSize,
18 : double? spacing,
19 : }) : _spacing = spacing ?? dotSize;
20 :
21 1 : @override
22 : BoxPainter createBoxPainter([VoidCallback? onChanged]) {
23 1 : return _CustomTabIndicatorPainter(
24 1 : controller: controller,
25 1 : itemCount: itemCount,
26 1 : color: color,
27 1 : dotSize: dotSize,
28 1 : spacing: _spacing,
29 : onChanged: onChanged,
30 : );
31 : }
32 : }
33 :
34 : class _CustomTabIndicatorPainter extends BoxPainter {
35 : final PageController controller;
36 : final int itemCount;
37 : final Color color;
38 : final double dotSize;
39 : final double spacing;
40 :
41 1 : _CustomTabIndicatorPainter({
42 : required this.controller,
43 : required this.itemCount,
44 : required this.color,
45 : required this.dotSize,
46 : required this.spacing,
47 : VoidCallback? onChanged,
48 1 : }) : super(onChanged);
49 :
50 1 : @override
51 : void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
52 2 : if (itemCount <= 1) {
53 : return;
54 : }
55 3 : final activeIndex = controller.page?.round() ?? controller.initialPage;
56 3 : final active = Paint()..color = color;
57 4 : final inactive = Paint()..color = color.withValues(alpha: 0.3);
58 3 : for (int i = 0; i < itemCount; i++) {
59 6 : double xPos = spacing + i * (dotSize + spacing);
60 2 : double yPos = spacing * 0.6;
61 1 : if (i == activeIndex) {
62 4 : canvas.drawCircle(Offset(xPos, yPos), dotSize / 2, active);
63 : } else {
64 4 : canvas.drawCircle(Offset(xPos, yPos), dotSize / 2, inactive);
65 : }
66 : }
67 : }
68 : }
|