cashumit/lib/widgets/dashed_border.dart

94 lines
2.3 KiB
Dart

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;
}