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 IMouseState { Offset? get mousePosition; set mousePosition(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 mousePositionChanged; late FEventHandler cursorTypeChanged; late FEventHandler cursorSizeChanged; late FEventHandler cursorScaleRatioChanged; late FEventHandler crossIndicatorStyleChanged; } class MouseState implements IMouseState { Offset? _mousePosition; double _cursorSize = 16; double _cursorScaleRatio = 1; MeasureCursorType _cursorType = MeasureCursorType.cursor01; @override var mousePositionChanged = FEventHandler(); @override var cursorSizeChanged = FEventHandler(); @override var cursorScaleRatioChanged = FEventHandler(); @override var cursorTypeChanged = FEventHandler(); @override var crossIndicatorStyleChanged = FEventHandler(); @override Offset? get mousePosition => _mousePosition; @override set mousePosition(Offset? value) { if (value != _mousePosition) { _mousePosition = value; mousePositionChanged.emit(this, 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 (mousePosition == null) return null; double dx = mousePosition!.dx, dy = mousePosition!.dy; final offset = cursorScaleRatio * cursorSize / 2; dx -= offset; dy -= offset; return Offset(dx, dy); } } class PositionedCursor extends StatefulWidget { const PositionedCursor({Key? key}) : super(key: key); @override State createState() => _PositionedCursorState(); } class _PositionedCursorState extends State { final mouseState = Get.find(); @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(() {}); } }