Files
kuaishai2/lib/features/home/widgets/running_control_panel.dart
Developer 736c36a98e refactor(home): 优化主页布局和运行控制面板
- 将主页左右布局改为弹性布局,左侧程序列表占2/5宽度,右侧控制区域占3/5宽度
- 移除程序列表组件的固定宽度设置,使其能够自适应布局
- 在运行控制面板中添加主轴最小尺寸限制以优化空间使用
- 移除暂停/继续按钮中的占位按钮,简化按钮逻辑
- 修改开始/继续按钮为暂停/继续按钮,支持运行中状态切换
- 更新按钮图标和文字根据当前运行状态动态显示
- 移除运行状态指示器,精简界面元素
2026-06-04 17:22:38 +08:00

323 lines
10 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/localization/app_localizations.dart';
import '../../../core/theme/app_theme.dart';
import '../../../shared/widgets/common_button.dart';
import '../../device/providers/run_state_provider.dart';
import '../../programs/models/program.dart';
import '../../programs/providers/programs_provider.dart';
/// 运行控制面板 - 暗色工业风格
/// 显示当前程序信息和运行控制按钮
class RunningControlPanel extends ConsumerWidget {
const RunningControlPanel({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final runState = ref.watch(runStateProvider);
final programsState = ref.watch(programsProvider);
return Container(
decoration: BoxDecoration(
color: AppTheme.cardBg,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppTheme.borderSubtle, width: 1),
),
child: runState.status == RunStatus.idle
? _buildIdleState(context, ref, l10n, programsState.selectedProgram)
: _buildRunningState(context, ref, l10n, runState),
);
}
/// 待机状态布局
Widget _buildIdleState(
BuildContext context,
WidgetRef ref,
AppLocalizations? l10n,
dynamic selectedProgram,
) {
final runNotifier = ref.read(runStateProvider.notifier);
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// 当前选中程序显示
if (selectedProgram != null)
Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: AppTheme.cardSelectedBg,
borderRadius: BorderRadius.circular(6),
border: Border.all(color: AppTheme.accentPrimary, width: 1),
),
child: Row(
children: [
Text(
'${l10n?.selectedProgramLabel ?? '当前选中'}:',
style: const TextStyle(
color: AppTheme.textTertiary,
fontSize: 12,
),
),
const SizedBox(width: 12),
Expanded(
child: Text(
'${selectedProgram.code} ${selectedProgram.name}',
style: const TextStyle(
color: AppTheme.accentPrimary,
fontSize: 14,
fontWeight: FontWeight.w600,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
)
else
Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: AppTheme.cardBg,
borderRadius: BorderRadius.circular(6),
border: Border.all(color: AppTheme.borderSubtle, width: 1),
),
child: Text(
l10n?.pleaseSelectProgram ?? '请选择要运行的程序',
style: const TextStyle(
color: AppTheme.textTertiary,
fontSize: 12,
),
),
),
const SizedBox(height: 12),
// 控制按钮
Row(
children: [
// 开始运行按钮
Expanded(
flex: 2,
child: SizedBox(
height: 48,
child: CommonButton(
text: l10n?.startRun ?? '开始运行',
icon: Icons.play_arrow,
type: ButtonType.primary,
enabled: selectedProgram != null,
onPressed: selectedProgram != null
? () => _confirmAndStart(context, runNotifier, selectedProgram, l10n)
: null,
),
),
),
const SizedBox(width: 12),
// 停止按钮(待机态禁用)
Expanded(
child: SizedBox(
height: 48,
child: CommonButton(
text: l10n?.stop ?? '停止',
icon: Icons.stop,
type: ButtonType.danger,
enabled: false,
onPressed: null,
),
),
),
],
),
],
),
);
}
/// 运行状态布局
Widget _buildRunningState(
BuildContext context,
WidgetRef ref,
AppLocalizations? l10n,
RunState runState,
) {
final runNotifier = ref.read(runStateProvider.notifier);
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// 当前程序名称
Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: AppTheme.cardSelectedBg,
borderRadius: BorderRadius.circular(6),
border: Border.all(color: AppTheme.accentPrimary, width: 1),
),
child: Row(
children: [
Text(
'${l10n?.selectedProgramLabel ?? '当前选中'}:',
style: const TextStyle(
color: AppTheme.textTertiary,
fontSize: 12,
),
),
const SizedBox(width: 12),
Expanded(
child: Text(
runState.currentProgram?.name ?? '',
style: const TextStyle(
color: AppTheme.accentPrimary,
fontSize: 14,
fontWeight: FontWeight.w600,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
const SizedBox(height: 12),
// 控制按钮
Row(
children: [
// 暂停/继续按钮(运行中切换)
Expanded(
flex: 2,
child: SizedBox(
height: 48,
child: CommonButton(
text: runState.status == RunStatus.paused
? (l10n?.continue_ ?? '继续')
: (l10n?.pause ?? '暂停'),
icon: runState.status == RunStatus.paused
? Icons.play_arrow
: Icons.pause,
type: ButtonType.primary,
onPressed: () {
if (runState.status == RunStatus.paused) {
runNotifier.resume();
} else {
runNotifier.pause();
}
},
),
),
),
const SizedBox(width: 12),
// 停止按钮
Expanded(
child: SizedBox(
height: 48,
child: CommonButton(
text: l10n?.stop ?? '停止',
icon: Icons.stop,
type: ButtonType.danger,
onPressed: () => _showStopConfirm(context, runNotifier, l10n),
),
),
),
],
),
],
),
);
}
/// 显示瓷套棒放置确认对话框,确认后启动程序
void _confirmAndStart(
BuildContext context,
RunStateNotifier runNotifier,
Program program,
AppLocalizations? l10n,
) {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: AppTheme.cardBg,
title: Text(
l10n?.ceramicSleeveConfirm ?? '运行前请确认已安装瓷套棒',
style: const TextStyle(color: AppTheme.textHeading),
),
content: Text(
l10n?.ceramicSleeveConfirmMessage ?? '请确认已放置瓷套棒后再启动程序。',
style: const TextStyle(color: AppTheme.textPrimary),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(
l10n?.cancel ?? '取消',
style: const TextStyle(color: AppTheme.textSecondary),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.accentPrimary,
foregroundColor: Colors.white,
),
onPressed: () {
Navigator.of(context).pop();
runNotifier.start(program);
},
child: Text(l10n?.confirm ?? '确认'),
),
],
),
);
}
/// 显示停止确认对话框
void _showStopConfirm(
BuildContext context,
RunStateNotifier runNotifier,
AppLocalizations? l10n,
) {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: AppTheme.cardBg,
title: Text(
l10n?.confirm ?? '确认',
style: const TextStyle(color: AppTheme.textHeading),
),
content: Text(
l10n?.stopConfirm ?? '确定要停止当前运行的程序吗?',
style: const TextStyle(color: AppTheme.textPrimary),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(
l10n?.cancel ?? '取消',
style: const TextStyle(color: AppTheme.textSecondary),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.accentCritical,
foregroundColor: Colors.white,
),
onPressed: () {
runNotifier.stop();
Navigator.of(context).pop();
},
child: Text(l10n?.confirm ?? '确认'),
),
],
),
);
}
}