import 'package:flutter/material.dart'; import 'package:trackoffical_app/generated/assets.dart'; import 'package:trackoffical_app/screen.dart'; import 'package:trackoffical_app/service/app.dart'; import 'package:trackoffical_app/service/mock.dart'; import 'package:trackoffical_app/service/user_profile.dart'; import 'package:trackoffical_app/view/sport_wear_select_view.dart'; import '../service/sport_wear.dart'; import '../widget/app_top_bar.dart'; import 'package:get/get.dart'; class GameSettingsView extends StatefulWidget { const GameSettingsView({super.key, this.isInGame = false}); final bool isInGame; @override State createState() { return _GameSettingsState(); } } class _GameSettingsState extends State { @override void initState() { super.initState(); if(!widget.isInGame){ profile.cleanGameSettingsLock(); setState(() {}); } } final SportWearService _sp = Get.find(); final profile = App.to.userProfile; Widget listView(String title, GameSettingsValue value, Widget trailing, {bool show=true}) { if(!show){ return const SizedBox(); } return ListTile( title: Row( mainAxisSize: MainAxisSize.min, children: [ Text( title, style: TextStyle(fontSize: 4.44.wp), ), SizedBox(width: 3.0.wp), widget.isInGame ? Image.asset( value.isLocked ? Assets.imagesIcLock : Assets.imagesIcLockOpen, height: 3.69.wp, ) : const SizedBox() ], ), trailing: trailing); } Widget listViewSwitch(String title, GameSettingsValue value, {bool show=true}) { return listView( title, value, Switch( activeColor: Colors.blue, value: value.value, onChanged: value.isLocked ? null : (v) { setState(() { value.value = v; }); }), show: show ); } Widget listViewMenu(String title, GameSettingsValue value, List menu, String Function(T) fmt) { final menuList = menu .map((e) => MenuItemButton( onPressed: () => setState(() { value.value = e; }), child: MenuAcceleratorLabel(fmt(e)), )) .toList(); return listView( title, value, SizedBox( height: 46, width: 94, child: value.isLocked ? Text(fmt(value.value)) : SubmenuButton( menuChildren: menuList, trailingIcon: const Icon(Icons.arrow_drop_down, size: 20), child: Text(fmt(value.value)), ), )); } Widget listViewSP(){ return ListTile( title: Text('心率带', style: TextStyle(fontSize: 4.44.wp),), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ Obx(() { final wear = _sp.connectedSportWear.value; return wear != null ? Text(wear.name) : const Text('未连接'); }), const Icon(Icons.keyboard_arrow_right) ], ), onTap: showSportWearSelectDialog, ); } @override Widget build(BuildContext context) { final children = []; final isInGame = widget.isInGame; if (isInGame) { children.add(listViewMenu('地图模式', profile.gameSettingsUIMode, GameUIMode.values, (m){ var text = ''; switch(m){ case GameUIMode.electronicMap: text = '电子'; break; case GameUIMode.noMap: text = '无图'; break; case GameUIMode.paperMap: text = '纸质'; break; } return text; })); } if (isInGame) { children.add(listViewSP()); } children.addAll([ listViewSwitch('简单显示面板', profile.gameSettingsSimpleDashboard), listViewSwitch('边界报警', profile.gameSettingsBoundaryWarn, show: isInGame), listViewMenu('轨迹长度', profile.gameSettingsTrackLengthSeconds, [60, 90, 120], (v) => '$v秒'), listViewSwitch('显示我的位置', profile.gameSettingsShowMyLocation), listViewSwitch('开始提示', profile.gameSettingsStartRemind), listViewSwitch('声音提示', profile.gameSettingsSoundPrompt), listViewSwitch('震动提示', profile.gameSettingsVibrationPrompt), listViewSwitch('打点文创', profile.gameSettingsShowOriginality, show: isInGame), listViewSwitch('指北针真北', profile.gameSettingsRealNorth), listViewSwitch('允许GPS场控', profile.gameSettingsGpsTrack), listViewMenu('打点半径', profile.gameSettingsPunchRadiusMeter, [2, 3, 5], (v) => '$v米'), listViewSwitch('路线预览', profile.gameSettingsRoutePreview), listViewSwitch('打点错误提示', profile.gameSettingsPunchErrorPrompt), listViewSwitch('热区提醒', profile.gameSettingsHotZonePrompt), // listViewSwitch('虚拟点打点方式', profile.gameSettingsRoutePreview), ]); return Scaffold( appBar: AppTopBar(title: const Text('设置'), automaticallyImplyLeading: true), body: ListView( children: children, ), ); } } void main() { Mock.initServices(); runPreview(const GameSettingsView()); }