You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

645 lines
20 KiB

3 months ago
  1. #include "ui_controler.hpp"
  2. #include <stdarg.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. //
  7. #include "tjc/tjc_constant.hpp"
  8. #include "tjc_event_processer_mgr.hpp"
  9. #include "ui_state_mgr.hpp"
  10. //
  11. using namespace iflytop;
  12. #define TAG "UIScheduler"
  13. #define MODULE_DEBUG 0
  14. #define UART_RX_OVERTIME 5
  15. #define CMD_OVERTIME 100
  16. static ZThread uart_rx_thread;
  17. static ZThread rx_processed_thread;
  18. static ZThread ui_block_work_thread;
  19. static ZQueue<tjc_rx_packet_t> ackQueue;
  20. static ZQueue<tjc_rx_packet_t> eventQueue;
  21. static ZThread usartRxThread;
  22. static ZThread eventProcessThread;
  23. static bool m_isWaitingForAck;
  24. static UART_HandleTypeDef* tjcUart;
  25. static UIEvent event_cache;
  26. /***********************************************************************************************************************
  27. * UTILS *
  28. ***********************************************************************************************************************/
  29. static const char* zhex2str(uint8_t* data, size_t len) {
  30. static char buf[256];
  31. memset(buf, 0, sizeof(buf));
  32. for (size_t i = 0; i < len; i++) {
  33. sprintf(buf + i * 2, "%02X", data[i]);
  34. }
  35. return buf;
  36. }
  37. namespace iflytop {
  38. __weak void UIControlerHock_PageInit() {}
  39. } // namespace iflytop
  40. /***********************************************************************************************************************
  41. * FUNC *
  42. ***********************************************************************************************************************/
  43. void UIControler::doBlockWork(const char* blockmask, function<void()> fn) {
  44. ui_block_work_thread.start([fn, blockmask]() {
  45. UIPublicState::setLoadingState(true, blockmask);
  46. osDelay(10);
  47. fn();
  48. UIPublicState::setLoadingState(false, "");
  49. });
  50. }
  51. void UIControler::postInitialize() {
  52. ackQueue.initialize(5, sizeof(tjc_rx_packet_t));
  53. eventQueue.initialize(5, sizeof(tjc_rx_packet_t));
  54. usartRxThread.init("UI_RX", 512);
  55. eventProcessThread.init("UI_RX_PROCESS", 1024);
  56. ui_block_work_thread.init("UI_WORK", 1024);
  57. tjcUart = AppHardware::ins()->tjcUart;
  58. UIPublicState::initialize();
  59. m_cmdlock.init();
  60. sendcmd("rest");
  61. osDelay(1000);
  62. sendcmd("page %d", pg_pStart);
  63. }
  64. void UIControler::initialize() { //
  65. startSchedule();
  66. }
  67. void UIControler::pageInitialize() { UIControlerHock_PageInit(); }
  68. void UIControler::callUsrEventCb(UIEvent* event) {
  69. static AppEvent appEvent;
  70. appEvent.type = KAE_UIEvent;
  71. appEvent.setUIEvent(event);
  72. AppEventBus::ins()->pushEventBlock("UIEvent", &appEvent);
  73. }
  74. void UIControler::startSchedule() {
  75. usartRxThread.start([this]() {
  76. static uint8_t rxbuf[256];
  77. tjcUart->USR_UartITRxing = 1;
  78. tjcUart->USR_UartITRxBuf = rxbuf;
  79. tjcUart->USR_UartITRxBufSize = 256;
  80. tjcUart->USR_UartITRxOff = 0;
  81. HAL_UART_Receive_IT(tjcUart, &tjcUart->USR_UartITRxBufCache, 1);
  82. while (1) {
  83. static uint8_t processbuf[256];
  84. int32_t rxsize = 0;
  85. if (tjcUart->USR_UartITRxOff != 0 && zos_haspassedms(tjcUart->USR_UartITLastRxTicket) > UART_RX_OVERTIME) {
  86. vPortEnterCritical();
  87. if (tjcUart->USR_UartITRxOff != 0 && zos_haspassedms(tjcUart->USR_UartITLastRxTicket) > UART_RX_OVERTIME) {
  88. memcpy(processbuf, tjcUart->USR_UartITRxBuf, tjcUart->USR_UartITRxOff);
  89. rxsize = tjcUart->USR_UartITRxOff;
  90. tjcUart->USR_UartITRxOff = 0;
  91. }
  92. vPortExitCritical();
  93. }
  94. if (rxsize != 0) {
  95. processScreenRxPacket(processbuf, rxsize);
  96. }
  97. osDelay(1);
  98. }
  99. });
  100. eventProcessThread.start([this]() {
  101. while (1) {
  102. static tjc_rx_packet_t packet;
  103. bool suc = eventQueue.receive(&packet, 10);
  104. if (suc) {
  105. memset(&event_cache, 0, sizeof(event_cache));
  106. tjc_packet_type_t packetType = (tjc_packet_type_t)packet.data[0];
  107. auto* processer = TJCEventProcesserMgr::findProcesser((tjc_packet_type_t)packetType);
  108. // ZLOGI(TAG, "[eventprocess-thread]: rx_event:%s(%d)", tjc::pt2str(packetType), packetType);
  109. if (processer != nullptr) {
  110. processer->process(packet.data, packet.datalen, &event_cache);
  111. } else {
  112. event_cache.eventId = packet.data[0];
  113. }
  114. // ZLOGI(TAG, "push event %s(%d) ", tjc::pt2str(event_cache.eventId), event_cache.eventId);
  115. callUsrEventCb(&event_cache);
  116. }
  117. osDelay(1);
  118. }
  119. });
  120. }
  121. void UIControler::processScreenRxPacket(uint8_t* data, size_t len) {
  122. // �жϰ��Ƿ��Ϸ�
  123. #if MODULE_DEBUG
  124. ZLOGI(TAG, "[rx-thread] : rx :%s(%d)", zhex2str(data, len), len);
  125. #endif
  126. if (!(data[len - 1] == 0xff && data[len - 2] == 0xff && data[len - 3] == 0xff)) {
  127. ZLOGI(TAG, "rx invalid packet %s", zhex2str(data, len));
  128. return;
  129. }
  130. if (TJC_MAX_PACKET_SIZE < len) {
  131. ZLOGI(TAG, "rx invalid packet(tool long) %s", zhex2str(data, len));
  132. return;
  133. }
  134. uint8_t packetType = data[0];
  135. static tjc_rx_packet_t packet;
  136. packet.datalen = len;
  137. memcpy(packet.data, data, len);
  138. if (kpt_ack == packetType) {
  139. if (m_isWaitingForAck) {
  140. bool suc = ackQueue.send(&packet, 10);
  141. if (!suc) {
  142. ZLOGI(TAG, "ackQueue send failed");
  143. }
  144. m_isWaitingForAck = false;
  145. }
  146. } else {
  147. bool suc = eventQueue.send(&packet, 10);
  148. if (!suc) {
  149. ZLOGI(TAG, "eventQueue send failed");
  150. }
  151. }
  152. }
  153. bool UIControler::readTxt(uint8_t pid, uint8_t cId, char* txt, int32_t txtbuflen) {
  154. zlock_guard lg(m_cmdlock);
  155. startReceiveAck();
  156. // sendcmd("com_stop");
  157. sendcmd("printh AA");
  158. sendcmd("prints p[%d].b[%d].txt,0", pid, cId);
  159. sendcmd("printh 00");
  160. sendcmd("printh FF FF FF");
  161. sendcmd("com_start");
  162. bool suc = ackQueue.receive(&ackcache, CMD_OVERTIME);
  163. if (!suc) {
  164. ZLOGI(TAG, "readTxt failed");
  165. return false;
  166. }
  167. int32_t cpysize = ackcache.datalen - 3;
  168. if (cpysize > txtbuflen) {
  169. cpysize = txtbuflen - 1;
  170. }
  171. memcpy(txt, &ackcache.data[1], cpysize);
  172. return true;
  173. }
  174. bool UIControler::readFiledAsInt(uint8_t pid, uint8_t bid, const char* filedName, int32_t* val) {
  175. for (int i = 0; i < 5; i++) {
  176. if (_readFiledAsInt(pid, bid, filedName, val)) {
  177. return true;
  178. }
  179. ZLOGW(TAG, "readFiledAsInt pid:%d bid:%d %s failed retry %d", pid, bid, filedName, i);
  180. osDelay(1000);
  181. }
  182. ZLOGE(TAG, "readFiledAsInt %s failed", filedName);
  183. return false;
  184. }
  185. bool UIControler::_readFiledAsInt(uint8_t pid, uint8_t bid, const char* filedName, int32_t* val) {
  186. zlock_guard lg(m_cmdlock);
  187. startReceiveAck();
  188. // sendcmd("com_stop");
  189. sendcmd("printh AA");
  190. sendcmd("prints p[%d].b[%d].%s,4", pid, bid, filedName);
  191. sendcmd("printh FF FF FF");
  192. // sendcmd("com_start");
  193. bool suc = ackQueue.receive(&ackcache, CMD_OVERTIME);
  194. if (!suc) {
  195. return false;
  196. }
  197. uint8_t int32val[4] = {0};
  198. memcpy(int32val, &ackcache.data[1], 4);
  199. *val = *(int32_t*)int32val;
  200. return true;
  201. }
  202. bool UIControler::readInt(uint8_t pid, uint8_t bid, int32_t* val) { return readFiledAsInt(pid, bid, "val", val); }
  203. bool UIControler::echo(uint8_t tx, uint8_t* rx) {
  204. zlock_guard lg(m_cmdlock);
  205. startReceiveAck();
  206. // sendcmd("com_stop");
  207. sendcmd("printh AA");
  208. sendcmd("printh %02X", tx);
  209. sendcmd("printh FF FF FF");
  210. sendcmd("com_start");
  211. bool suc = ackQueue.receive(&ackcache, CMD_OVERTIME);
  212. if (!suc) {
  213. ZLOGI(TAG, "readTxt failed");
  214. return false;
  215. }
  216. uint8_t int32val = 0;
  217. memcpy(&int32val, &ackcache.data[1], 1);
  218. *rx = int32val;
  219. if (tx != int32val) {
  220. return false;
  221. }
  222. return true;
  223. }
  224. bool UIControler::setTxt(uint8_t pid, uint8_t bid, const char* txt, ...) {
  225. zlock_guard lg(m_cmdlock);
  226. va_list args;
  227. va_start(args, txt);
  228. setTxt(pid, bid, txt, args);
  229. va_end(args);
  230. return true;
  231. }
  232. bool UIControler::setTxt(uint8_t pid, uint8_t bid, const char* txt, va_list args) {
  233. zlock_guard lg(m_cmdlock);
  234. static char buf[256];
  235. memset(buf, 0, sizeof(buf));
  236. vsprintf(buf, txt, args);
  237. sendcmd("p[%d].b[%d].txt=\"%s\"", pid, bid, buf);
  238. return true;
  239. }
  240. void UIControler::setPicturePicNum(uint8_t pid, uint8_t bid, uint8_t fromBid) {
  241. zlock_guard lg(m_cmdlock);
  242. sendcmd("p[%d].b[%d].pic=p[%d].b[%d].pic", pid, bid, pid, fromBid);
  243. }
  244. void UIControler::setButtonPicNum(uint8_t pid, uint8_t bid, uint8_t fromBid) {
  245. zlock_guard lg(m_cmdlock);
  246. sendcmd("p[%d].b[%d].pic=p[%d].b[%d].pic", pid, bid, pid, fromBid);
  247. sendcmd("p[%d].b[%d].pic2=p[%d].b[%d].pic2", pid, bid, pid, fromBid);
  248. }
  249. void UIControler::setPicturePicNumFromGlobal(uint8_t pid, uint8_t bid, uint8_t fromPid, uint8_t fromBid) {
  250. zlock_guard lg(m_cmdlock);
  251. sendcmd("p[%d].b[%d].pic=p[%d].b[%d].pic", pid, bid, fromPid, fromBid);
  252. }
  253. void UIControler::setButtonPicNumFromGlobal(uint8_t pid, uint8_t bid, uint8_t fromPid, uint8_t fromBid) {
  254. zlock_guard lg(m_cmdlock);
  255. sendcmd("p[%d].b[%d].pic=p[%d].b[%d].pic", pid, bid, fromPid, fromBid);
  256. sendcmd("p[%d].b[%d].pic2=p[%d].b[%d].pic2", pid, bid, fromPid, fromBid);
  257. }
  258. bool UIControler::setVal(uint8_t pid, uint8_t cid, int32_t val) {
  259. zlock_guard lg(m_cmdlock);
  260. sendcmd("p[%d].b[%d].val=%d", pid, cid, val);
  261. return true;
  262. }
  263. bool UIControler::vis(uint16_t buuid, int32_t val) {
  264. zlock_guard lg(m_cmdlock);
  265. sendcmd("vis %d,%d", buuid & 0xff, val);
  266. return true;
  267. }
  268. void UIControler::setrtc(zdate_t* date) {
  269. zlock_guard lg(m_cmdlock);
  270. sendcmd("rtc0=%d", date->year);
  271. sendcmd("rtc1=%d", date->month);
  272. sendcmd("rtc2=%d", date->day);
  273. sendcmd("rtc3=%d", date->hours);
  274. sendcmd("rtc4=%d", date->minutes);
  275. sendcmd("rtc5=%d", date->seconds);
  276. }
  277. void UIControler::popWin(UIPopWinType_t type, const char* info, function<void(bool)> onConfirm) {
  278. zlock_guard lg(m_cmdlock);
  279. UIPublicState::pushUIPopInfo(type, info, onConfirm);
  280. }
  281. void UIControler::chpage(uint8_t page, bool triggerEvent) {
  282. zlock_guard lg(m_cmdlock);
  283. UIStateMgr::ins()->changePage(page);
  284. if (triggerEvent) {
  285. AppEventBus::ins()->pushPageChangeEvent(page);
  286. osDelay(10);
  287. }
  288. sendcmd("page %d", page);
  289. }
  290. void UIControler::sendcmd(const char* format, ...) {
  291. // static char buf[256];
  292. va_list args;
  293. va_start(args, format);
  294. // vsprintf(buf, format, args);
  295. sendcmd(format, args);
  296. va_end(args);
  297. }
  298. void UIControler::sendcmd(const char* format, va_list args) {
  299. static char buf[1024];
  300. memset(buf, 0, sizeof(buf));
  301. vsprintf(buf, format, args);
  302. #if MODULE_DEBUG
  303. ZLOGI(TAG, "tx:%s", buf);
  304. #endif
  305. uint8_t len = strlen(buf);
  306. if (len > (1024 - 3)) {
  307. ZLOGI(TAG, "sendcmd too long");
  308. return;
  309. }
  310. buf[len] = 0xff;
  311. buf[len + 1] = 0xff;
  312. buf[len + 2] = 0xff;
  313. // vPortEnterCritical();
  314. // HAL_UART_Transmit_DMA(tjcUart, (uint8_t*)buf, len + 3);
  315. HAL_UART_Transmit(tjcUart, (uint8_t*)buf, len + 3, 100);
  316. // vPortExitCritical();
  317. // while (true) {
  318. // osDelay(2);
  319. // if (tjcUart->gState == HAL_UART_STATE_BUSY_RX || tjcUart->gState == HAL_UART_STATE_READY) {
  320. // return;
  321. // }
  322. // }
  323. }
  324. void UIControler::startReceiveAck() {
  325. ackQueue.clear();
  326. m_isWaitingForAck = true;
  327. }
  328. void UIControler::virtualClick(uint8_t pid, uint8_t bid, uint8_t event) {
  329. zlock_guard lg(m_cmdlock);
  330. sendcmd("click b[%d],%d", bid, event);
  331. }
  332. void UIControler::setTouchEnableState(uint8_t bid, uint8_t enable) {
  333. // tsw obj,state
  334. zlock_guard lg(m_cmdlock);
  335. sendcmd("tsw b[%d],%d", bid, enable);
  336. }
  337. void UIControler::setEnumComponentState(uint8_t pid, uint8_t bid, int32_t state) {
  338. // ö������ʹ�ö�������
  339. sendcmd("p[%d].b[%d].tim=%d", pid, bid, state * 50);
  340. }
  341. void UIControler::setPic(uint8_t pid, uint8_t bid, int32_t picNum) {
  342. zlock_guard lg(m_cmdlock);
  343. sendcmd("p[%d].b[%d].pic=%d", pid, bid, picNum);
  344. }
  345. void UIControler::setAph(uint8_t pid, uint8_t bid, int32_t state) {
  346. zlock_guard lg(m_cmdlock);
  347. sendcmd("p[%d].b[%d].aph=%d", pid, bid, state);
  348. }
  349. bool UIControler::visEx(uint8_t pid, uint8_t bid, bool val) {
  350. zlock_guard lg(m_cmdlock);
  351. component_info_t* component = UIStateMgr::ins()->forceFindComponent(pid, bid);
  352. if (component == NULL) {
  353. ZLOGW(TAG, "visEx failed,component alloc failed");
  354. return false;
  355. }
  356. bool suc = true;
  357. do {
  358. if (!component->isPosInited) {
  359. suc = readFiledAsInt(pid, bid, "x", &component->oldPosX);
  360. if (!suc) {
  361. for (size_t i = 0; i < 3; i++) {
  362. ZLOGE(TAG, "fatal error, reboot");
  363. osDelay(1000);
  364. }
  365. NVIC_SystemReset();
  366. }
  367. suc = readFiledAsInt(pid, bid, "y", &component->oldPosY);
  368. if (!suc) {
  369. for (size_t i = 0; i < 3; i++) {
  370. ZLOGE(TAG, "fatal error, reboot");
  371. osDelay(1000);
  372. }
  373. NVIC_SystemReset();
  374. }
  375. }
  376. if (val) {
  377. // ��ʾ
  378. if (!component->isVis) {
  379. sendcmd("p[%d].b[%d].x=%d", pid, bid, component->oldPosX);
  380. sendcmd("p[%d].b[%d].y=%d", pid, bid, component->oldPosY);
  381. component->isVis = true;
  382. }
  383. } else {
  384. if (component->isVis) {
  385. component->isPosInited = true;
  386. component->isVis = false;
  387. sendcmd("p[%d].b[%d].x=%d", pid, bid, -2000);
  388. sendcmd("p[%d].b[%d].y=%d", pid, bid, -2000);
  389. }
  390. }
  391. } while (false);
  392. return suc;
  393. }
  394. bool UIControler::movePicToXY(uint8_t pid, uint8_t bid, int32_t x, int32_t y) {
  395. sendcmd("p[%d].b[%d].x=%d", pid, bid, x);
  396. sendcmd("p[%d].b[%d].y=%d", pid, bid, y);
  397. return true;
  398. }
  399. bool UIControler::movePicTo(uint8_t pid, uint8_t bid, uint8_t toBid) {
  400. sendcmd("p[%d].b[%d].x=p[%d].b[%d].x", pid, bid, pid, toBid);
  401. sendcmd("p[%d].b[%d].y=p[%d].b[%d].y", pid, bid, pid, toBid);
  402. return true;
  403. }
  404. bool UIControler::movePicOutOfScreen(uint8_t pid, uint8_t bid) {
  405. sendcmd("p[%d].b[%d].x=%d", pid, bid, -2000);
  406. sendcmd("p[%d].b[%d].y=%d", pid, bid, -2000);
  407. return true;
  408. }
  409. /***********************************************************************************************************************
  410. * *
  411. ***********************************************************************************************************************/
  412. void UIControler::popFullKeyBoard(uint8_t fromPid, uint8_t fromBid, int limitLength, const char* initval) {
  413. zlock_guard lg(m_cmdlock);
  414. UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
  415. sendcmd("p[%d].b[%d].val=%d", pg_keybdAP, ob_keybdAP_loadpageid, fromPid);
  416. sendcmd("p[%d].b[%d].val=%d", pg_keybdAP, ob_keybdAP_loadcmpid, fromBid);
  417. sendcmd("p[%d].b[%d].txt=\"%s\"", pg_keybdAP, ob_keybdAP_show, initval);
  418. sendcmd("p[%d].b[%d].val=%d", pg_keybdAP, ob_keybdAP_inputlenth, limitLength);
  419. sendcmd("p[%d].b[%d].pw=0", pg_keybdAP, ob_keybdAP_show);
  420. chpage(pg_keybdAP, false);
  421. }
  422. void UIControler::popPasswdKeyBoard(uint8_t fromPid, uint8_t fromBid, int limitLength) {
  423. zlock_guard lg(m_cmdlock);
  424. UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
  425. sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_loadpageid, fromPid);
  426. sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_loadcmpid, fromBid);
  427. sendcmd("p[%d].b[%d].txt=\"%s\"", pg_keybdB, ob_keybdB_show, "");
  428. sendcmd("p[%d].b[%d].pw=1", pg_keybdB, ob_keybdB_show);
  429. sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_inputlenth, limitLength);
  430. visEx(pg_keybdB, ob_keybdB_b11, false); // '-'
  431. visEx(pg_keybdB, ob_keybdB_b10, false); // '.'
  432. chpage(pg_keybdB, false);
  433. }
  434. void UIControler::popNumKeyBoard(uint8_t fromPid, uint8_t fromBid, int limitLength, const char* initval, ...) {
  435. zlock_guard lg(m_cmdlock);
  436. UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
  437. static char buf[60];
  438. va_list args;
  439. va_start(args, initval);
  440. vsnprintf(buf, sizeof(buf), initval, args);
  441. va_end(args);
  442. sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_loadpageid, fromPid);
  443. sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_loadcmpid, fromBid);
  444. sendcmd("p[%d].b[%d].txt=\"%s\"", pg_keybdB, ob_keybdB_show, buf);
  445. sendcmd("p[%d].b[%d].pw=0", pg_keybdB, ob_keybdB_show);
  446. sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_inputlenth, limitLength);
  447. visEx(pg_keybdB, ob_keybdB_b11, true); // '-'
  448. visEx(pg_keybdB, ob_keybdB_b10, true); // '.'
  449. chpage(pg_keybdB, false);
  450. }
  451. void UIControler::popKeyBMutSel(uint8_t fromPid, uint8_t fromBid, int selectvalindex, const char** selectvals) {
  452. zlock_guard lg(m_cmdlock);
  453. static char contentbus[512];
  454. memset(contentbus, 0, sizeof(contentbus));
  455. for (int i = 0;; i++) {
  456. // \r\n ƴ���ַ�������
  457. if (selectvals[i] == nullptr) break;
  458. if (i == 0) {
  459. sprintf(contentbus, "%s", selectvals[i]);
  460. continue;
  461. }
  462. sprintf(contentbus, "%s\r\n%s", contentbus, selectvals[i]);
  463. }
  464. popKeyBMutSel(fromPid, fromBid, selectvalindex, contentbus);
  465. }
  466. void UIControler::popKeyBMutSel(uint8_t fromPid, uint8_t fromBid, int selectvalindex, const char* selectvals) {
  467. zlock_guard lg(m_cmdlock);
  468. UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
  469. sendcmd("p[%d].b[%d].val=%d", pg_keybMutSel, ob_keybMutSel_loadpageid, fromPid);
  470. sendcmd("p[%d].b[%d].val=%d", pg_keybMutSel, ob_keybMutSel_loadcmpid, fromBid);
  471. sendcmd("p[%d].b[%d].val=%d", pg_keybMutSel, ob_keybMutSel_ctent, selectvalindex);
  472. chpage(pg_keybMutSel, false); // ���л�ҳ�棬������ѡ��
  473. sendcmd("p[%d].b[%d].path=\"%s\"", pg_keybMutSel, ob_keybMutSel_ctent, selectvals);
  474. }
  475. void UIControler::popKeyBMutSelFix(uint8_t fromPid, uint8_t fromBid, int selectvalindex, const char* keyboardName, const char** selectvals) {
  476. int selectValsNum = 0;
  477. uint8_t pgNum = pg_keybMutSelFix;
  478. UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
  479. static uint8_t selbid_table[] = {
  480. ob_keybMutSelFix_b0, //
  481. ob_keybMutSelFix_b1, //
  482. ob_keybMutSelFix_b2, //
  483. ob_keybMutSelFix_b3, //
  484. ob_keybMutSelFix_b4, //
  485. ob_keybMutSelFix_b5, //
  486. ob_keybMutSelFix_b6, //
  487. ob_keybMutSelFix_b7, //
  488. ob_keybMutSelFix_b8, //
  489. ob_keybMutSelFix_b9, //
  490. ob_keybMutSelFix_b10, //
  491. ob_keybMutSelFix_b11, //
  492. ob_keybMutSelFix_b12, //
  493. ob_keybMutSelFix_b13, //
  494. ob_keybMutSelFix_b14, //
  495. };
  496. static uint8_t selmaskbid_table[] = {
  497. ob_keybMutSelFix_t0, //
  498. ob_keybMutSelFix_t1, //
  499. ob_keybMutSelFix_t2, //
  500. ob_keybMutSelFix_t3, //
  501. ob_keybMutSelFix_t4, //
  502. ob_keybMutSelFix_t5, //
  503. ob_keybMutSelFix_t6, //
  504. ob_keybMutSelFix_t7, //
  505. ob_keybMutSelFix_t8, //
  506. ob_keybMutSelFix_t9, //
  507. ob_keybMutSelFix_t10, //
  508. ob_keybMutSelFix_t11, //
  509. ob_keybMutSelFix_t12, //
  510. ob_keybMutSelFix_t13, //
  511. ob_keybMutSelFix_t14, //
  512. };
  513. for (int i = 0;; i++) {
  514. if (selectvals[i] == nullptr) break;
  515. selectValsNum++;
  516. }
  517. if (selectValsNum > sizeof(selbid_table) / sizeof(selbid_table[0])) {
  518. ZLOGE(TAG, "selectvals num is too large");
  519. return;
  520. }
  521. if (selectvalindex >= selectValsNum) {
  522. ZLOGE(TAG, "selectvalindex is too large");
  523. return;
  524. }
  525. zlock_guard lg(m_cmdlock);
  526. sendcmd("p[%d].b[%d].val=%d", pgNum, ob_keybMutSelFix_loadpageid, fromPid);
  527. sendcmd("p[%d].b[%d].val=%d", pgNum, ob_keybMutSelFix_loadcmpid, fromBid);
  528. sendcmd("p[%d].b[%d].val=%d", pgNum, ob_keybMutSelFix_val, selectvalindex);
  529. sendcmd("p[%d].b[%d].txt=%d", pgNum, ob_keybMutSelFix_txt, selectvals[selectvalindex]);
  530. sendcmd("p[%d].b[%d].txt=\"%s\"", pgNum, ob_keybMutSelFix_keybtil, keyboardName);
  531. chpage(pgNum, false); // ���л�ҳ�棬������ѡ��
  532. // ����ѡ��
  533. for (int i = 0; i < selectValsNum; i++) {
  534. // visEx(pgNum, selbid_table[i], true);
  535. sendcmd("p[%d].b[%d].txt=\"%s\"", pgNum, selbid_table[i], selectvals[i]);
  536. }
  537. // ���ն�����ѡ��
  538. for (int i = selectValsNum; i < sizeof(selbid_table) / sizeof(selbid_table[0]); i++) {
  539. sendcmd("p[%d].b[%d].txt=\"\"", pgNum, selbid_table[i], selectvals[i]);
  540. }
  541. for (int i = 0; i < selectValsNum; i++) {
  542. movePicToXY(pgNum, selmaskbid_table[i], -100, -100);
  543. }
  544. for (int i = selectValsNum; i < sizeof(selbid_table) / sizeof(selbid_table[0]); i++) {
  545. movePicTo(pgNum, selmaskbid_table[i], selbid_table[i]);
  546. }
  547. }