123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- import 'dart:async';
- import 'package:fis_i18n/i18n.dart';
- import 'package:fis_measure/interfaces/process/items/item.dart';
- import 'package:fis_measure/interfaces/process/workspace/application.dart';
- import 'package:fis_measure/process/items/top_item.dart';
- import 'package:fis_measure/process/workspace/application.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:get/get.dart';
- class FineTunePanel extends StatefulWidget {
- final Size panelSize;
- const FineTunePanel({
- Key? key,
- this.panelSize = const Size(150, 150),
- }) : super(key: key);
- @override
- State<StatefulWidget> createState() => _FineTunePanelState();
- }
- class _FineTunePanelState extends State<FineTunePanel> {
- Application application = Get.find<IApplication>() as Application;
- final GlobalKey _magnifierKey = GlobalKey();
- double arrowButtonSize = 50;
- Offset containerPos = const Offset(0, 0);
- Size containerSize = const Size(0, 0);
- bool ifShowPanel = false;
- bool ifSetTop = false; //是否置于顶部
- static const double fineTuneStep = 0.001;
- bool isCombined = false;
- Timer? _timer;
- IMeasureItem? get _currWorkingItem => isCombined
- ? (application.activeMeasureItem as TopMeasureItem).workingChild
- : application.activeMeasureItem;
- @override
- void initState() {
- arrowButtonSize = widget.panelSize.width / 2.5;
- application.mobileTouchEndEvent.addListener(_onMobileTouchEndEvent);
- application.mobileTouchEvent.addListener(_onMobileTouchEvent);
- application.activeMeasureItemChanged
- .addListener(_onActiveMeasureItemChanged);
- WidgetsBinding.instance.addPostFrameCallback((_) => {
- _initContainerParam(),
- });
- super.initState();
- }
- @override
- void dispose() {
- application.mobileTouchEndEvent.removeListener(_onMobileTouchEndEvent);
- application.mobileTouchEvent.removeListener(_onMobileTouchEvent);
- application.activeMeasureItemChanged
- .removeListener(_onActiveMeasureItemChanged);
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return Row(
- children: [
- Column(
- mainAxisAlignment:
- ifSetTop ? MainAxisAlignment.start : MainAxisAlignment.end,
- children: [
- if (ifShowPanel)
- Opacity(
- opacity: 0.7,
- child: Container(
- margin: EdgeInsets.only(
- left: 20,
- right: 20,
- top: ifSetTop ? 20 : 0,
- bottom: ifSetTop ? 0 : 20,
- ),
- decoration: BoxDecoration(
- border: Border.all(color: Colors.white, width: 2),
- borderRadius: BorderRadius.circular(10),
- color: Colors.black.withOpacity(0.8)),
- child: Column(
- children: [
- Container(
- decoration: BoxDecoration(
- color: const Color.fromARGB(255, 53, 53, 53)
- .withOpacity(0.8),
- borderRadius: const BorderRadius.only(
- topLeft: Radius.circular(8),
- topRight: Radius.circular(8),
- )),
- width: widget.panelSize.width,
- child: Padding(
- padding: const EdgeInsets.all(3.0),
- child: Text(
- i18nBook.measure.fineTuneStartPoint.t,
- style: const TextStyle(
- color: Colors.white, fontSize: 14),
- textAlign: TextAlign.center,
- ),
- ),
- ),
- Container(
- height: 2,
- width: widget.panelSize.width,
- color: Colors.white,
- ),
- SizedBox(
- key: _magnifierKey,
- width: widget.panelSize.width,
- height: widget.panelSize.height,
- child: Stack(
- children: [
- _buildFineTuneButton(
- Alignment.centerLeft,
- Icons.arrow_circle_left_outlined,
- const Offset(-1 * fineTuneStep, 0)),
- _buildFineTuneButton(
- Alignment.topCenter,
- Icons.arrow_circle_up_outlined,
- const Offset(0, -1 * fineTuneStep)),
- _buildFineTuneButton(
- Alignment.centerRight,
- Icons.arrow_circle_right_outlined,
- const Offset(fineTuneStep, 0)),
- _buildFineTuneButton(
- Alignment.bottomCenter,
- Icons.arrow_circle_down_outlined,
- const Offset(0, fineTuneStep)),
- ],
- ),
- ),
- ],
- ),
- ),
- ),
- ],
- ),
- ],
- );
- }
- Align _buildFineTuneButton(
- Alignment alignment, IconData icon, Offset offset) {
- return Align(
- alignment: alignment,
- child: GestureDetector(
- onTapDown: (e) {
- _onTapFineTuneButton(offset);
- },
- onLongPress: () {
- _startLongPressTimer(offset);
- },
- onLongPressUp: () {
- _stopLongPressTimer();
- },
- child: Icon(
- icon,
- color: Colors.white,
- size: arrowButtonSize,
- ),
- ),
- );
- }
- void _initContainerParam() {
- final containerLayer = context.findRenderObject() as RenderBox;
- containerPos = containerLayer.localToGlobal(Offset.zero);
- containerSize = containerLayer.size;
- }
- void _updateAlignment(Offset touchPos) {
- if (touchPos.dx < widget.panelSize.width) {
- if (ifSetTop && (touchPos.dy < containerSize.height / 2)) {
- setState(() {
- ifSetTop = false;
- });
- } else if (!ifSetTop && (touchPos.dy > containerSize.height / 2)) {
- setState(() {
- ifSetTop = true;
- });
- }
- } else if (ifSetTop) {
- setState(() {
- ifSetTop = false;
- });
- }
- }
- void _onMobileTouchEndEvent(_, Offset offset) {
- isCombined = false;
- if (_currWorkingItem?.feature != null) {
- int pointsNum = 0;
- pointsNum =
- _currWorkingItem?.feature!.innerPoints.toSet().toList().length ?? 0;
- if (pointsNum == 1) {
- setState(() {
- ifShowPanel = true;
- });
- Offset startPoint = application
- .activeMeasureItem!.feature!.innerPoints[0]
- .toOffset()
- .scale(containerSize.width, containerSize.height);
- _updateAlignment(startPoint);
- return;
- }
- if (application.activeMeasureItem is TopMeasureItem) {
- isCombined = true;
- if (_currWorkingItem?.feature != null) {
- pointsNum =
- _currWorkingItem!.feature!.innerPoints.toSet().toList().length;
- if (pointsNum == 1) {
- setState(() {
- ifShowPanel = true;
- });
- Offset startPoint = _currWorkingItem!.feature!.innerPoints[0]
- .toOffset()
- .scale(containerSize.width, containerSize.height);
- _updateAlignment(startPoint);
- return;
- }
- }
- }
- }
- setState(() {
- ifShowPanel = false;
- });
- }
- void _onMobileTouchEvent(_, Offset offset) {
- if (!ifShowPanel) return;
- setState(() {
- ifShowPanel = false;
- });
- }
- void _onActiveMeasureItemChanged(_, IMeasureItem? item) {
- if (!ifShowPanel) return;
- setState(() {
- ifShowPanel = false;
- });
- }
- void _onTapFineTuneButton(Offset offset) {
- if (_currWorkingItem?.feature != null) {
- HapticFeedback.lightImpact();
- _currWorkingItem?.update();
- int pointsNum = 0;
- pointsNum = _currWorkingItem?.feature!.innerPoints.length ?? 0;
- if (pointsNum > 0) {
- for (int i = 0; i < pointsNum; i++) {
- _currWorkingItem?.feature!.innerPoints[i]
- .addOffset(offset.dx, offset.dy);
- }
- }
- }
- }
- /// 开启长按定时器
- void _startLongPressTimer(Offset offset) {
- /// 随着触发次数的增多,触发的距离越来越长
- int fineTuneTimes = 0;
- _timer = Timer.periodic(const Duration(milliseconds: 50), (timer) {
- fineTuneTimes++;
- final scale = (1 + fineTuneTimes * 0.1).truncate().toDouble();
- _onTapFineTuneButton(offset.scale(scale, scale));
- });
- }
- void _stopLongPressTimer() {
- if (_timer != null) {
- _timer!.cancel();
- _timer = null;
- }
- }
- }
|