126 lines
3.9 KiB
Dart
126 lines
3.9 KiB
Dart
import 'package:cc_ui_kit/cc_ui_kit.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:vibration/vibration.dart';
|
|
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
|
|
|
import '../bloc/remote_control_cubit.dart';
|
|
|
|
class RightJoystickArea extends StatefulWidget {
|
|
final bool isLocked;
|
|
final double width;
|
|
|
|
// 修复:删除重复的 key 定义
|
|
const RightJoystickArea({
|
|
super.key,
|
|
required this.isLocked,
|
|
required this.width,
|
|
});
|
|
|
|
@override
|
|
State<RightJoystickArea> createState() => _RightJoystickAreaState();
|
|
}
|
|
|
|
class _RightJoystickAreaState extends State<RightJoystickArea> {
|
|
int _lastX = 0;
|
|
bool _hasShownNoPushDialog = false; // 防止重复弹窗
|
|
|
|
/// 检查是否可以控制,不能则弹出提示
|
|
bool _checkCanControl(BuildContext context) {
|
|
final cubit = context.read<RemoteControlCubit>();
|
|
if (!cubit.isStatusPushActive()) {
|
|
if (!_hasShownNoPushDialog) {
|
|
_hasShownNoPushDialog = true;
|
|
_showNoStatusPushDialog(context);
|
|
}
|
|
return false;
|
|
}
|
|
_hasShownNoPushDialog = false;
|
|
return true;
|
|
}
|
|
|
|
/// 显示暂未收到推送的提示弹窗(小圆角)
|
|
void _showNoStatusPushDialog(BuildContext context) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (ctx) => Dialog(
|
|
backgroundColor: Colors.transparent,
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xE5333333),
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: const Text(
|
|
'暂未收到该机器的推送,不能控制',
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 14,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
// 1.5秒后自动关闭
|
|
Future.delayed(const Duration(milliseconds: 1500), () {
|
|
Navigator.of(context).pop();
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
IgnorePointer(
|
|
ignoring: widget.isLocked,
|
|
child: AnimatedOpacity(
|
|
duration: const Duration(milliseconds: 300),
|
|
opacity: widget.isLocked ? 0.3 : 1.0,
|
|
child: CCJoystick(
|
|
radius: widget.width,
|
|
axisHint: AxisHint.leftRight,
|
|
onValueChanged: (value) {
|
|
if (!_checkCanControl(context)) return;
|
|
int currentX = value.x.toInt();
|
|
if (currentX == _lastX) return;
|
|
_lastX = currentX;
|
|
|
|
int finalX = currentX.abs() < 1 ? 0 : currentX;
|
|
debugPrint('右摇杆的数据- x: $finalX, y: 0');
|
|
context.read<RemoteControlCubit>().updateOriginX(finalX);
|
|
},
|
|
onPress: () {
|
|
if (!_checkCanControl(context)) return;
|
|
_triggerVibration();
|
|
},
|
|
onPanEnd: () async {
|
|
_hasShownNoPushDialog = false; // 松手重置,下次触摸重新检查
|
|
debugPrint('🕹️ [右摇杆] 松手,强制 X=0, Y=0');
|
|
_lastX = 0;
|
|
|
|
// 🔥 使用安全方法,一次性清零双轴,确保只发送 (X=0, Y=0)
|
|
await context.read<RemoteControlCubit>().stopAllMovement();
|
|
},
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 18),
|
|
Text(
|
|
AppLocalizations.of(context).translate('remote_control.left_right'),
|
|
style: TextStyle(
|
|
color: Colors.white.withOpacity(0.5),
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
void _triggerVibration() {
|
|
Vibration.hasVibrator().then((has) {
|
|
if (has ?? false) Vibration.vibrate(duration: 12);
|
|
});
|
|
}
|
|
} |