import 'package:flutter/material.dart'; /// Widget yang menggambar border putus-putus (dashed) mengelilingi child. /// Untuk tombol "template card" gaya struk. class DashedBorder extends StatelessWidget { final Widget child; final Color color; final double strokeWidth; final double dashLength; final double gapLength; final double radius; final EdgeInsets padding; const DashedBorder({ super.key, required this.child, this.color = Colors.grey, this.strokeWidth = 1.0, this.dashLength = 5.0, this.gapLength = 3.0, this.radius = 4.0, this.padding = const EdgeInsets.all(8.0), }); @override Widget build(BuildContext context) { return CustomPaint( painter: _DashedBorderPainter( color: color, strokeWidth: strokeWidth, dashLength: dashLength, gapLength: gapLength, radius: radius, ), child: Padding( padding: padding, child: child, ), ); } } class _DashedBorderPainter extends CustomPainter { final Color color; final double strokeWidth; final double dashLength; final double gapLength; final double radius; _DashedBorderPainter({ required this.color, required this.strokeWidth, required this.dashLength, required this.gapLength, required this.radius, }); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = color ..strokeWidth = strokeWidth ..style = PaintingStyle.stroke; // Bangun path rounded rect final rrect = RRect.fromRectAndRadius( Offset.zero & size, Radius.circular(radius), ); // Gunakan PathMetric untuk dash effect pada rounded rect final path = Path()..addRRect(rrect); final metrics = path.computeMetrics(); for (final metric in metrics) { double distance = 0; while (distance < metric.length) { final next = distance + dashLength; final extract = metric.extractPath(distance, next); canvas.drawPath(extract, paint); distance = next + gapLength; } } } @override bool shouldRepaint(covariant _DashedBorderPainter oldDelegate) => color != oldDelegate.color || strokeWidth != oldDelegate.strokeWidth || dashLength != oldDelegate.dashLength || gapLength != oldDelegate.gapLength || radius != oldDelegate.radius; }