utils.dart 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import 'package:trackoffical_app/model/game_person_data.dart';
  2. import 'package:trackoffical_app/model/m_control_point.dart';
  3. import 'package:trackoffical_app/utils.dart';
  4. import 'package:screen_brightness/screen_brightness.dart';
  5. import '../../../widget/app_dialog.dart';
  6. import '../checked_cp_record.dart';
  7. import 'game_std_controller.dart';
  8. extension MCPExt on MControlPoint{
  9. Widget display({TextStyle? textStyle, double? height}){
  10. final next = this;
  11. if (next.sn == MControlPoint.snStart || next.sn == MControlPoint.snFinish) {
  12. var src = 'ic_bottom_bar_next_start.png';
  13. if (next.sn == MControlPoint.snFinish) {
  14. src = 'ic_bottom_bar_next_finish.png';
  15. }
  16. return Image.asset(
  17. 'assets/images/$src',
  18. height: height??22,
  19. fit: BoxFit.fitHeight,
  20. color: Colors.white,
  21. );
  22. }
  23. return Text(next.sn, style: textStyle);
  24. }
  25. Widget icon({double? height}){
  26. final next = this;
  27. var src = 'ic_cp.png';
  28. if(next.isStart){
  29. src = 'ic_cp_start.png';
  30. }
  31. if(next.isFinish){
  32. src = 'ic_cp_finish.png';
  33. }
  34. return Image.asset(
  35. 'assets/images/$src',
  36. height: height??22,
  37. fit: BoxFit.fitHeight,
  38. );
  39. }
  40. }
  41. extension MCPNullableExt on MControlPoint?{
  42. Widget display({TextStyle? textStyle, double? height}){
  43. Widget text;
  44. final nextCp = this;
  45. if (nextCp != null) {
  46. text = nextCp.display(textStyle: textStyle);
  47. if (nextCp.areaId.isNotEmpty && nextCp.type == MControlPointType.nfc) {
  48. text = Row(
  49. mainAxisSize: MainAxisSize.min,
  50. children: [
  51. text,
  52. Text(
  53. ' (${nextCp.areaId})',
  54. style: textStyle,
  55. )
  56. ],
  57. );
  58. }
  59. } else {
  60. text = Text('--', style: textStyle, maxLines: 1);
  61. }
  62. return text;
  63. }
  64. }
  65. class _TwoValueElem extends StatelessWidget{
  66. const _TwoValueElem({
  67. required this.value1,
  68. required this.value2,
  69. required this.unit,
  70. required this.fontSize
  71. });
  72. final String value1;
  73. final String value2;
  74. final String unit;
  75. final double fontSize;
  76. @override
  77. Widget build(BuildContext context) {
  78. final small = fontSize * 0.875;
  79. final unitSize = small -2;
  80. return Row(
  81. children: [
  82. Expanded(child: Column(
  83. mainAxisSize: MainAxisSize.min,
  84. children: [
  85. SizedBox(
  86. width: context.width,
  87. child: Text(value1,
  88. maxLines: 1,
  89. style: TextStyle(fontSize: small))),
  90. Container(height: 1, width: context.width, color: Colors.white,),
  91. SizedBox(
  92. width: context.width,
  93. child: Text(value2,
  94. maxLines: 1,
  95. textAlign: TextAlign.end,
  96. style: TextStyle(fontSize: fontSize))),
  97. ],
  98. )),
  99. const SizedBox(width: 5),
  100. Text(unit, style: TextStyle(fontSize: unitSize))
  101. ],
  102. );
  103. }
  104. }
  105. extension GameModelExt on GamePersonData{
  106. Widget widgetDistance({double fontSize = 17.4, bool withTrip = true}) {
  107. final small = fontSize * 0.875;
  108. final unitSize = small -2;
  109. if (withTrip){
  110. return _TwoValueElem(
  111. value1: (myPositionHistoryLenFromLastCP.m).round().toString(),
  112. value2: (myPositionHistoryLen.value.m).round().toString(),
  113. unit: 'm',
  114. fontSize: fontSize);
  115. }else{
  116. var unit = ' km';
  117. var value = '--';
  118. (value, unit) = myPositionHistoryLen.value.toStringValueAndUnit();
  119. return RichText(text: TextSpan(
  120. text: value,
  121. style: TextStyle(fontSize: fontSize),
  122. children: [
  123. TextSpan(text: unit, style: TextStyle(fontSize: unitSize))
  124. ]
  125. ));
  126. }
  127. }
  128. String paceString(Duration pace){
  129. if(pace.inMinutes> 99){
  130. return '99+\'';
  131. }
  132. return pace.toMinSecondString();
  133. }
  134. Widget widgetPace({double fontSize = 17.4, bool withTrip = true}) {
  135. final small = fontSize * 0.875;
  136. final unitSize = small -2;
  137. if (withTrip){
  138. return _TwoValueElem(
  139. value1: paceString(paceSecondKmFromLastCP.value),
  140. value2: paceString(paceSecondKm.value),
  141. unit: '/km',
  142. fontSize: fontSize);
  143. }else{
  144. return RichText(text: TextSpan(
  145. text: paceString(paceSecondKm.value),
  146. style: TextStyle(fontSize: fontSize),
  147. children: [
  148. TextSpan(text: '/km', style: TextStyle(fontSize: unitSize))
  149. ]
  150. ));
  151. }
  152. }
  153. }
  154. Widget wSport(String value, String iconSrc, {TextStyle? textStyle}) {
  155. return Column(
  156. mainAxisSize: MainAxisSize.min,
  157. crossAxisAlignment: CrossAxisAlignment.center,
  158. children: [
  159. Text(value, maxLines: 1, overflow: TextOverflow.clip, style: textStyle),
  160. Image.asset(iconSrc, height: 14.16)],
  161. );
  162. }
  163. void showCheckedPoints(List<MControlPoint> data) {
  164. final textStyle = Get.theme.textTheme.titleLarge;
  165. Get.dialog(
  166. Card(
  167. color: Colors.white,
  168. surfaceTintColor: Colors.white,
  169. margin: const EdgeInsets.fromLTRB(40, 50, 40, 100),
  170. child: Padding(
  171. padding: const EdgeInsets.all(20),
  172. child: Column(
  173. children: [
  174. Text('打点记录', style: textStyle),
  175. const SizedBox(height: 12),
  176. Expanded(
  177. child: CheckedCPRecord(
  178. data: data,
  179. ),
  180. ),
  181. // SizedBox(
  182. // child: CheckPointRecord(data: controller.checkedPointHistory),
  183. // ),
  184. FilledButton(
  185. onPressed: () => Get.back(), child: const Text('确定'))
  186. ],
  187. ),
  188. )),
  189. );
  190. }
  191. Widget getSmallTitle(String title){
  192. return Container(
  193. alignment: Alignment.center,
  194. padding: const EdgeInsets.only(left: 3, right: 3),
  195. decoration: const BoxDecoration(color: Colors.black),
  196. child: Text(title,
  197. style: const TextStyle(
  198. fontSize:11,
  199. color: Colors.white,
  200. fontWeight: FontWeight.w700))
  201. );
  202. }
  203. Future<bool> get isBrightnessMax async{
  204. final b = await ScreenBrightness().current;
  205. return b>=1;
  206. }
  207. void onButtonExit(GameStdController controller) {
  208. Get.dialog(AppDialog(
  209. title: const Text('退出比赛'),
  210. content: const Text('是否强制结束?'),
  211. onConfirm: (){
  212. Get.back();
  213. controller.forceExit();
  214. } ,
  215. onCancel: () => Get.back(),
  216. onConfirmText: '是',
  217. onCancelText: '否',
  218. ));
  219. }