import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:minehunter/utils/color_extensions.dart'; class StyledButton extends StatelessWidget { const StyledButton({ super.key, required this.color, required this.onPressed, this.onLongPress, required this.child, }); final Color color; final VoidCallback? onPressed; final VoidCallback? onLongPress; final Widget child; factory StyledButton.text({ Key? key, required VoidCallback? onPressed, VoidCallback? onLongPress, required String caption, required Color color, }) { final Widget captionWidget = AutoSizeText( caption, maxLines: 1, style: TextStyle( inherit: true, fontWeight: FontWeight.w900, color: color.darken(60), shadows: [ Shadow( blurRadius: 5.0, color: color.lighten(60), offset: const Offset(2, 2), ), Shadow( blurRadius: 5.0, color: color.lighten(60), offset: const Offset(2, -2), ), Shadow( blurRadius: 5.0, color: color.lighten(60), offset: const Offset(-2, 2), ), Shadow( blurRadius: 5.0, color: color.lighten(60), offset: const Offset(-2, -2), ), ], ), ); return StyledButton( color: color, onPressed: onPressed, onLongPress: onLongPress, child: captionWidget, ); } factory StyledButton.icon({ Key? key, required VoidCallback? onPressed, VoidCallback? onLongPress, required Icon icon, required Color color, required double iconSize, }) { return StyledButton( color: color, onPressed: onPressed, onLongPress: onLongPress, child: Icon( icon.icon, color: icon.color ?? color.darken(60), size: iconSize, shadows: [ Shadow( blurRadius: 5.0, color: color.lighten(60), offset: const Offset(2, 2), ), Shadow( blurRadius: 5.0, color: color.lighten(60), offset: const Offset(2, -2), ), Shadow( blurRadius: 5.0, color: color.lighten(60), offset: const Offset(-2, 2), ), Shadow( blurRadius: 5.0, color: color.lighten(60), offset: const Offset(-2, -2), ), ], ), ); } @override Widget build(BuildContext context) { const double borderWidth = 4; final Color borderColor = color.darken(40); const double borderRadius = 10; return Container( margin: const EdgeInsets.all(2), padding: const EdgeInsets.all(2), decoration: BoxDecoration( color: color, border: Border.all( color: borderColor, width: borderWidth, ), borderRadius: BorderRadius.circular(borderRadius), ), child: CustomPaint( painter: StyledButtonPainter( baseColor: color, ), child: MaterialButton( onPressed: onPressed, onLongPress: onLongPress, padding: const EdgeInsets.all(8), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, minWidth: 40, child: child, ), ), ); } } class StyledButtonPainter extends CustomPainter { StyledButtonPainter({ required this.baseColor, }); final Color baseColor; @override void paint(Canvas canvas, Size size) { final Color lightColor = baseColor.lighten(20); final Color darkColor = baseColor.darken(20); final Paint paint = Paint()..style = PaintingStyle.fill; const double cornerRadius = 6; Path topPath = Path() ..moveTo(cornerRadius, 0) ..lineTo(size.width - cornerRadius, 0) ..arcToPoint( Offset(size.width, cornerRadius), radius: const Radius.circular(cornerRadius), ) ..lineTo(size.width, size.height * .35) ..quadraticBezierTo( size.width * .4, size.height * .1, 0, size.height * .3, ) ..lineTo(0, cornerRadius) ..arcToPoint( const Offset(cornerRadius, 0), radius: const Radius.circular(cornerRadius), ); Path bottomPath = Path() ..moveTo(cornerRadius, size.height) ..lineTo(size.width - cornerRadius, size.height) ..arcToPoint( Offset(size.width, size.height - cornerRadius), radius: const Radius.circular(cornerRadius), clockwise: false, ) ..lineTo(size.width, size.height * .7) ..quadraticBezierTo( size.width * .6, size.height * .9, 0, size.height * .7, ) ..lineTo(0, size.height - cornerRadius) ..arcToPoint( Offset(cornerRadius, size.height), radius: const Radius.circular(cornerRadius), clockwise: false, ); paint.color = lightColor; canvas.drawPath(topPath, paint); paint.color = darkColor; canvas.drawPath(bottomPath, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) => false; }