layer_front_ui.dart 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. import 'package:trackoffical_app/generated/assets.dart';
  2. import 'package:trackoffical_app/screen.dart';
  3. import 'package:trackoffical_app/utils.dart';
  4. import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
  5. import '../layer/layer_controller.dart';
  6. import 'guardian_controller.dart';
  7. import '../m_icon_button.dart';
  8. class LayerFrontUI extends GetView<LayerController> {
  9. const LayerFrontUI({super.key});
  10. @override
  11. Widget build(BuildContext context) {
  12. final pH = 4.96.wp;
  13. return Padding(
  14. padding: EdgeInsets.fromLTRB(
  15. pH, MediaQuery.of(context).padding.top + 5.0.wp, pH, 11.19.wp),
  16. child: Stack(
  17. children: [
  18. Column(
  19. children: [
  20. Row(
  21. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  22. crossAxisAlignment: CrossAxisAlignment.start,
  23. children: [
  24. _ButtonBar(),
  25. GestureDetector(
  26. onTap: () => Get.back(),
  27. child: Image.asset(Assets.imagesBtnMapBack,
  28. height: 46.0, fit: BoxFit.fitHeight),
  29. )
  30. ],
  31. ),
  32. const Spacer(),
  33. _InfoCard(),
  34. ],
  35. )
  36. ],
  37. ));
  38. }
  39. }
  40. class _ButtonBar extends GetView<LayerController> {
  41. @override
  42. Widget build(BuildContext context) {
  43. final c = controller;
  44. if (c is! GuardianControllerMock) {
  45. return const SizedBox();
  46. }
  47. return Column(
  48. mainAxisSize: MainAxisSize.min,
  49. children: [
  50. _btnLocUnderGuardian(),
  51. _btnLocUnderGuardianLock(c),
  52. MIconButton(
  53. icon: Image.asset(Assets.imagesBtnMapAdd),
  54. onPressed: () {
  55. controller.mapDoScale(1.2);
  56. }),
  57. MIconButton(
  58. icon: Image.asset(Assets.imagesBtnMapMinus),
  59. onPressed: () {
  60. controller.mapDoScale(0.8);
  61. }),
  62. _btnShowRoute(),
  63. _btnLocateGuardian(),
  64. _btnShowGuardian()
  65. ],
  66. );
  67. }
  68. Widget _btnLocUnderGuardian(){
  69. return Obx((){
  70. final c = controller;
  71. if (c is! GuardianControllerMock) {
  72. return const SizedBox();
  73. }
  74. final person = c.selectedPersonData;
  75. final position = person?.myPositionOnMap;
  76. return MIconButton(
  77. src: Assets.imagesBtnLocUnderGuardian,
  78. onPressed: position!=null?(){
  79. c.moveOnMapPointToScreen(position, c.mapRotateCenter.value);
  80. }: null);
  81. });
  82. }
  83. Widget _btnLocUnderGuardianLock(GuardianControllerMock c){
  84. return Obx((){
  85. final person = c.selectedPersonData;
  86. return MIconButton(
  87. src: Assets.imagesBtnLocUnderGuardianUnlock,
  88. selectedSrc: Assets.imagesBtnLocUnderGuardianLock,
  89. isSelected: person?.userId==c.lockUnderGuardianToCenterUserId.value,
  90. onPressed: person!=null?(){
  91. c.lockUnderGuardianToCenter(person);
  92. } :null);
  93. });
  94. }
  95. Widget _btnShowRoute(){
  96. return Obx((){
  97. final c = controller;
  98. if (c is! GuardianControllerMock) {
  99. return const SizedBox();
  100. }
  101. return MIconButton(
  102. src: Assets.imagesBtnShowRouteSwitch,
  103. isSelected: c.isShowRoute.value,
  104. onPressed: ()=>c.isShowRoute.value=!c.isShowRoute.value);
  105. });
  106. }
  107. Widget _btnShowGuardian(){
  108. return Obx((){
  109. final c = controller;
  110. if (c is! GuardianControllerMock) {
  111. return const SizedBox();
  112. }
  113. return MIconButton(
  114. src: Assets.imagesBtnGuardianLocationSwitch,
  115. isSelected: c.isShowGuardian.value,
  116. onPressed: ()=>c.isShowGuardian.value=!c.isShowGuardian.value);
  117. });
  118. }
  119. Widget _btnLocateGuardian(){
  120. final c = controller;
  121. if (c is! GuardianControllerMock) {
  122. return const SizedBox();
  123. }
  124. return Obx((){
  125. final c = controller;
  126. if (c is! GuardianControllerMock) {
  127. return const SizedBox();
  128. }
  129. return MIconButton(
  130. src: Assets.imagesBtnGuardianLocation,
  131. onPressed: c.isShowGuardian.value? c.moveScreenCenterToGuardianLocation :null);
  132. });
  133. }
  134. }
  135. class _InfoCard extends GetView<LayerController> {
  136. @override
  137. Widget build(BuildContext context) {
  138. return Obx(() {
  139. final c = controller;
  140. if (c is! GuardianControllerMock) {
  141. return const SizedBox();
  142. }
  143. final personData = c.selectedPersonData;
  144. if (personData == null) {
  145. return const SizedBox();
  146. }
  147. final nextWantCP = personData.nextWantPoint;
  148. var nextWantCPDistance = '--';
  149. var nextWantCPDistanceD = personData.nextWantCPDistanceKmShow;
  150. if(nextWantCPDistanceD!=null){
  151. nextWantCPDistance = nextWantCPDistanceD.m.toInt().toString();
  152. }
  153. String? underGuardianDis;
  154. if(c.isShowGuardian.value){
  155. underGuardianDis = '--';
  156. final p1 = c.guardianPosition.value;
  157. final p2 = personData.myPosition;
  158. if(p1!= null && p2!= null){
  159. underGuardianDis = p2.distance(p1).m.toStringAsFixed(0);
  160. }
  161. }
  162. return Container(
  163. decoration: BoxDecoration(
  164. color: Colors.white,
  165. borderRadius: BorderRadius.circular(3.82.wp),
  166. boxShadow: [
  167. BoxShadow(color: const Color(0x45000000), blurRadius: 1.53.wp)
  168. ]),
  169. padding: EdgeInsets.all(3.56.wp),
  170. width: context.width,
  171. child: Column(
  172. mainAxisSize: MainAxisSize.min,
  173. children: [
  174. Row(
  175. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  176. children: [
  177. Column(
  178. mainAxisSize: MainAxisSize.min,
  179. crossAxisAlignment: CrossAxisAlignment.start,
  180. children: [
  181. Text.rich(TextSpan(
  182. text: personData.userName,
  183. style: TextStyle(
  184. fontSize: 6.62.wp, fontWeight: FontWeight.w500),
  185. children: [
  186. // TextSpan(text: ' 距离监护人米',
  187. TextSpan(
  188. text: underGuardianDis!=null?' 距离监护人$underGuardianDis米': ' ',
  189. style: TextStyle(
  190. fontSize: 3.56.wp,
  191. fontWeight: FontWeight.w400,
  192. color: context.theme.colorScheme.primary),
  193. )
  194. ])),
  195. Text(
  196. personData.duration.value.toAppString(),
  197. style: TextStyle(
  198. fontSize: 6.11.wp, fontFamily: 'sa-digital-number'),
  199. )
  200. ],
  201. ),
  202. bean(personData.beanCount.value, 4.5.wp),
  203. ],
  204. ),
  205. const Divider(),
  206. Row(
  207. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  208. children: [
  209. _wPointText(
  210. '打点${personData.checkedCount}/${personData.validCPAllNum}'),
  211. _wPointText(
  212. '里程${personData.myPositionHistoryLen.value}'),
  213. _wPointText(
  214. '配速${personData.pacePerKm.value.toMinSecondString()}'),
  215. ],
  216. ),
  217. SizedBox(height: 2.0.wp),
  218. Row(
  219. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  220. children: [
  221. _wCardText('实时心率', "${personData.heartRate.value}",
  222. color: personData.heartRatePercent.value.round().toHRPColor()),
  223. _wCardText(
  224. '目标', nextWantCP != null ? '${nextWantCP.snString}点' : ''),
  225. _wCardText('点距(米)', nextWantCPDistance),
  226. _wCardText('步数', '${personData.stepCount.value}'),
  227. _wCardText('消耗热量', personData.kCal.value.toStringAsFixed(1)),
  228. ],
  229. )
  230. ],
  231. ),
  232. );
  233. });
  234. }
  235. }
  236. Widget _wPointText(String text) {
  237. return Row(
  238. mainAxisSize: MainAxisSize.min,
  239. children: [
  240. Container(
  241. width: 2.0.wp,
  242. height: 2.0.wp,
  243. decoration: const BoxDecoration(
  244. shape: BoxShape.circle, color: Color(0xffff870d)),
  245. ),
  246. Text(
  247. text,
  248. style: TextStyle(fontSize: 4.0.wp, fontWeight: FontWeight.w500),
  249. ),
  250. ],
  251. );
  252. }
  253. Widget _wCardText(String title, String value, {Color? color}) {
  254. final valueColor = color != null ? Colors.white : Colors.black;
  255. final titleColor = color != null ? Colors.white : Colors.grey;
  256. return Container(
  257. width: 13.99.wp,
  258. height: 16.03.wp,
  259. decoration: BoxDecoration(
  260. color: color ?? const Color(0xfff9f9f9),
  261. borderRadius: BorderRadius.circular(1.53.wp),
  262. ),
  263. child: Column(
  264. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  265. children: [
  266. Text(
  267. title,
  268. style: TextStyle(fontSize: 2.54.wp, color: titleColor),
  269. ),
  270. Text(
  271. value,
  272. style: TextStyle(fontSize: 4.0.wp, color: valueColor),
  273. )
  274. ],
  275. ),
  276. );
  277. }