121 lines
4.2 KiB
Dart
121 lines
4.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:pj_supermarket_cloud/common/index.dart';
|
|
import 'package:pj_supermarket_cloud/sub_screen/widgets/reservation_display_metrics.dart';
|
|
|
|
/// 等待识别布局中的外接快捷小键盘操作提示。
|
|
///
|
|
/// 键盘形态复用公共示意组件 [ShortcutKeyboardDiagram]:上排依次为“人脸”“饭卡”
|
|
/// 与一个未绑定动作的留白键,下排左侧为占两列的加宽“核销”键、右侧为“取消”键。
|
|
/// 提示仅为示意图形,不参与任何交互。
|
|
class ReservationKeyboardHint extends StatelessWidget {
|
|
const ReservationKeyboardHint({super.key, required this.scale});
|
|
|
|
/// 基于副屏实际尺寸计算的统一缩放系数。
|
|
final double scale;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(
|
|
Icons.keyboard_outlined,
|
|
color: XfjDesignTokens.primary,
|
|
size: reservationFontSize(22, scale),
|
|
),
|
|
SizedBox(width: 8 * scale),
|
|
Text(
|
|
'键盘操作提示',
|
|
style: TextStyle(
|
|
color: XfjDesignTokens.ink,
|
|
fontSize: reservationFontSize(20, scale),
|
|
fontWeight: FontWeight.w800,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 12 * scale),
|
|
// 键盘质感来自预渲染 3D 素材图,布局随副屏缩放系数等比收缩;
|
|
// 显示宽度按视觉验收略小于 486 设计宽,避免在等待布局中占比过大。
|
|
ShortcutKeyboardDiagram(
|
|
key: const ValueKey('reservation-keyboard-hint'),
|
|
width: 440 * scale,
|
|
semanticLabel: '外接快捷小键盘操作提示示意图',
|
|
),
|
|
SizedBox(height: 16 * scale),
|
|
_ReservationKeyboardHintLines(scale: scale),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 键盘提示下方的通俗操作说明。
|
|
///
|
|
/// 面向全部年龄段的顾客与操作员,避免“识别方式”“餐段”等术语:
|
|
/// 每行以对应按键的语义色圆点开头,说明“两段式按键”“核销前提”和“取消用途”。
|
|
class _ReservationKeyboardHintLines extends StatelessWidget {
|
|
const _ReservationKeyboardHintLines({required this.scale});
|
|
|
|
/// 基于副屏实际尺寸计算的统一缩放系数。
|
|
final double scale;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
const lines = [
|
|
(
|
|
color: XfjDesignTokens.primary,
|
|
text: '按一下「人脸」或「饭卡」是选中,再按一下就开始识别',
|
|
),
|
|
(
|
|
color: XfjDesignTokens.success,
|
|
text: '按「核销」前要先识别出本人,且当天这一顿有预约才能成功',
|
|
),
|
|
(
|
|
color: XfjDesignTokens.danger,
|
|
text: '按「取消」可以随时停下来,回到开始的画面',
|
|
),
|
|
];
|
|
return SizedBox(
|
|
width: 620 * scale,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
for (final (index, line) in lines.indexed) ...[
|
|
if (index > 0) SizedBox(height: 7 * scale),
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// 色点与按键同色,帮助把文字说明对应到实体按键。
|
|
Container(
|
|
width: 10 * scale,
|
|
height: 10 * scale,
|
|
margin: EdgeInsets.only(top: 8 * scale, right: 9 * scale),
|
|
decoration: BoxDecoration(
|
|
color: line.color,
|
|
borderRadius: BorderRadius.circular(3 * scale),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
line.text,
|
|
style: TextStyle(
|
|
color: XfjDesignTokens.muted,
|
|
fontSize: reservationFontSize(19, scale),
|
|
height: 1.45,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|