92 lines
2.2 KiB
Dart
92 lines
2.2 KiB
Dart
/// Overlays a highlight on the receipt photo for a parsed line item.
|
|
library;
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import '../models/receipt_bounds.dart';
|
|
|
|
class ReceiptHighlightOverlay extends StatelessWidget {
|
|
const ReceiptHighlightOverlay({
|
|
super.key,
|
|
required this.imagePath,
|
|
required this.bounds,
|
|
this.maxHeight = 280,
|
|
});
|
|
|
|
final String imagePath;
|
|
final ReceiptBounds bounds;
|
|
final double maxHeight;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final scheme = Theme.of(context).colorScheme;
|
|
return ClipRRect(
|
|
borderRadius: BorderRadius.circular(12),
|
|
child: LayoutBuilder(
|
|
builder: (context, constraints) {
|
|
return Stack(
|
|
fit: StackFit.passthrough,
|
|
children: [
|
|
Image.file(
|
|
File(imagePath),
|
|
fit: BoxFit.contain,
|
|
height: maxHeight,
|
|
width: constraints.maxWidth,
|
|
),
|
|
Positioned.fill(
|
|
child: CustomPaint(
|
|
painter: _BoundsPainter(
|
|
bounds: bounds,
|
|
color: scheme.primary.withValues(alpha: 0.35),
|
|
stroke: scheme.primary,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _BoundsPainter extends CustomPainter {
|
|
_BoundsPainter({
|
|
required this.bounds,
|
|
required this.color,
|
|
required this.stroke,
|
|
});
|
|
|
|
final ReceiptBounds bounds;
|
|
final Color color;
|
|
final Color stroke;
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
if (bounds.isEmpty) return;
|
|
final rect = Rect.fromLTRB(
|
|
bounds.left * size.width,
|
|
bounds.top * size.height,
|
|
bounds.right * size.width,
|
|
bounds.bottom * size.height,
|
|
);
|
|
canvas.drawRect(rect, Paint()..color = color);
|
|
canvas.drawRect(
|
|
rect,
|
|
Paint()
|
|
..color = stroke
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = 2,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(covariant _BoundsPainter oldDelegate) {
|
|
return oldDelegate.bounds != bounds ||
|
|
oldDelegate.color != color ||
|
|
oldDelegate.stroke != stroke;
|
|
}
|
|
}
|