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:flutter/material.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.withOpacity(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 : }