import 'package:fis_common/event/event_type.dart'; import 'package:fis_measure/values/colors.dart'; import 'package:fis_measure/view/cursor.dart'; import 'package:fis_measure/view/gesture/cross_position_indicator.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; abstract class ITouchPointState { Offset? get touchPosition; set touchPosition(Offset? value); Offset get touchOffset; set touchOffset(Offset value); Offset? get cursorPosition; MeasureCursorType get cursorType; set cursorType(MeasureCursorType value); double get cursorSize; set cursorSize(double value); /// 卡尺缩放比 double get cursorScaleRatio; set cursorScaleRatio(double value); late FEventHandler<Offset?> mousePositionChanged; late FEventHandler<MeasureCursorType> cursorTypeChanged; late FEventHandler<double> cursorSizeChanged; late FEventHandler<double> cursorScaleRatioChanged; late FEventHandler<CrossIndicatorStyle> crossIndicatorStyleChanged; } class TouchPointState implements ITouchPointState { Offset? _touchPosition; Offset _touchOffset = Offset.zero; double _cursorSize = 16; double _cursorScaleRatio = 1; MeasureCursorType _cursorType = MeasureCursorType.cursor01; @override var mousePositionChanged = FEventHandler<Offset?>(); @override var cursorSizeChanged = FEventHandler<double>(); @override var cursorScaleRatioChanged = FEventHandler<double>(); @override var cursorTypeChanged = FEventHandler<MeasureCursorType>(); @override var crossIndicatorStyleChanged = FEventHandler<CrossIndicatorStyle>(); @override Offset? get touchPosition => _touchPosition; @override set touchPosition(Offset? value) { if (value != _touchPosition) { _touchPosition = value; mousePositionChanged.emit(this, value); } } @override Offset get touchOffset => _touchOffset; @override set touchOffset(Offset value) { if (value != _touchOffset) { _touchOffset = value; } } @override double get cursorSize => _cursorSize; @override set cursorSize(double value) { if (value != _cursorSize) { _cursorSize = value; cursorSizeChanged.emit(this, value); } } @override double get cursorScaleRatio => _cursorScaleRatio; @override set cursorScaleRatio(double value) { if (value != _cursorScaleRatio) { _cursorScaleRatio = value; cursorScaleRatioChanged.emit(this, value); } } @override MeasureCursorType get cursorType => _cursorType; @override set cursorType(MeasureCursorType value) { if (value != _cursorType) { _cursorType = value; cursorTypeChanged.emit(this, value); } } @override Offset? get cursorPosition { if (touchPosition == null) return null; double dx = touchPosition!.dx, dy = touchPosition!.dy; final offset = cursorScaleRatio * cursorSize / 2; dx -= offset; dy -= offset; return Offset(dx, dy); } } class PositionedTouchCursor extends StatefulWidget { const PositionedTouchCursor({Key? key}) : super(key: key); @override State<StatefulWidget> createState() => _PositionedTouchCursorState(); } class _PositionedTouchCursorState extends State<PositionedTouchCursor> { final mouseState = Get.find<ITouchPointState>(); @override void initState() { mouseState.cursorSizeChanged.addListener(onCursorSizeChanged); mouseState.cursorScaleRatioChanged.addListener(onCursorScaleRatioChanged); mouseState.cursorTypeChanged.addListener(cursorTypeChanged); mouseState.mousePositionChanged.addListener(mousePositionChanged); super.initState(); } @override void dispose() { mouseState.cursorSizeChanged.removeListener(onCursorSizeChanged); mouseState.cursorScaleRatioChanged .removeListener(onCursorScaleRatioChanged); mouseState.cursorTypeChanged.removeListener(cursorTypeChanged); mouseState.mousePositionChanged.removeListener(mousePositionChanged); super.dispose(); } @override Widget build(BuildContext context) { final position = mouseState.cursorPosition; if (position == null) return Container(); return Positioned( left: position.dx, top: position.dy, child: MeasureCursor( type: mouseState.cursorType, size: mouseState.cursorSize * mouseState.cursorScaleRatio, color: MeasureColors.Primary, ), ); } void onCursorSizeChanged(Object sender, dynamic e) { onUpdate(); } void onCursorScaleRatioChanged(Object sender, dynamic e) { onUpdate(); } void cursorTypeChanged(Object sender, dynamic e) { onUpdate(); } void mousePositionChanged(Object sender, dynamic e) { onUpdate(); } void onUpdate() { setState(() {}); } }