完成远程控制页面中点火和熄火的长按选中类别的操作

完成远程控制页面中割刀的长按选中类别的操作
This commit is contained in:
2026-03-17 16:10:40 +08:00
parent f31a20f1d9
commit 68a45ee487
7 changed files with 204 additions and 55 deletions

1
assets/svgs/fire.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-flame-icon lucide-flame"><path d="M12 3q1 4 4 6.5t3 5.5a1 1 0 0 1-14 0 5 5 0 0 1 1-3 1 1 0 0 0 5 0c0-2-1.5-3-1.5-5q0-2 2.5-4"/></svg>

After

Width:  |  Height:  |  Size: 335 B

View File

@@ -1 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-flame-icon lucide-flame"><path d="M12 3q1 4 4 6.5t3 5.5a1 1 0 0 1-14 0 5 5 0 0 1 1-3 1 1 0 0 0 5 0c0-2-1.5-3-1.5-5q0-2 2.5-4"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-flame-icon lucide-flame">
<!-- 绕中心逆时针旋转90°(向左转),中心点12,12适配24x24画布 -->
<g transform="rotate(-90 12 12)">
<path d="M12 3q1 4 4 6.5t3 5.5a1 1 0 0 1-14 0 5 5 0 0 1 1-3 1 1 0 0 0 5 0c0-2-1.5-3-1.5-5q0-2 2.5-4"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 335 B

After

Width:  |  Height:  |  Size: 483 B

View File

@@ -2,24 +2,26 @@
width="24"
height="24"
viewBox="0 0 24 24">
<!-- 核心修改:rotate(-90 12 12) 表示绕中心逆时针旋转90°(向左转) -->
<g transform="rotate(-90 12 12)">
<!-- 原有火焰主体图形 -->
<path
d="M12 3
q1 4 4 6.5
t3 5.5
a1 1 0 0 1 -14 0
a5 5 0 0 1 1 -3
a1 1 0 0 0 5 0
c0 -2 -1.5 -3 -1.5 -5
q0 -2 2.5 -4"
fill="black"/>
<!-- 原来的主体图形 -->
<path
d="M12 3
q1 4 4 6.5
t3 5.5
a1 1 0 0 1 -14 0
a5 5 0 0 1 1 -3
a1 1 0 0 0 5 0
c0 -2 -1.5 -3 -1.5 -5
q0 -2 2.5 -4"
fill="black"/>
<!-- 右上角水平减号 -->
<path
d="M16 4 L20 4"
stroke="black"
stroke-width="2"
fill="none"
stroke-linecap="round"/>
</svg>
<!-- 右上角水平减号(旋转后适配水平滑块) -->
<path
d="M16 4 L20 4"
stroke="black"
stroke-width="2"
fill="none"
stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 511 B

After

Width:  |  Height:  |  Size: 760 B

View File

@@ -2,32 +2,34 @@
width="24"
height="24"
viewBox="0 0 24 24">
<!-- 核心:绕中心逆时针旋转90°(向左转),中心点12,12适配24x24画布 -->
<g transform="rotate(-90 12 12)">
<!-- 原来的火焰主体图形 -->
<path
d="M12 3
q1 4 4 6.5
t3 5.5
a1 1 0 0 1 -14 0
a5 5 0 0 1 1 -3
a1 1 0 0 0 5 0
c0 -2 -1.5 -3 -1.5 -5
q0 -2 2.5 -4"
fill="black"/>
<!-- 原来的主体图形 -->
<path
d="M12 3
q1 4 4 6.5
t3 5.5
a1 1 0 0 1 -14 0
a5 5 0 0 1 1 -3
a1 1 0 0 0 5 0
c0 -2 -1.5 -3 -1.5 -5
q0 -2 2.5 -4"
fill="black"/>
<!-- 右上角加号:水平线 -->
<path
d="M16 4 L20 4"
stroke="black"
stroke-width="2"
fill="none"
stroke-linecap="round"/>
<!-- 右上角加号:水平线 -->
<path
d="M16 4 L20 4"
stroke="black"
stroke-width="2"
fill="none"
stroke-linecap="round"/>
<!-- 右上角加号:垂直线 -->
<path
d="M18 2 L18 6"
stroke="black"
stroke-width="2"
fill="none"
stroke-linecap="round"/>
</svg>
<!-- 右上角加号:垂直线 -->
<path
d="M18 2 L18 6"
stroke="black"
stroke-width="2"
fill="none"
stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 694 B

After

Width:  |  Height:  |  Size: 945 B

1
assets/svgs/scissors.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scissors-icon lucide-scissors"><circle cx="6" cy="6" r="3"/><path d="M8.12 8.12 12 12"/><path d="M20 4 8.12 15.88"/><circle cx="6" cy="18" r="3"/><path d="M14.8 14.8 20 20"/></svg>

After

Width:  |  Height:  |  Size: 382 B

View File

@@ -40,7 +40,7 @@ class CenterControlArea extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildSliderBox(expandedWidth, "底盘", true),
_buildSliderBox(expandedWidth, "底盘", true,context),
SizedBox(height: totalWidth * 0.01),
],
),
@@ -70,7 +70,7 @@ class CenterControlArea extends StatelessWidget {
width: expandedWidth,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [_buildSliderBox(expandedWidth, "割刀", false)],
children: [_buildSliderBox(expandedWidth, "割刀", false,context)],
),
),
],
@@ -80,7 +80,7 @@ class CenterControlArea extends StatelessWidget {
);
}
Widget _buildSliderBox(double boxWidth, String label, bool isLeft) {
Widget _buildSliderBox(double boxWidth, String label, bool isLeft,BuildContext context) {
return SizedBox(
width: boxWidth,
child: Center(
@@ -90,10 +90,14 @@ class CenterControlArea extends StatelessWidget {
child: CCExpandSlider(
label: label,
svgStart: "assets/svgs/remote_up.svg",
svgCenter: "assets/svgs/remote_layers.svg",
svgCenter: switch (label) {
"割刀" => "assets/svgs/remote_scissors.svg",
"底盘" => "assets/svgs/remote_layers.svg",
_ => "assets/svgs/remote_layers.svg", // 下划线表示默认值
},
svgEnd: "assets/svgs/remote_down.svg",
onStart: () => debugPrint("$label start"),
onCenter: () => debugPrint("$label center"),
onStart: () => _handleSliderAction(label, "start", context),
onCenter: () => _handleSliderAction(label, "center", context),
onEnd: () => debugPrint("$label end"),
iconSize: boxWidth * 0.6 * 0.35,
),
@@ -101,4 +105,67 @@ class CenterControlArea extends StatelessWidget {
),
);
}
// 🔥 新增:统一的业务逻辑分发方法
void _handleSliderAction(String label, String action, BuildContext context) {
debugPrint('🎯 [Slider 业务] label: $label, action: $action');
// 🔥 根据 label 区分不同的设备
switch (label) {
case "底盘":
_handleChassisAction(action, context);
break;
case "割刀":
_handleMowerAction(action, context);
break;
default:
debugPrint('⚠️ 未知的 label: $label');
}
}
// 🔥 底盘的业务逻辑(左滑块)
void _handleChassisAction(String action, BuildContext context) {
final cubit = context.read<RemoteControlCubit>();
switch (action) {
case "start":
debugPrint('⬆️ 底盘 - 向上(例如:前进)');
// TODO: 发送底盘前进指令
// cubit.sendChassisCommand(ChassisCommand.forward);
break;
case "center":
debugPrint('️ 底盘 - 中间(例如:停止)');
// TODO: 发送底盘停止指令
// cubit.sendChassisCommand(ChassisCommand.stop);
break;
case "end":
debugPrint('⬇️ 底盘 - 向下(例如:后退)');
// TODO: 发送底盘后退指令
// cubit.sendChassisCommand(ChassisCommand.backward);
break;
}
}
// 🔥 割刀的业务逻辑(右滑块)
void _handleMowerAction(String action, BuildContext context) {
final cubit = context.read<RemoteControlCubit>();
switch (action) {
case "start":
debugPrint('⬆️ 割刀 - 向上(例如:抬刀)');
// TODO: 发送抬刀指令
// cubit.sendMowerCommand(MowerCommand.lift);
break;
case "center":
debugPrint('⏹️ 割刀 - 中间(例如:保持)');
// TODO: 发送保持指令
// cubit.sendMowerCommand(MowerCommand.hold);
break;
case "end":
debugPrint('⬇️ 割刀 - 向下(例如:降刀)');
// TODO: 发送降刀指令
// cubit.sendMowerCommand(MowerCommand.lower);
break;
}
}
}

View File

@@ -4,6 +4,7 @@ import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:maibu_satabot_v2/features/remote_control/presentation/bloc/remote_control_state.dart';
import 'package:maibu_satabot_v2/features/remote_control/presentation/widgets/status_chip.dart';
import 'package:cc_ui_kit/cc_ui_kit.dart';
import '../../../devices/presentation/bloc/devices_cubit.dart';
import '../bloc/remote_control_cubit.dart';
@@ -73,8 +74,12 @@ class TopStatusBar extends StatelessWidget {
// 4. 刷新按钮
_buildIconButton("assets/svgs/remote_refresh.svg", () {}),
const SizedBox(width: 25),
// 5. 火技能按钮 (对应 SmallFunctionButton)
//_buildIconButton("assets/svgs/fire.svg", () {}),
_buildSliderBox("割刀", false,context),
const Spacer(),
const Spacer(),
// TODO
_buildControlModeChip( _parseControlMode(remoteState.runningStatusModel.controlMode)),
@@ -207,4 +212,70 @@ class TopStatusBar extends StatelessWidget {
svgPath: svgPath,
);
}
Widget _buildSliderBox(String label, bool isLeft, BuildContext context) {
// 1. 核心尺寸调整:足够宽的容器解决拥挤,高度匹配状态栏
const double boxWidth = 96; // 水平宽度放大,容纳左右图标
const double boxHeight = 32; // 高度和其他按钮保持一致
const double iconSize = 20; // 图标尺寸放大,避免过小拥挤
return SizedBox(
width: boxWidth,
height: boxHeight,
child: Center(
// 2. 关键:旋转组件将竖向CCExpandSlider转为水平(无direction参数的替代方案)
child: RotatedBox(
quarterTurns: 1, // 旋转90度(竖向→横向),若方向反了可改为3
child: SizedBox(
// 旋转后宽高互换,这里给CCExpandSlider足够的显示空间
width: boxHeight, // 旋转后对应原高度
height: boxWidth, // 旋转后对应原宽度(足够长,不拥挤)
child: CCExpandSlider(
label: " ",
// 3. 图标适配旋转后的方向(仍用上下箭头,旋转后变为左右)
svgStart: "assets/svgs/remote_flame_minus.svg", // 旋转后→左箭头
svgCenter: "assets/svgs/remote_flame.svg",
svgEnd: "assets/svgs/remote_flame_plus.svg", // 旋转后→右箭头
// 4. 放大图标尺寸,解决拥挤
iconSize: iconSize,
// 保留原有业务逻辑
onStart: () => _handleSliderAction(label, "start", context),
onCenter: () => _handleSliderAction(label, "center", context),
onEnd: () => debugPrint("$label end"),
),
),
),
),
);
}
// 🔥 新增:统一的业务逻辑分发方法
void _handleSliderAction(String label, String action, BuildContext context) {
debugPrint('🎯 [Slider 业务] label: $label, action: $action');
// 🔥 根据 label 区分不同的设备
_handleChassisAction(action, context);
}
// 🔥 底盘的业务逻辑(左滑块)
void _handleChassisAction(String action, BuildContext context) {
final cubit = context.read<RemoteControlCubit>();
switch (action) {
case "start":
debugPrint('⬆️ 底盘 - 向上(例如:前进)');
// TODO: 发送底盘前进指令
// cubit.sendChassisCommand(ChassisCommand.forward);
break;
case "center":
debugPrint('️ 底盘 - 中间(例如:停止)');
// TODO: 发送底盘停止指令
// cubit.sendChassisCommand(ChassisCommand.stop);
break;
case "end":
debugPrint('⬇️ 底盘 - 向下(例如:后退)');
// TODO: 发送底盘后退指令
// cubit.sendChassisCommand(ChassisCommand.backward);
break;
}
}
}