import 'package:fis_ui/define.dart'; import 'package:flutter/material.dart'; enum MeasureCursorType { cursor01, cursor02, cursor03, cursor04, cursor05, } class MeasureCursor extends StatelessWidget implements FWidget { const MeasureCursor({ Key? key, required this.type, required this.size, this.color, }) : super(key: key); final double size; final MeasureCursorType type; final Color? color; @override Widget build(BuildContext context) { return SizedBox( width: size, height: size, child: RepaintBoundary( child: CustomPaint(painter: _CursorPainter(type, color: color)), ), ); } } class _CursorPainter extends CustomPainter { const _CursorPainter(this.type, {this.color}); final MeasureCursorType type; final Color? color; @override void paint(Canvas canvas, Size size) { final double width = size.width; final double offset = width / 2; // position center point canvas.translate(offset, offset); _CursorPathGeometry( cursorType: type, offset: offset, color: color, ).draw(canvas); } @override bool shouldRepaint(covariant _CursorPainter oldDelegate) { return oldDelegate.color != color || oldDelegate.type != type; } } class _CursorPathGeometry { _CursorPathGeometry({ required double offset, required this.cursorType, this.color, }) { _offset = offset; _paint = Paint() ..color = color ?? const Color.fromARGB(255, 255, 255, 0) ..strokeWidth = 2 ..style = PaintingStyle.stroke; _assemblePathArray(); } // ignore: constant_identifier_names static const double LINE_RATIO = 0.8; late final Paint _paint; late double _offset; final MeasureCursorType cursorType; final Color? color; final List _pathArray = []; List get pathArray => _pathArray; void draw(Canvas canvas) { canvas.save(); for (final Path path in _pathArray) { canvas.drawPath(path, _paint); } canvas.restore(); } void _assemblePathArray() { switch (cursorType) { case MeasureCursorType.cursor01: _pathArray.add(_buildHorizontalLine()); _pathArray.add(_buildVerticalLine()); break; case MeasureCursorType.cursor02: _pathArray.add(_buildLeftBias()); _pathArray.add(_buildRightBias()); break; case MeasureCursorType.cursor03: _pathArray.add(_buildHorizontalLine()); _pathArray.add(_buildLeftBias()); _pathArray.add(_buildRightBias()); break; case MeasureCursorType.cursor04: _pathArray.add(_buildVerticalLine()); _pathArray.add(_buildLeftBias()); _pathArray.add(_buildRightBias()); break; case MeasureCursorType.cursor05: _pathArray.add(_buildLeftSide()); _pathArray.add(_buildRightSide()); _pathArray.add(_buildTopSide()); _pathArray.add(_buildBottomSide()); _offset *= LINE_RATIO; _pathArray.add(_buildHorizontalLine()); _pathArray.add(_buildVerticalLine()); break; } } Path _buildHorizontalLine() { return Path() ..moveTo(-_offset, 0) ..lineTo(_offset, 0); } Path _buildVerticalLine() { return Path() ..moveTo(0, -_offset) ..lineTo(0, _offset); } Path _buildLeftBias() { return Path() ..moveTo(-_offset, -_offset) ..lineTo(_offset, _offset); } Path _buildRightBias() { return Path() ..moveTo(_offset, -_offset) ..lineTo(-_offset, _offset); } Path _buildLeftSide() { return Path() ..moveTo(-_offset, -_offset * LINE_RATIO) ..lineTo(-_offset, _offset * LINE_RATIO); } Path _buildRightSide() { return Path() ..moveTo(_offset, -_offset * LINE_RATIO) ..lineTo(_offset, _offset * LINE_RATIO); } Path _buildTopSide() { return Path() ..moveTo(-_offset * LINE_RATIO, -_offset) ..lineTo(_offset * LINE_RATIO, -_offset); } Path _buildBottomSide() { return Path() ..moveTo(-_offset * LINE_RATIO, _offset) ..lineTo(_offset * LINE_RATIO, _offset); } }