From dbb91bca9afe45c4b62fcc7629dcc5bc2f24fe7b Mon Sep 17 00:00:00 2001
From: lgq <1015864684@qq.com>
Date: 星期一, 13 四月 2026 11:54:21 +0800
Subject: [PATCH] 1.完善模块文件和库文件 2.修复NFC功能,当前支持人脸、指纹、刷卡组合认证 删除: vf107/dxmodules/dxNfc.js 新文件: vf107/dxmodules/dxUi.js 新文件: vf107/dxmodules/libvbar-m-dxhttp.so 新文件: vf107/dxmodules/libvbar-m-dxui.so 新文件: vf107/dxmodules/uiBase.js 新文件: vf107/dxmodules/uiButton.js 新文件: vf107/dxmodules/uiButtons.js 新文件: vf107/dxmodules/uiCheckbox.js 新文件: vf107/dxmodules/uiDropdown.js 新文件: vf107/dxmodules/uiFont.js 新文件: vf107/dxmodules/uiImage.js 新文件: vf107/dxmodules/uiKeyboard.js 新文件: vf107/dxmodules/uiLabel.js 新文件: vf107/dxmodules/uiLine.js 新文件: vf107/dxmodules/uiList.js 新文件: vf107/dxmodules/uiSlider.js 新文件: vf107/dxmodules/uiStyle.js 新文件: vf107/dxmodules/uiSwitch.js 新文件: vf107/dxmodules/uiTextarea.js 新文件: vf107/dxmodules/uiUtils.js 新文件: vf107/dxmodules/uiView.js 修改: vf107/src/controller.js 修改: vf107/src/driver.js 修改: vf107/src/main.js
---
vf107/dxmodules/uiFont.js | 18
vf107/dxmodules/uiView.js | 27
vf107/dxmodules/uiSlider.js | 42 +
vf107/src/driver.js | 36
vf107/dxmodules/uiLabel.js | 34
vf107/dxmodules/uiImage.js | 27
vf107/dxmodules/uiStyle.js | 149 +++
vf107/dxmodules/uiButtons.js | 107 ++
vf107/dxmodules/uiCheckbox.js | 48 +
vf107/dxmodules/uiBase.js | 597 ++++++++++++++
vf107/dxmodules/uiUtils.js | 301 +++++++
vf107/dxmodules/uiTextarea.js | 76 +
vf107/dxmodules/uiSwitch.js | 49 +
vf107/dxmodules/uiButton.js | 16
vf107/.temp/md5snew.json | 27
vf107/dxmodules/uiList.js | 45 +
vf107/src/main.js | 6
vf107/dxmodules/uiKeyboard.js | 102 ++
vf107/.temp/md5s.json | 27
vf107/dxmodules/libvbar-m-dxui.so | 0
vf107/src/controller.js | 12
/dev/null | 409 ---------
vf107/dxmodules/libvbar-m-dxhttp.so | 0
vf107/dxmodules/uiDropdown.js | 53 +
vf107/dxmodules/dxUi.js | 216 +++++
vf107/dxmodules/uiLine.js | 24
26 files changed, 2,004 insertions(+), 444 deletions(-)
diff --git a/vf107/.temp/md5s.json b/vf107/.temp/md5s.json
index 5355e9c..e50cb99 100644
--- a/vf107/.temp/md5s.json
+++ b/vf107/.temp/md5s.json
@@ -60,7 +60,6 @@
"dxmodules\\dxMap.js": "61c9b76b7e05e4e8bebeccd1dfaaa963",
"dxmodules\\dxMqttClient.js": "d18248384c1ecee412c1f1ba86c233ac",
"dxmodules\\dxNetwork.js": "e377baf713245bf54012d56ea15b48d2",
- "dxmodules\\dxNfc.js": "feb5bc21d4b13ab9736de1941290312d",
"dxmodules\\dxNfcCard.js": "689161d840c1ee82107e55b3e43da5c3",
"dxmodules\\dxNtp.js": "54a83064faa67f8f4991e1da56a3caf4",
"dxmodules\\dxOs.js": "8171120055734e75dd6c878862ae965a",
@@ -71,6 +70,7 @@
"dxmodules\\dxStd.js": "322e8885cd0c7d2d9137b47fec8c8b00",
"dxmodules\\dxTimeZones.js": "c05c66e1fc1dfea0aca722f148190148",
"dxmodules\\dxUart.js": "0cb032a9f73a894b601ff7fef1c648e7",
+ "dxmodules\\dxUi.js": "ca489da8327242bbbae73b7d10b35bf4",
"dxmodules\\dxVgBle.js": "348e4999a1c77d85bfc962c6fbdcc742",
"dxmodules\\dxWatchdog.js": "4833387ea9787b18a8c75a4ffc57b35e",
"dxmodules\\dxWorkerPool.js": "77ec46afea15eac3ff99c41fb23f43ff",
@@ -100,6 +100,7 @@
"dxmodules\\libvbar-m-dxcommonutils.so": "c72011e82a558a4e84819645700ec879",
"dxmodules\\libvbar-m-dxdisplay.so": "4de71b250645bcf8e63da84015976196",
"dxmodules\\libvbar-m-dxfacial.so": "a401e8e0460a881d748bba0cf235a5a9",
+ "dxmodules\\libvbar-m-dxhttp.so": "1ec2f9ccc26aebc390944340afde6044",
"dxmodules\\libvbar-m-dxhttpclient.so": "9d2ce48027e5afcb1e85b5703a5f1f53",
"dxmodules\\libvbar-m-dxhttpserver.so": "7238d45c439402b79b696067b3eb2ec8",
"dxmodules\\libvbar-m-dxkey.so": "e9efc4894bcd538c2a59d048ca57c70a",
@@ -110,12 +111,30 @@
"dxmodules\\libvbar-m-dxos.so": "b46dd08ab1769f5c246c284f83311294",
"dxmodules\\libvbar-m-dxsqlitedb.so": "7581e5d8a56f6d9c23885e4ceb57e4a2",
"dxmodules\\libvbar-m-dxuart.so": "e59a58bddafa0d7fa8d13387feb59946",
+ "dxmodules\\libvbar-m-dxui.so": "ca22e1a0c52977749a32b2cc70e942a9",
"dxmodules\\libvbar-m-dxwatchdog.so": "9854b627923ad943b2b34250ba717505",
"dxmodules\\libvbar-m-eid.so": "a4d1b2fa880f6d67e805dfca07f26523",
"dxmodules\\libvbar-m-key.so": "a51d6ce68a66e21865a47cf5a350ce80",
"dxmodules\\libvbar-m-net.so": "e058b3e454d27044d6544dbfe13a3254",
"dxmodules\\libvbar-p-nfc.so": "1b3af2b46962720f8f13a7c275576049",
"dxmodules\\libzbar.so": "dc72c4323c8b5616037b8ebf32740665",
+ "dxmodules\\uiBase.js": "997eb4fc071f7ff5e686b3e0fa1cad34",
+ "dxmodules\\uiButton.js": "f2baccc3c77cfcc0a57f5177acfcbb13",
+ "dxmodules\\uiButtons.js": "d3551f30ae0f00f10e02a9249a5ebbba",
+ "dxmodules\\uiCheckbox.js": "8dc6e7ef17751ef8cf738deba18b6416",
+ "dxmodules\\uiDropdown.js": "e8183f20d4a50bc99c2bb40e4c510d7b",
+ "dxmodules\\uiFont.js": "c73571e2b0bfa41aeead4f7ebc370e33",
+ "dxmodules\\uiImage.js": "af13c919b495e04690ad8f335821735c",
+ "dxmodules\\uiKeyboard.js": "d910d634f87c07ecdb2626aa7a5ad223",
+ "dxmodules\\uiLabel.js": "9ce527eccd0893fb37c3b8ed1bf14d05",
+ "dxmodules\\uiLine.js": "b96254f972313441d924e30c3d6c5716",
+ "dxmodules\\uiList.js": "1c69ce505c3627bdb2c88cf05fc1c59b",
+ "dxmodules\\uiSlider.js": "74c3e79d2a812e78f50c83663b1d513a",
+ "dxmodules\\uiStyle.js": "28f5345016754323a1dc38bfd0f74e70",
+ "dxmodules\\uiSwitch.js": "e43e240b86a749754d8c5199bb2ad482",
+ "dxmodules\\uiTextarea.js": "ca55782581a1a58ad266dfaa5247051d",
+ "dxmodules\\uiUtils.js": "56e6983fc8ef84646665c5548fcf54e9",
+ "dxmodules\\uiView.js": "efe5bac101af8e25ccede4b0adb748ec",
"dxmodules\\vbar_version": "ecaec8f34eac0b8b086a1638030427bc",
"dxmodules\\vgUartWorker.js": "fc3e9e0051836d5063c0eecf555d9521",
"dxmodules\\zoneinfo\\Africa\\Abidjan": "74c6fb9ae4ea68d0012c1f6ad42b5848",
@@ -2652,9 +2671,9 @@
"src\\common\\utils\\tokenUtil.js": "b7abd3698644aadb7d3e936fb6f7fc8b",
"src\\common\\utils\\utils.js": "bbee074a060e962a570dddc4d586504d",
"src\\config.json": "6619f6367ac0230030de3131160a2178",
- "src\\controller.js": "3ca7b098eaf218df5e911fea64113d11",
- "src\\driver.js": "94ef548d913eb6ba832e87e1748f2bc2",
- "src\\main.js": "e5958b02098ba5d92c159970c2e9bd63",
+ "src\\controller.js": "954bd6baaf4a7f91b7534f71b0e2365b",
+ "src\\driver.js": "42e819e90d7d5b00191447edb06e928c",
+ "src\\main.js": "51de780e61133a6f39ba5554dacf7644",
"src\\screen.js": "b8a256f4f3ba51b4c1e49fcb69e06b28",
"src\\service\\accessService.js": "304718a9a06ded28947373c3d9a21295",
"src\\service\\api.js": "def5b52441ccc827913a73478cc7c32a",
diff --git a/vf107/.temp/md5snew.json b/vf107/.temp/md5snew.json
index 5355e9c..e50cb99 100644
--- a/vf107/.temp/md5snew.json
+++ b/vf107/.temp/md5snew.json
@@ -60,7 +60,6 @@
"dxmodules\\dxMap.js": "61c9b76b7e05e4e8bebeccd1dfaaa963",
"dxmodules\\dxMqttClient.js": "d18248384c1ecee412c1f1ba86c233ac",
"dxmodules\\dxNetwork.js": "e377baf713245bf54012d56ea15b48d2",
- "dxmodules\\dxNfc.js": "feb5bc21d4b13ab9736de1941290312d",
"dxmodules\\dxNfcCard.js": "689161d840c1ee82107e55b3e43da5c3",
"dxmodules\\dxNtp.js": "54a83064faa67f8f4991e1da56a3caf4",
"dxmodules\\dxOs.js": "8171120055734e75dd6c878862ae965a",
@@ -71,6 +70,7 @@
"dxmodules\\dxStd.js": "322e8885cd0c7d2d9137b47fec8c8b00",
"dxmodules\\dxTimeZones.js": "c05c66e1fc1dfea0aca722f148190148",
"dxmodules\\dxUart.js": "0cb032a9f73a894b601ff7fef1c648e7",
+ "dxmodules\\dxUi.js": "ca489da8327242bbbae73b7d10b35bf4",
"dxmodules\\dxVgBle.js": "348e4999a1c77d85bfc962c6fbdcc742",
"dxmodules\\dxWatchdog.js": "4833387ea9787b18a8c75a4ffc57b35e",
"dxmodules\\dxWorkerPool.js": "77ec46afea15eac3ff99c41fb23f43ff",
@@ -100,6 +100,7 @@
"dxmodules\\libvbar-m-dxcommonutils.so": "c72011e82a558a4e84819645700ec879",
"dxmodules\\libvbar-m-dxdisplay.so": "4de71b250645bcf8e63da84015976196",
"dxmodules\\libvbar-m-dxfacial.so": "a401e8e0460a881d748bba0cf235a5a9",
+ "dxmodules\\libvbar-m-dxhttp.so": "1ec2f9ccc26aebc390944340afde6044",
"dxmodules\\libvbar-m-dxhttpclient.so": "9d2ce48027e5afcb1e85b5703a5f1f53",
"dxmodules\\libvbar-m-dxhttpserver.so": "7238d45c439402b79b696067b3eb2ec8",
"dxmodules\\libvbar-m-dxkey.so": "e9efc4894bcd538c2a59d048ca57c70a",
@@ -110,12 +111,30 @@
"dxmodules\\libvbar-m-dxos.so": "b46dd08ab1769f5c246c284f83311294",
"dxmodules\\libvbar-m-dxsqlitedb.so": "7581e5d8a56f6d9c23885e4ceb57e4a2",
"dxmodules\\libvbar-m-dxuart.so": "e59a58bddafa0d7fa8d13387feb59946",
+ "dxmodules\\libvbar-m-dxui.so": "ca22e1a0c52977749a32b2cc70e942a9",
"dxmodules\\libvbar-m-dxwatchdog.so": "9854b627923ad943b2b34250ba717505",
"dxmodules\\libvbar-m-eid.so": "a4d1b2fa880f6d67e805dfca07f26523",
"dxmodules\\libvbar-m-key.so": "a51d6ce68a66e21865a47cf5a350ce80",
"dxmodules\\libvbar-m-net.so": "e058b3e454d27044d6544dbfe13a3254",
"dxmodules\\libvbar-p-nfc.so": "1b3af2b46962720f8f13a7c275576049",
"dxmodules\\libzbar.so": "dc72c4323c8b5616037b8ebf32740665",
+ "dxmodules\\uiBase.js": "997eb4fc071f7ff5e686b3e0fa1cad34",
+ "dxmodules\\uiButton.js": "f2baccc3c77cfcc0a57f5177acfcbb13",
+ "dxmodules\\uiButtons.js": "d3551f30ae0f00f10e02a9249a5ebbba",
+ "dxmodules\\uiCheckbox.js": "8dc6e7ef17751ef8cf738deba18b6416",
+ "dxmodules\\uiDropdown.js": "e8183f20d4a50bc99c2bb40e4c510d7b",
+ "dxmodules\\uiFont.js": "c73571e2b0bfa41aeead4f7ebc370e33",
+ "dxmodules\\uiImage.js": "af13c919b495e04690ad8f335821735c",
+ "dxmodules\\uiKeyboard.js": "d910d634f87c07ecdb2626aa7a5ad223",
+ "dxmodules\\uiLabel.js": "9ce527eccd0893fb37c3b8ed1bf14d05",
+ "dxmodules\\uiLine.js": "b96254f972313441d924e30c3d6c5716",
+ "dxmodules\\uiList.js": "1c69ce505c3627bdb2c88cf05fc1c59b",
+ "dxmodules\\uiSlider.js": "74c3e79d2a812e78f50c83663b1d513a",
+ "dxmodules\\uiStyle.js": "28f5345016754323a1dc38bfd0f74e70",
+ "dxmodules\\uiSwitch.js": "e43e240b86a749754d8c5199bb2ad482",
+ "dxmodules\\uiTextarea.js": "ca55782581a1a58ad266dfaa5247051d",
+ "dxmodules\\uiUtils.js": "56e6983fc8ef84646665c5548fcf54e9",
+ "dxmodules\\uiView.js": "efe5bac101af8e25ccede4b0adb748ec",
"dxmodules\\vbar_version": "ecaec8f34eac0b8b086a1638030427bc",
"dxmodules\\vgUartWorker.js": "fc3e9e0051836d5063c0eecf555d9521",
"dxmodules\\zoneinfo\\Africa\\Abidjan": "74c6fb9ae4ea68d0012c1f6ad42b5848",
@@ -2652,9 +2671,9 @@
"src\\common\\utils\\tokenUtil.js": "b7abd3698644aadb7d3e936fb6f7fc8b",
"src\\common\\utils\\utils.js": "bbee074a060e962a570dddc4d586504d",
"src\\config.json": "6619f6367ac0230030de3131160a2178",
- "src\\controller.js": "3ca7b098eaf218df5e911fea64113d11",
- "src\\driver.js": "94ef548d913eb6ba832e87e1748f2bc2",
- "src\\main.js": "e5958b02098ba5d92c159970c2e9bd63",
+ "src\\controller.js": "954bd6baaf4a7f91b7534f71b0e2365b",
+ "src\\driver.js": "42e819e90d7d5b00191447edb06e928c",
+ "src\\main.js": "51de780e61133a6f39ba5554dacf7644",
"src\\screen.js": "b8a256f4f3ba51b4c1e49fcb69e06b28",
"src\\service\\accessService.js": "304718a9a06ded28947373c3d9a21295",
"src\\service\\api.js": "def5b52441ccc827913a73478cc7c32a",
diff --git a/vf107/dxmodules/dxNfc.js b/vf107/dxmodules/dxNfc.js
deleted file mode 100644
index 377c6c4..0000000
--- a/vf107/dxmodules/dxNfc.js
+++ /dev/null
@@ -1,409 +0,0 @@
-//build:20240715
-//閫氳繃杩欎釜缁勪欢鏉ヨ鍙栧崱锛屽寘鎷琈1鍗★紝psam鍗′箣绫荤殑
-//渚濊禆缁勪欢: dxDriver,dxMap,dxLogger,dxDriver,dxCommon,dxEventBus
-import { nfcClass } from './libvbar-p-dxnfc.so'
-import dxCommon from './dxCommon.js'
-import bus from './dxEventBus.js'
-import dxMap from './dxMap.js'
-const nfcObj = new nfcClass();
-const map = dxMap.get("default")
-const nfc = {}
-
-/**
- * NFC 鍒濆鍖�
- * @param {number} useEid 闈炲繀濉紝鏄惁浣跨敤浜戣瘉 0涓嶄娇鐢� 1浣跨敤
- */
-nfc.init = function (useEid = 0) {
- let pointer = nfcObj.init(useEid)
- if (pointer === undefined || pointer === null) {
- throw new Error("nfc.init: init failed")
- }
- dxCommon.handleId("nfc", 'nfcid', pointer)
-}
-
-/**
- * NFC 鏅�氬崱娉ㄥ唽鍥炶皟
- */
-nfc.cbRegister = function (callback) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- return nfcObj.cbRegister(pointer, "nfc_cb", 1, callback)
-}
-
-/**
- * NFC PSAM鍗℃敞鍐屽洖璋�
- */
-nfc.psamCbRegister = function (callback) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- return nfcObj.nfcPsamCheckVgcardCallback(pointer, callback)
-}
-
-/**
- * NFC 鍙栨秷鍒濆鍖�
- */
-nfc.deinit = function () {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- let ret = nfcObj.cbUnregister(pointer, "nfc_cb")
- if (ret === false) {
- throw new Error("nfc.cbUnregister: cbUnregister failed")
- }
- return nfcObj.deinit(pointer)
-}
-
-/**
- * NFC 鍗′俊鎭垱寤�
- * @param {number} cardType 鍗¤姱鐗囩被鍨�(鍘熷巶瀹氫箟)
- * @param {ArrayBuffer} cardId 鍗″彿
- * @param {number} type 鍗$被鍨�(鎴戜滑鑷繁瀹氫箟鐨�)
- * @returns cardInfo(pointer)
- */
-nfc.cardInfoCreate = function (cardType, cardId, type) {
- if (!cardType) {
- throw new Error("cardInfoCreate:cardType should not be null or empty")
- }
- if (!cardId) {
- throw new Error("cardInfoCreate:cardId should not be null or empty")
- }
- if (!type) {
- throw new Error("cardInfoCreate:type should not be null or empty")
- }
- return nfcObj.cardInfoCreate(cardType, cardId, type);
-}
-
-/**
- * NFC 鍗′俊鎭攢姣�
- * @param {pointer} cardInfo 鍗′俊鎭�
- * @returns
- */
-nfc.cardInfoDestory = function (cardInfo) {
- if (!cardInfo) {
- throw new Error("cardInfoDestory:cardInfo should not be null or empty")
- }
- return nfcObj.cardInfoDestory(cardInfo);
-}
-
-/**
- * NFC 鍗′俊鎭鍒�
- * @param {pointer} cardInfo 鍗′俊鎭�
- * @returns cardInfo(pointer)
- */
-nfc.cardInfoCopy = function (cardInfo) {
- if (cardInfo == null) {
- throw new Error("cardInfoCopy:cardInfo should not be null or empty")
- }
- return nfcObj.cardInfoCopy(cardInfo);
-}
-
-/**
- * NFC 鍒ゆ柇鏄惁鏈夊崱
- * @returns bool
- */
-nfc.isCardIn = function () {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- return nfcObj.isCardIn(pointer);
-}
-
-/**
- * NFC 璇籑1鍗℃墖鍖�
- * @param {number} taskFlg 浠诲姟鏍囧織锛�
- * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
- * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
- * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
- * @param {number} secNum 鎵囧尯鍙�
- * @param {number} logicBlkNum 鍧楀彿锛堝湪鎵囧尯鍐呯殑閫昏緫鍙�0~3)
- * @param {number} blkNums 鍧楁暟
- * @param {array} key 瀵嗛挜, 闀垮害6bytes
- * @param {number} keyType 瀵嗛挜绫诲瀷: A:0x60 B:0x61
- * @returns Array 璇诲彇缁撴灉 undefined:澶辫触
- */
-nfc.m1cardReadSector = function (taskFlg, secNum, logicBlkNum, blkNums, key, keyType) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- _validate('m1cardReadSector', taskFlg, secNum, logicBlkNum, blkNums, key, keyType, ' ')
- return nfcObj.m1cardReadSector(pointer, taskFlg, secNum, logicBlkNum, blkNums, key, keyType);
-}
-
-/**
- * NFC 璇籑1鍗℃墖鍖�
- * @param {number} taskFlg 浠诲姟鏍囧織锛�
- * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
- * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
- * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
- * @param {number} secNum 鎵囧尯鍙�
- * @param {number} logicBlkNum 鍧楀彿锛堝湪鎵囧尯鍐呯殑閫昏緫鍙�0~3)
- * @param {number} blkNums 鍧楁暟
- * @param {array} key 瀵嗛挜, 闀垮害6bytes
- * @param {number} keyType 瀵嗛挜绫诲瀷: A:0x60 B:0x61
- * @param {array} data 鍐欏叆鏁版嵁
- * @returns int 鍐欏叆闀垮害 -1:閿欒
- */
-nfc.m1cardWriteSector = function (taskFlg, secNum, logicBlkNum, blkNums, key, keyType, data) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- _validate('m1cardWriteSector', taskFlg, secNum, logicBlkNum, blkNums, key, keyType, data)
- return nfcObj.m1cardWriteSector(pointer, taskFlg, secNum, logicBlkNum, blkNums, key, keyType, data);
-}
-
-/**
- *
- * @param {number} taskFlg 浠诲姟鏍囧織锛�
- * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
- * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
- * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
- * @param {number} blkNums 鍧楀彿
- * @param {array} key 瀵嗛挜, 闀垮害6bytes
- * @param {number} keyType 瀵嗛挜绫诲瀷: A:0x60 B:0x61
- * @returns Array 璇诲彇缁撴灉 undefined:澶辫触
- */
-nfc.m1cardReadBlk = function (taskFlg, blkNum, key, keyType) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- _validate('m1cardReadBlk', taskFlg, 1, 0, blkNum, key, keyType, ' ')
- return nfcObj.m1cardReadBlk(pointer, taskFlg, blkNum, key, keyType);
-}
-
-/**
- *
- * @param {number} taskFlg 浠诲姟鏍囧織锛�
- * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
- * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
- * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
- * @param {number} blkNums 鍧楀彿
- * @param {array} key 瀵嗛挜, 闀垮害6bytes
- * @param {number} keyType 瀵嗛挜绫诲瀷: A:0x60 B:0x61
- * @param {array} data 鍐欏叆鏁版嵁
- * @returns int 鍐欏叆闀垮害 -1:閿欒
- */
-nfc.m1cardWriteBlk = function (taskFlg, blkNum, key, keyType, data) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- _validate('m1cardWriteBlk', taskFlg, 1, 0, blkNum, key, keyType, data)
- return nfcObj.m1cardWriteBlk(pointer, taskFlg, blkNum, key, keyType, data);
-}
-/**
- * ATS妫�娴�
- */
-nfc.nfc_iso14443_type_a_get_ats = function () {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- return nfcObj.nfc_iso14443_type_a_get_ats(pointer)
-}
-
-/**
- *
- * @param {number} taskFlg 浠诲姟鏍囧織锛�
- * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
- * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
- * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
- * @param {ArrayBuffer} buffer 瑕佸彂閫佺殑鏁版嵁
- * @param {number} bufferLen 瑕佸彂閫佺殑鏁版嵁闀垮害
- * @returns buffer
- */
-nfc.iso14443Apdu = function (taskFlg, buffer, bufferLen) {
- let pointer = dxCommon.handleId("nfc", "nfcid")
- return nfcObj.iso14443Apdu(pointer, taskFlg, buffer, bufferLen);
-}
-
-/**
- * PSAM鍗℃柇鐢�
- */
-nfc.nfcPsamPowerDown = function () {
- let pointer = dxCommon.handleId("nfc", "nfcid")
- return nfcObj.nfcPsamPowerDown(pointer);
-}
-
-/**
- * NFC 鏀瑰彉鐘舵��
- */
-nfc.nfcPsamChangeBaud = function () {
- let pointer = dxCommon.handleId("nfc", "nfcid")
- return nfcObj.nfcPsamChangeBaud(pointer);
-}
-
-/**
- * PSAM鍗¢噸缃�
- */
-nfc.nfcPsamCardReset = function (force) {
- let pointer = dxCommon.handleId("nfc", "nfcid")
- return nfcObj.nfcPsamCardReset(pointer, force);
-}
-
-/**
- * 鍙戦�丳SAM APDU鎸囦护
- */
-nfc.nfcPsamCardApdu = function (buffer) {
- let pointer = dxCommon.handleId("nfc", "nfcid")
- return nfcObj.nfcPsamCardApdu(pointer, buffer);
-}
-
-/**
- * EID 鏇存柊浜戣瘉閰嶇疆
- * @param {object} eidConfig 浜戣瘉閰嶇疆
- * @param {string} eidConfig.appid 骞冲彴鍒嗛厤缁欏簲鐢ㄧ殑appid
- * @param {number} eidConfig.read_len; // 鍗曟璇诲崱闀垮害锛岄粯璁�0x80
- * @param {number} eidConfig.declevel; // 鏄惁璇诲彇鐓х墖锛�1涓轰笉璇诲彇锛�2涓鸿鍙�
- * @param {number} eidConfig.loglevel; //鏃ュ織绾у埆锛屾敮鎸�0锛�1锛�2
- * @param {number} eidConfig.model; // 鏄惁鐩存帴鏌ュ嚭淇℃伅 0鏄� 1鍚� 锛堝嵆0鏄師璺繑鍥烇紝杩斿洖韬唤淇℃伅锛�1鏄浆鍙戯紝杩斿洖reqid锛�
- * @param {number} eidConfig.type; // 鍗$墖绫诲瀷锛�0 韬唤璇� 1鐢靛瓙璇佺収
- * @param {number} eidConfig.pic_type; // 鐓х墖瑙g爜鏁版嵁绫诲瀷 0 wlt 1 jpg
- * @param {number} eidConfig.envCode; // 鐜璇嗗埆鐮�
- * @param {string} eidConfig.sn[128]; // 璁惧搴忓垪鍙�
- * @param {string} eidConfig.device_model[128]; // 璁惧鍨嬪彿
- * @param {number} eidConfig.info_type; // 淇℃伅杩斿洖绫诲瀷锛�0 韬唤淇℃伅缁撴瀯浣� 锛�1鍘熷鏁版嵁 char
- */
-nfc.eidUpdateConfig = function (eidConfig) {
- if (eidConfig == null) {
- throw new Error("eidUpdateConfig:eidConfig should not be null or empty")
- }
- return nfcObj.eidUpdateConfig(eidConfig);
-}
-
-/**
- * 璇籒TAG鐗堟湰鍙�
- * @param {number} hdl nfc鍙ユ焺
- * @returns {ArrayBuffer} buffer
- */
-nfc.nfcNtagReadVersion = function () {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- return nfcObj.nfcNtagReadVersion(pointer);
-}
-
-/**
- * 璇籒TAG椤靛唴瀹� 鍥哄畾璇诲彇4椤靛叡16瀛楄妭
- * @param {number} hdl nfc鍙ユ焺
- * @param {number} pageNum 璧峰椤靛湴鍧�锛�
- * 姣忔璇诲彇鍥涗釜椤�
- * 濡傛灉鍦板潃(Addr)鏄�04h锛屽垯杩斿洖椤�04h銆�05h銆�06h銆�07h鍐呭
- * @returns {ArrayBuffer} buffer
- */
-nfc.nfcNtagReadPage = function (pageNum) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- if (pageNum == null) {
- throw new Error("nfcNtagReadPage:pageNum should not be null or empty")
- }
- return nfcObj.nfcNtagReadPage(pointer, pageNum);
-}
-
-/**
- * 璇籒TAG澶氶〉鍐呭 璇诲彇鏁版嵁鐨刡uffer,鏈�灏忎负 椤垫暟*4锛涜璇诲彇鐨勬暟鎹暱搴� 椤垫暟*4
- * @param {number} hdl nfc鍙ユ焺
-* @param {number} start_addr 璧峰椤靛湴鍧�
- * @param {number} end_addr 缁撴潫椤靛湴鍧�
- * @returns {ArrayBuffer} buffer
- */
-nfc.nfcNtagFastReadPage = function (start_page, end_page) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- if (start_page == null) {
- throw new Error("nfcNtagFastReadPage:start_page should not be null or empty")
- }
- if (end_page == null) {
- throw new Error("nfcNtagFastReadPage:end_page should not be null or empty")
- }
- return nfcObj.nfcNtagFastReadPage(pointer, start_page, end_page);
-}
-
-/**
- * 鍐橬TAG椤靛唴瀹�
- * @param {number} hdl nfc鍙ユ焺
- * @param {number} pageNum 鍐欏叆鐨勯〉鍙� 锛氭湁鏁圓ddr鍙傛暟
- * 瀵逛簬NTAG213锛岄〉鍦板潃02h鑷�2Ch
- * 瀵逛簬NTAG215锛岄〉鍦板潃02h鑷�86h
- * 瀵逛簬NTAG216锛岄〉鍦板潃02h鑷矱6h
- * @param {ArrayBuffer} pageData 鍐欏叆椤电殑鍐呭锛氬洓瀛楄妭
- * @returns {boolean} ture/false
- */
-nfc.nfcNtagWritePage = function (pageNum, pageData) {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- if (pageNum == null) {
- throw new Error("nfcNtagWritePage:pageNum should not be null or empty")
- }
- if (!pageData) {
- throw new Error("nfcNtagWritePage:pageData should not be null or empty")
- }
- return nfcObj.nfcNtagWritePage(pointer, pageNum, pageData);
-}
-
-/**
- * 鍒ゆ柇nfc娑堟伅闃熷垪鏄惁涓虹┖
- * @returns bool
- */
-nfc.msgIsEmpty = function () {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- return nfcObj.msgIsEmpty(pointer)
-}
-
-/**
- * 浠巒fc娑堟伅闃熷垪涓鍙栨暟鎹�
- * @returns json娑堟伅瀵硅薄
- */
-nfc.msgReceive = function () {
- let pointer = dxCommon.handleId("nfc", 'nfcid')
- let msg = nfcObj.msgReceive(pointer)
- return JSON.parse(msg);
-}
-
-function _validate(fun, taskFlg, secNum, logicBlkNum, blkNums, key, keyType, data) {
- if (![0x00, 0x01, 0x02].includes(taskFlg)) {
- throw new Error(fun, ":taskFlg error")
- }
- if (!(secNum >= 0)) {
- throw new Error(fun, ":secNum error")
- }
- if (logicBlkNum == null || logicBlkNum == undefined || logicBlkNum < 0 || logicBlkNum > 3) {
- throw new Error(fun, ":logicBlkNum error")
- }
- if (blkNums == null || blkNums == undefined || blkNums < 0 || blkNums > 59) {
- throw new Error(fun, ":blkNums error")
- }
- if (key == null || key === undefined || key.length < 0) {
- throw new Error(fun, ":key error")
- }
- if (![0x60, 0x61].includes(keyType)) {
- throw new Error(fun, ":keyType error")
- }
- if (data === null || data === undefined) {
- throw new Error(fun, ":data error")
- }
-}
-
-nfc.RECEIVE_MSG = '__nfc__MsgReceive'
-
-/**
- * 绠�鍖朜FC缁勪欢鐨勪娇鐢紝鏃犻渶杞鍘昏幏鍙栫綉缁滅姸鎬侊紝缃戠粶鐨勭姸鎬佷細閫氳繃eventcenter鍙戦�佸嚭鍘�
- * run 鍙細鎵ц涓�娆★紝鎵ц涔嬪悗缃戠粶鍩烘湰閰嶇疆涓嶈兘淇敼
- * 濡傛灉闇�瑕佸疄鏃惰幏鍙栧埛鍗℃暟鎹紝鍙互璁㈤槄 eventCenter鐨勪簨浠讹紝浜嬩欢鐨則opic鏄痭fc.CARD锛屼簨浠剁殑鍐呭鏄被浼�
- * {id:'鍗d',card_type:鍗¤姱鐗囩被鍨�,id_len:鍗″彿闀垮害,type锛氬崱绫诲瀷,timestamp:'鍒峰崱鏃堕棿鎴�',monotonic_timestamp:'鐩稿寮�鏈虹殑鏃堕棿'}
- * @param {*} options
- * @param {boolean} options.m1 闈炲繀濉紝鏅�氬崱鍥炶皟寮�鍏�
- * @param {boolean} options.psam 闈炲繀濉紝psam鍗″洖璋冨紑鍏�
- */
-nfc.run = function (options) {
- if (options === undefined || options.length === 0) {
- throw new Error("dxnfc.run:'options' parameter should not be null or empty")
- }
- let init = map.get("__nfc__run_init")
- if (!init) {//纭繚鍙垵濮嬪寲涓�娆�
- map.put("__nfc__run_init", options)
- bus.newWorker("__nfc", '/app/code/dxmodules/nfcWorker.js')
- }
-}
-
-/**
- * 濡傛灉nfc鍗曠嫭涓�涓嚎绋嬶紝鍙互鐩存帴浣跨敤run鍑芥暟锛屼細鑷姩鍚姩涓�涓嚎绋嬶紝
- * 濡傛灉鎯冲姞鍏ュ埌鍏朵粬宸叉湁鐨勭嚎绋嬶紝鍙互浣跨敤浠ヤ笅灏佽鐨勫嚱鏁�
- */
-nfc.worker = {
- //鍦╳hile寰幆鍓�
- beforeLoop: function (options) {
- nfc.init(options.useEid)
- // PSAM鍜屾櫘閫氬崱鍥炶皟
- if (options.m1) {
- nfc.cbRegister()
- }
- if (options.psam) {
- nfc.psamCbRegister()
- }
- },
- //鍦╳hile寰幆閲�
- loop: function () {
- if (!nfc.msgIsEmpty()) {
- let res = nfc.msgReceive();
- bus.fire(nfc.RECEIVE_MSG, res)
- }
- }
-}
-export default nfc;
diff --git a/vf107/dxmodules/dxUi.js b/vf107/dxmodules/dxUi.js
new file mode 100644
index 0000000..4101eda
--- /dev/null
+++ b/vf107/dxmodules/dxUi.js
@@ -0,0 +1,216 @@
+//build:20240724
+/**
+ * Basic UI components. First, you need to understand some concepts:
+ * 1. Layers: The device has 2 basic layers, the main layer (main) and the top layer (top)
+ The TOP layer is always above the main layer. Switching pages on the main layer won't cover the TOP layer. The TOP layer is suitable for displaying status bars.
+ Multiple pages can be pre-constructed in memory for the main layer, then loaded and switched using loadMain. The TOP layer cannot be switched, only hidden or deleted.
+
+ * 2. UI Objects: There are many types of UI objects. The most basic is the 'view' object. The root UI object of the main and top layers must be a 'view' object. The rest of the UI objects are children of some UI object.
+ UI objects include common 'button', 'label', 'image', etc. All objects have some common properties and some unique properties.
+ All UI objects have a globally unique id that cannot be duplicated. Common properties also include:
+ - type: Get the UI object type, string
+ - parent: Get the parent node of the UI object, string
+ - children: Get all child object ids of the UI object, string array
+
+ * 3. dxui files: Files with .dxui extension are UI trees generated by visual drag-and-drop tools. The tool automatically generates corresponding js files that can be imported and operated.
+
+ */
+
+ import logger from './dxLogger.js'
+ import utils from './uiUtils.js'
+ import button from './uiButton.js'
+ import font from './uiFont.js'
+ import image from './uiImage.js'
+ import label from './uiLabel.js'
+ import line from './uiLine.js'
+ import list from './uiList.js'
+ import dropdown from './uiDropdown.js'
+ import checkbox from './uiCheckbox.js'
+ import slider from './uiSlider.js'
+ import _switch from './uiSwitch.js'
+ import textarea from './uiTextarea.js'
+ import keyboard from './uiKeyboard.js'
+ import style from './uiStyle.js'
+ import view from './uiView.js'
+ import buttons from './uiButtons.js'
+
+ const dxui = {}
+ dxui.Button = button
+ dxui.Font = font
+ dxui.Image = image
+ dxui.Label = label
+ dxui.Line = line
+ dxui.List = list
+ dxui.Dropdown = dropdown
+ dxui.Checkbox = checkbox
+ dxui.Slider = slider
+ dxui.Switch = _switch
+ dxui.Textarea = textarea
+ dxui.Keyboard = keyboard
+ dxui.Style = style
+ dxui.View = view
+ dxui.Utils = utils
+ dxui.Buttons = buttons
+ let orientation = 1 //Default landscape
+ /**
+ * Initialize, must be called at the beginning of the code
+ * @param {object} options Initialization parameters
+ * @param {number} options.orientation Screen orientation, can be 0, 1, 2, 3, representing portrait with screen on left; landscape with screen on top; portrait with screen on right; landscape with screen on bottom
+ * @param {object} context Context, each application has a unique context variable. Different js files can reference dxUi.js, but context must be consistent
+ */
+ dxui.init = function (options, context = {}) {
+ this.initContext(context)
+ if (options && options.orientation != undefined && options.orientation != null && [0, 1, 2, 3].includes(options.orientation)) {
+ orientation = options.orientation
+ }
+ utils.GG.NativeDisp.lvDispSetRotation(orientation)
+ }
+ /**
+ * Initialize context. Each application has a unique context variable. Different js files can reference dxUi.js, but context must be consistent
+ * Context needs to be initialized before building UI
+ * @param {object} context Initially an empty object {}
+ */
+ dxui.initContext = function (context) {
+ utils.validateObject(context)
+ dxui.all = context
+ dxui.Button.all = dxui.all
+ dxui.Image.all = dxui.all
+ dxui.Label.all = dxui.all
+ dxui.Line.all = dxui.all
+ dxui.List.all = dxui.all
+ dxui.Dropdown.all = dxui.all
+ dxui.Checkbox.all = dxui.all
+ dxui.Slider.all = dxui.all
+ dxui.Switch.all = dxui.all
+ dxui.Textarea.all = dxui.all
+ dxui.Keyboard.all = dxui.all
+ dxui.View.all = dxui.all
+ dxui.Buttons.all = dxui.all
+ }
+ /**
+ * Get the already built UI object by id
+ * @param {string} id
+ * @returns
+ */
+ dxui.getUi = function (id) {
+ return dxui.all[id]
+ }
+ /**
+ * External loop needs to call this method
+ */
+ dxui.handler = function () {
+ return utils.GG.NativeTimer.lvTimerHandler()
+ }
+ /**
+ * Get screen orientation. Different screen orientations may require loading different UI or different processing logic
+ * @returns Can be 0, 1, 2, 3, representing portrait with screen on left; landscape with screen on top; portrait with screen on right; landscape with screen on bottom
+ */
+ dxui.getOrientation = function () {
+ return orientation;
+ }
+ /**
+ * Create a timer that executes the callback function every ms milliseconds, mainly used to periodically refresh a UI object's value
+ * Can delete the timer (clearInterval) in the callback function to achieve setTimeout effect
+ * @param {string} id Unique identifier for the timer Required
+ * @param {function} callback Callback function (can be anonymous function)
+ * @param {number} ms Milliseconds
+ * @param {object} user_data User data, passed to callback parameter
+ * @returns Timer handle
+ */
+ dxui.setInterval = function (id, callback, ms, user_data) {
+ if (utils.validateId(dxui.all, id))
+ if (!callback || (typeof callback != 'function') || !callback.name || callback.name === '') {
+ throw new Error('The callback should not be null and should be named function')
+ }
+ if (!ms || (typeof ms != 'number')) {
+ throw new Error('The interval should not be empty, and should be number')
+ }
+ if (!this.all.__interval) {
+ this.all.__interval = {}
+ }
+ this.all.__interval[id] = utils.GG.NativeTimer.lvTimerCreate(callback, ms, user_data)
+ }
+ /**
+ * When the timer is no longer needed, you can delete this timer
+ * @param {string} id Timer id
+ */
+ dxui.clearInterval = function (id) {
+ if (!dxui.all[id]) {
+ return
+ }
+ utils.GG.NativeTimer.lvTimerDel(dxui.all[id])
+ delete dxui.all.__interval[id]
+ }
+ /**
+ * Get the parent object of a UI object
+ * @param {Object} ui
+ */
+ dxui.getParent = function (ui) {
+ if (ui.parent) {
+ return dxui.getUi(ui.parent)
+ }
+ return null
+ }
+ /**
+ * Delete the current UI object itself
+ */
+ dxui.del = function (ui) {
+ function recursiveDelete(ui) {
+ // If the object doesn't exist, return directly
+ if (!dxui.all[ui.id]) {
+ return;
+ }
+
+ // First recursively delete all child objects
+ if (ui.children && Array.isArray(ui.children)) {
+ // Traverse child nodes in reverse order
+ for (let i = ui.children.length - 1; i >= 0; i--) {
+ const childId = ui.children[i];
+ if (dxui.all[childId]) {
+ recursiveDelete(dxui.all[childId]);
+ }
+ }
+ }
+ // Remove current object from parent object
+ if (ui.parent && dxui.all[ui.parent] && Array.isArray(dxui.all[ui.parent].children)) {
+ const children = dxui.all[ui.parent].children
+ let index = children.indexOf(ui.id);
+ if (index !== -1) {
+ children.splice(index, 1);
+ }
+ }
+
+ // Delete current object
+ ui.obj.lvObjDel();
+ delete dxui.all[ui.id];
+ }
+
+ // Start recursive deletion
+ recursiveDelete(ui);
+ }
+ /**
+ * Load (switch) an already built UI object on the main layer
+ * @param {object} ui UI object built using the build function
+ */
+ dxui.loadMain = function (ui) {
+ if (!ui || !ui.obj) {
+ throw new Error("dxui.loadMain:'ui' paramter should not be null")
+ }
+ // Load main screen
+ utils.GG.NativeDisp.lvScrLoad(ui.obj)
+ }
+ /**
+ * Time elapsed since the last user activity (such as click)
+ * @returns Returns the elapsed time since the last activity (milliseconds)
+ */
+ dxui.getIdleDuration = function () {
+ return utils.GG.NativeDisp.lvDispGetInactiveTime()
+ }
+ /**
+ * Reset the elapsed time of user activity (such as click)
+ */
+ dxui.trigActivity = function () {
+ utils.GG.NativeDisp.lvDispTrigActivity()
+ }
+
+ export default dxui;
\ No newline at end of file
diff --git a/vf107/dxmodules/libvbar-m-dxhttp.so b/vf107/dxmodules/libvbar-m-dxhttp.so
new file mode 100644
index 0000000..a654c8f
--- /dev/null
+++ b/vf107/dxmodules/libvbar-m-dxhttp.so
Binary files differ
diff --git a/vf107/dxmodules/libvbar-m-dxui.so b/vf107/dxmodules/libvbar-m-dxui.so
new file mode 100644
index 0000000..c2cd72b
--- /dev/null
+++ b/vf107/dxmodules/libvbar-m-dxui.so
Binary files differ
diff --git a/vf107/dxmodules/uiBase.js b/vf107/dxmodules/uiBase.js
new file mode 100644
index 0000000..a171868
--- /dev/null
+++ b/vf107/dxmodules/uiBase.js
@@ -0,0 +1,597 @@
+//build:20240524
+/**
+ * Base class for UI, inherited by other components. Subclasses are not allowed to modify corresponding function behavior. This js file does not need to be directly referenced or used.
+ */
+import utils from "./uiUtils.js"
+import logger from './dxLogger.js'
+import * as os from "os"
+const uibase = {}
+/**
+* Modify or get the width of the component
+* @param {number} w Optional, if not provided, get the width; otherwise, modify the width
+*/
+uibase.width = function (w) {
+ if (!utils.validateNumber(w)) {
+ return this.obj.getWidth()
+ }
+ this.obj.lvObjSetWidth(w)
+}
+/**
+* Modify or get the height of the component
+* @param {number} h Optional, if not provided, get the height; otherwise, modify the height
+*/
+uibase.height = function (h) {
+ if (!utils.validateNumber(h)) {
+ return this.obj.getHeight()
+ }
+ this.obj.lvObjSetHeight(h)
+}
+/**
+ * Get width excluding borders and padding
+ * @returns
+ */
+uibase.contentWidth = function () {
+ return this.obj.lvObjGetContentWidth()
+}
+/**
+ * Get height excluding borders and padding
+ * @returns
+ */
+uibase.contentHeight = function () {
+ return this.obj.lvObjGetContentHeight()
+}
+/**
+ * Get top scroll distance
+ * @returns
+ */
+uibase.scrollTop = function () {
+ return this.obj.getScrollTop()
+}
+/**
+ * Get bottom scroll distance
+ * @returns
+ */
+uibase.scrollBottom = function () {
+ return this.obj.getScrollBottom()
+}
+/**
+ * Get left scroll distance
+ * @returns
+ */
+uibase.scrollLeft = function () {
+ return this.obj.getScrollLeft()
+}
+/**
+ * Get right scroll distance
+ * @returns
+ */
+uibase.scrollRight = function () {
+ return this.obj.getScrollRight()
+}
+/**
+* Modify the width and height of the component
+* @param {number} w Required
+* @param {number} h Required
+*/
+uibase.setSize = function (w, h) {
+ let err = 'dxui.setSize: width or height should not be empty'
+ utils.validateNumber(w, err)
+ utils.validateNumber(h, err)
+ this.obj.lvObjSetSize(w, h)
+}
+/**
+* Modify or get the x coordinate of the component relative to the parent object
+* @param {number} x Optional, if not provided, get the x coordinate; otherwise, modify the x coordinate
+*/
+uibase.x = function (x) {
+ if (!utils.validateNumber(x)) {
+ return this.obj.getX()
+ }
+ this.obj.lvObjSetX(x)
+}
+/**
+* Modify or get the y coordinate of the component relative to the parent object
+* @param {number} y Optional, if not provided, get the y coordinate; otherwise, modify the y coordinate
+*/
+uibase.y = function (y) {
+ if (!utils.validateNumber(y)) {
+ return this.obj.getY()
+ }
+ this.obj.lvObjSetY(y)
+}
+/**
+* Modify the x and y coordinates of the component relative to the parent object
+* @param {number} x Required
+* @param {number} y Required
+*/
+uibase.setPos = function (x, y) {
+ let err = 'dxui.setPos: x or y should not be empty'
+ utils.validateNumber(x, err)
+ utils.validateNumber(y, err)
+ this.obj.lvObjSetPos(x, y)
+}
+/**
+ * Move the component to the top layer, equivalent to the last created child component of the parent object, will cover all other child components
+ */
+uibase.moveForeground = function () {
+ this.obj.moveForeground()
+}
+/**
+ * Move the component to the bottom layer, equivalent to the first created child component of the parent object, will be covered by all other child components
+ */
+uibase.moveBackground = function () {
+ this.obj.moveBackground()
+}
+/**
+ * Subscribe to events, supported event types refer to utils.EVENT
+ * @param {number} type Enum utils.EVENT, such as click, long press, etc.
+ * @param {function} cb Event trigger callback function (cannot be an anonymous function)
+ * @param {object} ud User data
+ */
+uibase.on = function (type, cb, ud) {
+ this.obj.addEventCb(() => {
+ if (cb) {
+ cb({ target: this, ud: ud })
+ }
+ }, type)
+}
+/**
+ * Send event, for example, to simulate clicking a button, you can send a CLICK event to the button
+ * @param {number} type Enum utils.EVENT, such as click, long press, etc.
+ */
+uibase.send = function (type) {
+ NativeObject.APP.NativeComponents.NativeEvent.lvEventSend(this.obj, type)
+}
+/**
+ * Hide UI object
+ */
+uibase.hide = function () {
+ if (!this.obj.hasFlag(1)) {
+ this.obj.lvObjAddFlag(1);
+ }
+}
+/**
+ * Check if hidden
+ * @returns
+ */
+uibase.isHide = function () {
+ return this.obj.hasFlag(1);
+}
+/**
+ * Show hidden UI object
+ */
+uibase.show = function () {
+ if (this.obj.hasFlag(1)) {
+ this.obj.lvObjClearFlag(1);
+ }
+}
+/**
+ * Disable/enable object
+ * @param {*} en false/true, true is disabled, false is enabled
+ */
+uibase.disable = function (en) {
+ if (en) {
+ this.obj.addState(utils.STATE.DISABLED)
+ } else {
+ this.obj.clearState(utils.STATE.DISABLED)
+ }
+}
+/**
+ * Whether object is clickable
+ * @param {*} en false/true, true is clickable, false is not clickable
+ */
+uibase.clickable = function (en) {
+ if (en) {
+ this.obj.lvObjAddFlag(utils.OBJ_FLAG.CLICKABLE)
+ } else {
+ this.obj.lvObjClearFlag(utils.OBJ_FLAG.CLICKABLE)
+ }
+}
+/**
+ * Check if disabled
+ * @returns true is disabled, false is enabled
+ */
+uibase.isDisable = function () {
+ return this.obj.hasState(utils.STATE.DISABLED)
+}
+/**
+ * Focus object
+ * @param {*} en false/true, true is focus, false is unfocus
+ */
+uibase.focus = function (en) {
+ if (en) {
+ this.obj.addState(utils.STATE.FOCUSED)
+ } else {
+ this.obj.clearState(utils.STATE.FOCUSED)
+ }
+}
+/**
+ * Check if focused
+ * @returns true is focused, false is not focused
+ */
+uibase.isFocus = function () {
+ return this.obj.hasState(utils.STATE.FOCUSED)
+}
+
+/**
+ * Set UI style, can be set individually for each style, or define a style object first and then bind it to the UI object
+ * Bind UI object and style object, can be bound to different parts or different states
+ * @param {object} style Object returned by style.js build function
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.addStyle = function (style, type) {
+ if (!style || !style.obj) {
+ throw new Error('dxui.addStyle: style should not be null')
+ }
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjAddStyle(style.obj, type);
+}
+/**
+* Set all padding (left, right, top, bottom) to one value
+* @param {number} pad Padding value
+* @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+*/
+uibase.padAll = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStylePadAll(pad, type)
+}
+/**
+ * Set/get right padding to one value
+ * @param {number} pad Padding value
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.padRight = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(pad)) {
+ return this.obj.getStylePadRight(type)
+ }
+ this.obj.setStylePadRight(pad, type)
+}
+/**
+ * Set/get left padding to one value
+ * @param {number} pad Padding value
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.padLeft = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(pad)) {
+ return this.obj.getStylePadLeft(type)
+ }
+ this.obj.setStylePadLeft(pad, type)
+}
+/**
+ * Set/get top padding to one value
+ * @param {number} pad Padding value
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.padTop = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(pad)) {
+ return this.obj.getStylePadTop(type)
+ }
+ this.obj.setStylePadTop(pad, type)
+}
+/**
+ * Set/get bottom padding to one value
+ * @param {number} pad Padding value
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.padBottom = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(pad)) {
+ return this.obj.getStylePadBottom(type)
+ }
+ this.obj.setStylePadBottom(pad, type)
+}
+/**
+ * Set/get border width
+ * @param {number} w
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.borderWidth = function (w, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(w)) {
+ return this.obj.lvObjGetStyleBorderWidth(type)
+ }
+ this.obj.lvObjSetStyleBorderWidth(w, type)
+}
+// Deprecated
+uibase.setBorderColor = function (color, type) {
+ this.borderColor(color, type)
+}
+/**
+ * Set border color
+ * @param {number} color Supports number type: e.g. 0x34ffaa; string type (starting with #), e.g.: '#34ffaa'
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.borderColor = function (color, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.setStyleBorderColor(utils.colorParse(color), type)
+}
+/**
+ * Set border radius
+ * @param {number} r
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.radius = function (r, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleRadius(r, type)
+}
+/**
+ * Set background opacity, value range is 0-100, smaller value is more transparent
+ * @param {number} opa Must be 0-100
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.bgOpa = function (opa, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleBgOpa(utils.OPA_MAPPING(opa), type)
+}
+/**
+ * Set background color
+ * @param {any} color Supports number type: e.g. 0x34ffaa; string type (starting with #), e.g.: '#34ffaa'
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.bgColor = function (color, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleBgColor(utils.colorParse(color), type)
+}
+/**
+ * Set shadow
+ * @param {number} width Shadow width
+ * @param {number} x Horizontal offset
+ * @param {number} y Vertical offset
+ * @param {number} spread Spread distance
+ * @param {number} color Color
+ * @param {number} opa Opacity, must be 0-100
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.shadow = function (width, x, y, spread, color, opa, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleShadowWidth(width, type)
+ this.obj.lvObjSetStyleShadowOfsX(x, type)
+ this.obj.lvObjSetStyleShadowOfsY(y, type)
+ this.obj.lvObjSetStyleShadowSpread(spread, type)
+ this.obj.setStyleShadowColor(color, type)
+ this.obj.setStyleShadowOpa(utils.OPA_MAPPING(opa), type)
+}
+/**
+ * Set text color
+ * @param {any} color Supports number type: e.g. 0x34ffaa; string type (starting with #), e.g.: '#34ffaa'
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.textColor = function (color, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleTextColor(utils.colorParse(color), type)
+}
+/**
+ * Set text alignment
+ * @param {number} align Refer to utils.TEXT_ALIGN
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.textAlign = function (align, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleTextAlign(align, type)
+}
+/**
+ * Set text font
+ * @param {object} font Object returned by font.js build function
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.textFont = function (font, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!font || !font.obj) {
+ throw new Error("dxui.textFont: 'font' parameter should not be null")
+ }
+ this.obj.lvObjSetStyleTextFont(font.obj, type)
+}
+/**
+ * Set line object (line) color
+ * @param {any} color Supports number type: e.g. 0x34ffaa; string type (starting with #), e.g.: '#34ffaa'
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.lineColor = function (color, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleLineColor(utils.colorParse(color), type)
+}
+/**
+ * Set line object (line) width
+ * @param {number} w
+ * @param {number} type Refer to utils.STYLE, optional, default is bound to the object itself
+ */
+uibase.lineWidth = function (w, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleLineWidth(w, type)
+}
+/**
+ * Set line object (line) rounded corners
+ * @param {boolean} enable true/false
+ */
+uibase.lineRound = function (enable) {
+ this.obj.lvObjSetStyleLineRounded(enable)
+}
+/**
+ * Set the scrollbar display mode for the UI object
+ * @param {boolean} state true/false
+ */
+uibase.scrollbarMode = function (state) {
+ this.obj.lvObjSetScrollbarMode(state)
+}
+/**
+ * Set whether the UI object supports scrolling
+ * @param {boolean} state
+ */
+uibase.scroll = function (state) {
+ if (state) {
+ this.obj.lvObjAddFlag(16)
+ } else {
+ this.obj.lvObjClearFlag(16)
+ }
+}
+/**
+ * Align the object with another reference object
+ * @param {object} ref Reference object
+ * @param {number} type Alignment direction, refer to dxui.Utils.ALIGN enum
+ * @param {number} x X offset
+ * @param {number} y Y offset
+ */
+uibase.alignTo = function (ref, type, x, y) {
+ if (!ref || !ref.obj) {
+ throw new Error("dxui.alignto: 'ref' parameter should not be null")
+ }
+ this.obj.lvObjAlignTo(ref.obj, type, x, y)
+}
+/**
+ * Align the object with its parent object
+ * @param {number} type Alignment direction, refer to dxui.Utils.ALIGN enum
+ * @param {number} x X offset
+ * @param {number} y Y offset
+ */
+uibase.align = function (type, x, y) {
+ this.obj.lvObjAlign(type, x, y)
+}
+/**
+ * Flexbox layout allows for more flexible positioning, arrangement, and distribution of elements, making it easier to create responsive and scalable layouts.
+ * It is based on a container with flexible items inside. Here are some concepts for using this layout:
+ * 1. Container: The container holds the flexible items inside and can arrange them from left to right or right to left, etc.
+ * 2. Main axis and cross axis: The main axis is the primary arrangement direction of items in the container, usually horizontal or vertical, allowing items to be arranged horizontally or vertically.
+ * The cross axis is perpendicular to the main axis and can specify how items are arranged on the cross axis.
+ * The main and cross axes are set by flexFlow(), mainly ROW (horizontal) and COLUMN (vertical). Those with WRAP suffix automatically wrap when items exceed the container, and those with REVERSE suffix arrange in the opposite direction (right to left for horizontal, bottom to top for vertical).
+ * 3. Main axis alignment: START (default main axis order), END (opposite of default main axis order), CENTER (centered on main axis), SPACE_EVENLY (evenly distributed on main axis with equal spacing), SPACE_AROUND (evenly distributed on main axis, each item gets equal space), SPACE_BETWEEN (flush at both ends, evenly spaced in between), set by flexAlign().
+ * 4. Cross axis alignment: Treat each row or column as an item, align on the cross axis direction, alignment methods same as main axis, set by flexAlign().
+ * 5. Overall alignment: Treat all items in the container as a whole, align within the container, alignment methods same as main axis, set by flexAlign().
+ * @param {number} type Main axis and cross axis settings
+ */
+uibase.flexFlow = function (type) {
+ this.obj.lvObjSetFlexFlow(type)
+}
+/**
+ *
+ * @param {number} main Child element alignment along the main axis
+ * @param {number} cross Child element alignment along the cross axis
+ * @param {number} track All child elements alignment relative to the container
+ */
+uibase.flexAlign = function (main, cross, track) {
+ this.obj.lvObjSetFlexAlign(main, cross, track)
+}
+/**
+ * Update the size of a control. When getting a control's size returns 0, call this first, equivalent to updating the display cache.
+ */
+uibase.update = function () {
+ this.obj.lvObjUpdateLayout()
+}
+/**
+ * Add a state to a control
+ * @param {number} state State enum
+ */
+uibase.addState = function (state) {
+ this.obj.addState(state)
+}
+/**
+ * Remove a state from a control. To unfocus a focused input box, call this method to remove the FOCUSED state
+ * @param {number} state State enum
+ */
+uibase.clearState = function (state) {
+ this.obj.clearState(state)
+}
+/**
+ * Check if a control has a state. To check if an input box is focused, use this method with the FOCUSED parameter
+ * @param {number} state State enum
+ * @returns true/false
+ */
+uibase.hasState = function (state) {
+ return this.obj.hasState(state)
+}
+/**
+ * Redraw a control, force refresh the control's cache. Can forcefully solve screen artifacts, but calling in a loop will reduce performance
+ */
+uibase.invalidate = function () {
+ this.obj.invalidate()
+}
+/**
+ * Scroll a child control until it's visible. If an item has been scrolled outside the container and is not visible, call this method to scroll it into view.
+ * @param {boolean} en Whether to enable animation, enabled will scroll slowly, disabled will jump directly
+ * @param {boolean} notRecursive Default recursive, suitable for general scrolling and nested scrolling controls
+ */
+uibase.scrollToView = function (en, isRecursive) {
+ if (isRecursive) {
+ this.obj.scrollToView(en)
+ } else {
+ this.obj.scrollToViewRecursive(en)
+ }
+}
+/**
+ * Scroll a control in the x direction
+ * @param {number} x Scroll distance on x-axis
+ * @param {boolean} en Whether to enable animation
+ */
+uibase.scrollToX = function (x, en) {
+ this.obj.scrollToX(x, en)
+}
+/**
+ * Scroll a control in the y direction
+ * @param {number} y Scroll distance on y-axis
+ * @param {boolean} en Whether to enable animation
+ */
+uibase.scrollToY = function (y, en) {
+ this.obj.scrollToY(y, en)
+}
+/**
+ * Element snapshot (essentially a screenshot. To save a full screen screenshot, use this method on the screen object)
+ * @param {string} fileName Required, filename to save the snapshot (note: extension should match the format)
+ * @param {number} type Optional, defaults to png, snapshot format 0:bmp/1:png/2:jpg(jpeg)
+ * @param {number} cf Optional, an RGB color storage format
+ */
+uibase.snapshot = function (fileName, type = 1, cf = NativeObject.APP.NativeComponents.NativeEnum.LV_IMG_CF_TRUE_COLOR_ALPHA) {
+ if (!fileName) {
+ return
+ }
+ // Default storage location is /app/data/snapshot
+ os.mkdir("/app/data/snapshot/")
+ this.obj.lvSnapshotTake(cf, "/app/data/snapshot/" + fileName, type)
+}
+/**
+ * Set the base layout direction of the object
+ * @param {number} dir Refer to utils.STYLE Required, base layout direction of the object
+ * @param {number} type Refer to utils.STYLE Optional, defaults to binding with the object itself
+ */
+uibase.setStyleBaseDir = function (dir, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.setStyleBaseDir(dir, type)
+}
+export default uibase;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiButton.js b/vf107/dxmodules/uiButton.js
new file mode 100644
index 0000000..dfba343
--- /dev/null
+++ b/vf107/dxmodules/uiButton.js
@@ -0,0 +1,16 @@
+//build: 20240311
+//Button component, no new features compared to base class
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let button = {}
+
+button.build = function (id, parent) {
+ let temp = utils.validateBuild(button.all, id, parent, 'button')
+ let my = { type: 'button' }
+ my.obj = new utils.GG.NativeButton({ uid: id }, temp)
+ my.id = id
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default button;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiButtons.js b/vf107/dxmodules/uiButtons.js
new file mode 100644
index 0000000..7f7cb2e
--- /dev/null
+++ b/vf107/dxmodules/uiButtons.js
@@ -0,0 +1,107 @@
+//build: 20240314
+//Button group control
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let buttons = {}
+
+buttons.build = function (id, parent) {
+ let temp = utils.validateBuild(buttons.all, id, parent, 'buttons')
+ let my = {type: 'buttons'}
+ my.obj = new utils.GG.NativeBtnmatrix({ uid: id }, temp)
+ my.id = id
+ /**
+ * Set the data for the button group, must be in array format. Example below shows 3 rows of buttons, 12 buttons in total:
+ * ["1", "2", "3", "0", "\n",
+ * "4", "5", "6", "Cancel", "\n",
+ * "7", "8", "9", "Confirm", ""]
+ * @param {array} d Optional, if not provided or not an object type, it will get the data
+ */
+ my.data = function (d) {
+ if (utils.validateObject(d)) {
+ this.obj.lvBtnmatrixSetMap(d)
+ } else {
+ return this.obj.lvBtnmatrixGetMap()
+ }
+ }
+ /**
+ * Call clickedButton to get the id and text of the clicked button when any button in the button group is clicked
+ * Return example: {id:11,text:'Cancel'}
+ */
+ my.clickedButton = function () {
+ let id = this.obj.lvBtnmatrixGetSelectedBtn();
+ if (id == 0xFFFF) {
+ // Clicking on the button group boundary will result in 0xFFFF invalid value, return empty
+ return { id: null, text: null }
+ }
+ let txt = this.obj.lvBtnmatrixGetBtnText(id);
+ return { id: id, text: txt }
+ }
+ /**
+ * Set the state of a specific button in the button group, can be changed to selected, disabled, etc.
+ * @param {number} id Button index, starting from 0 from left to right, top to bottom, also the id returned by clickedButton
+ * @param {number} state Refer to dxui.Utils.BUTTONS_STATE
+ */
+ my.setState = function (id, state) {
+ this.obj.lvBtnmatrixSetBtnCtrl(id, state)
+ }
+ /**
+ * Clear the already set state of a specific button in the button group
+ * @param {number} id Button index, starting from 0 from left to right, top to bottom, also the id returned by clickedButton
+ * @param {number} state Refer to dxui.Utils.BUTTONS_STATE
+ */
+ my.clearState = function (id, state) {
+ this.obj.lvBtnmatrixClearBtnCtrl(id, state)
+ }
+ /**
+ * Set the state of all buttons in the button group, can be changed to selected, disabled, etc.
+ * @param {number} state Refer to dxui.Utils.BUTTONS_STATE
+ */
+ my.setAllState = function (state) {
+ this.obj.lvBtnmatrixSetBtnCtrlAll(state)
+ }
+ /**
+ * Clear the already set state of all buttons in the button group
+ * @param {number} state Refer to dxui.Utils.BUTTONS_STATE
+ */
+ my.clearAllState = function (state) {
+ this.obj.lvBtnmatrixClearBtnCtrlAll(state)
+ }
+ /**
+ * Set the button width to span multiple columns for a specific button id
+ * @param {number} id Button index, starting from 0
+ * @param {number} width Width span in number of columns
+ */
+ my.setBtnWidth = function (id, width) {
+ this.obj.lvBtnmatrixSetBtnWidth(id, width)
+ }
+ /**
+ * Set the button icon for a specific button id
+ * @param {number} id Button index, starting from 0
+ * @param {string} src Icon file path
+ */
+ my.setBtnIcon = function (id, src) {
+ this.obj.addEventCb((e) => {
+ // Get the draw control object
+ let dsc = e.lvEventGetDrawPartDsc()
+ // If drawing the id-th button
+ if (dsc.type == utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN && dsc.id == id) {
+ // Get image information
+ let header = utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // Define an area, center display, note: size to area needs -1, area to size needs +1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // Draw image information
+ let img_draw_dsc = utils.GG.NativeDraw.lvDrawImgDscInit()
+ // Draw image
+ utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ }, utils.ENUM.LV_EVENT_DRAW_PART_END)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all,comp,parent)
+ return comp;
+}
+export default buttons;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiCheckbox.js b/vf107/dxmodules/uiCheckbox.js
new file mode 100644
index 0000000..4e3aebc
--- /dev/null
+++ b/vf107/dxmodules/uiCheckbox.js
@@ -0,0 +1,48 @@
+//build: 20240329
+//Checkbox component
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let checkbox = {}
+
+checkbox.build = function (id, parent) {
+ let temp = utils.validateBuild(checkbox.all, id, parent, 'checkbox')
+ let my = { type: 'checkbox' }
+ my.obj = new utils.GG.NativeCheckbox({ uid: id }, temp)
+ my.id = id
+ /**
+ * Get/set text
+ * @param {string} text Set text
+ * @returns Get text
+ */
+ my.text = function (text) {
+ if (text == null || text == undefined) {
+ return this.obj.getText()
+ } else {
+ this.obj.setText(text)
+ }
+ }
+ /**
+ * Check or uncheck
+ * @param {boolean} en true/false
+ */
+ my.select = function (en) {
+ if (en) {
+ if (!my.obj.hasState(utils.STATE.CHECKED)) {
+ my.obj.addState(utils.STATE.CHECKED)
+ }
+ } else {
+ my.obj.clearState(utils.STATE.CHECKED)
+ }
+ }
+ /**
+ * Check if selected
+ * @returns Returns true/false
+ */
+ my.isSelect = function () {
+ return my.obj.hasState(utils.STATE.CHECKED)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default checkbox;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiDropdown.js b/vf107/dxmodules/uiDropdown.js
new file mode 100644
index 0000000..608df6e
--- /dev/null
+++ b/vf107/dxmodules/uiDropdown.js
@@ -0,0 +1,53 @@
+//build: 20240329
+//Dropdown control
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let dropdown = {}
+
+dropdown.build = function (id, parent) {
+ let temp = utils.validateBuild(dropdown.all, id, parent, 'dropdown')
+ let my = {type: 'dropdown'}
+ my.obj = new utils.GG.NativeDropdown({ uid: id }, temp)
+ my.id = id
+ /**
+ * Set dropdown option content
+ * @param {array} arr Option content, a string array where each item is an option
+ */
+ my.setOptions = function (arr) {
+ this.obj.setOptions(arr.join('\n'))
+ }
+ /**
+ * Get dropdown option list
+ * @returns Returns list object, a base class object that can have its font set separately
+ */
+ my.getList = function () {
+ let res = {}
+ res.obj = this.obj.getList()
+ return Object.assign(res, base)
+ }
+ /**
+ * Set selected item, this will be selected by default
+ * @param {number} index Selected item index
+ */
+ my.setSelected = function (index) {
+ this.obj.setSelected(index)
+ }
+ /**
+ * Get selected item index
+ * @returns Returns the currently selected index
+ */
+ my.getSelected = function () {
+ return this.obj.getSelected()
+ }
+ /**
+ * Set dropdown accessory icon, default is a downward arrow
+ * @param {string} icon Icon address
+ */
+ my.setSymbol = function (icon) {
+ this.obj.setSymbol(icon)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default dropdown;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiFont.js b/vf107/dxmodules/uiFont.js
new file mode 100644
index 0000000..1d69505
--- /dev/null
+++ b/vf107/dxmodules/uiFont.js
@@ -0,0 +1,18 @@
+//build: 20240311
+//Font object (to support Chinese, you need to use a TTF font file that supports Chinese)
+import utils from "./uiUtils.js"
+let font = {}
+/**
+ * Build font
+ * @param {string} ttf Full path to the TTF font file
+ * @param {number} size Font size
+ * @param {number} style Font style, refer to utils.FONT_STYLE
+ * @returns
+ */
+font.build = function (ttf, size, style) {
+ let comp = {}
+ comp.obj = utils.GG.NativeFont.lvFontInit(ttf, size, style)
+ return comp;
+}
+
+export default font;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiImage.js b/vf107/dxmodules/uiImage.js
new file mode 100644
index 0000000..884ca7f
--- /dev/null
+++ b/vf107/dxmodules/uiImage.js
@@ -0,0 +1,27 @@
+//build: 20240311
+//Image control
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let image = {}
+
+image.build = function (id, parent) {
+ let temp = utils.validateBuild(image.all, id, parent, 'image')
+ let my = {type: 'image'}
+ my.obj = new utils.GG.NativeImage({ uid: id }, temp)
+ my.id = id
+ /**
+ * Set or get the image source
+ * @param {string} path Optional, absolute path to the image file. If not provided or not a string type, it will get the source
+ */
+ my.source = function (path) {
+ if (utils.validateString(path)) {
+ this.obj.lvImgSetSrc(path)
+ } else {
+ return this.obj.lvImgGetSrc()
+ }
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default image;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiKeyboard.js b/vf107/dxmodules/uiKeyboard.js
new file mode 100644
index 0000000..37cea50
--- /dev/null
+++ b/vf107/dxmodules/uiKeyboard.js
@@ -0,0 +1,102 @@
+//build: 20240329
+//Keyboard control
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let keyboard = {}
+
+keyboard.build = function (id, parent) {
+ let temp = utils.validateBuild(keyboard.all, id, parent, 'keyboard')
+ let my = {type: 'keyboard'}
+ my.obj = new utils.GG.NativeKeyboard({ uid: id }, temp)
+
+ // Pinyin input method will get a new object, bound to the current keyboard, to enhance keyboard functionality such as 9-key, etc. Users don't need to care about this, just operate the initially created keyboard object
+ let pinyin = {}
+ pinyin.obj = my.obj.lvImePinyinCreate()
+ my.obj.lvImePinyinSetKeyboard(pinyin.obj)
+ my["__obj"] = Object.assign(pinyin, base)
+ my.__mode = "K26"
+
+ my.id = id
+ /**
+ * Set associated text box, keyboard output will be displayed here
+ * @param {object} textarea Text box control object
+ */
+ my.setTextarea = function (textarea) {
+ this.obj.lvKeyboardSetTextarea(textarea.obj)
+ my.textarea = textarea
+ }
+ /**
+ * Set/get mode, pure numeric keyboard or other modes
+ * @param {any} mode Mode, refer to enum
+ * @returns Returns current mode
+ */
+ my.mode = function (mode) {
+ if (!mode) {
+ return my.__mode
+ }
+ if (mode == "K26" || mode == "K9") {
+ this.obj.lvImePinyinSetMode(my["__obj"].obj, mode == "K26" ? 0 : 1)
+ } else {
+ if (mode == utils.KEYBOARD.NUMBER) {
+ this.obj.lvImePinyinSetMode(my["__obj"].obj, 2)
+ }
+ this.obj.lvKeyboardSetMode(mode)
+ }
+ my.__mode = mode
+ }
+ /**
+ * Set pinyin font, different from keyboard, this sets the candidate character font
+ * @param {object} font Font object returned by font.js build
+ * @param {number} type Refer to utils.STYLE Optional, defaults to binding with the object itself
+ */
+ my.chFont = function (font, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!font || !font.obj) {
+ throw new Error("dxui.textFont: 'font' parameter should not be null")
+ }
+ my.obj.lvImePinyinGetCandPanel(my["__obj"].obj).lvObjSetStyleTextFont(font.obj, type)
+ }
+ /**
+ * Display button title in popup window when pressed, i.e., auxiliary display upper frame
+ * @param {boolean} en true/false
+ */
+ my.setPopovers = function (en) {
+ this.obj.lvKeyboardSetPopovers(en)
+ }
+ /**
+ * Set dictionary
+ * @param {object} dict Dictionary, format like: {"a": "鍟�", "ai": "鐖�",...,"zu":"缁�"}, all 26 letters must be present, write "" if no candidate characters
+ * @returns
+ */
+ my.dict = function (dict) {
+ if (!dict) {
+ return my.obj.lvImePinyinGetDict(my["__obj"].obj)
+ } else {
+ my.obj.lvImePinyinSetDict(my["__obj"].obj, dict)
+ }
+ }
+ let comp = Object.assign(my, base);
+ // Override methods
+ // Keep original methods
+ const super_hide = my.hide;
+ const super_show = my.show;
+ my.hide = function () {
+ super_hide.call(this)
+ my.obj.lvImePinyinGetCandPanel(my["__obj"].obj).lvObjAddFlag(1);
+ if (my.textarea.text() && my.textarea.text().length > 0) {
+ my.obj.lvImePinyinClearData(my["__obj"].obj)
+ }
+ }
+ my.show = function () {
+ super_show.call(this)
+ if (my.obj.lvImePinyinGetCandNum(my["__obj"].obj) > 0) {
+ my.obj.lvImePinyinGetCandPanel(my["__obj"].obj).lvObjClearFlag(1);
+ }
+ my.obj.lvImePinyinGetCandPanel(my["__obj"].obj).lvObjAlignTo(my.obj, utils.ALIGN.OUT_TOP_MID, 0, 0)
+ }
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default keyboard;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiLabel.js b/vf107/dxmodules/uiLabel.js
new file mode 100644
index 0000000..493311f
--- /dev/null
+++ b/vf107/dxmodules/uiLabel.js
@@ -0,0 +1,34 @@
+//build: 20240311
+//Label component
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let label = {}
+
+label.build = function (id, parent) {
+ let temp = utils.validateBuild(label.all, id, parent, 'label')
+ let my = {type: 'label'}
+ my.obj = new utils.GG.NativeLabel({ uid: id }, temp)
+ my.id = id
+ /**
+ * Set or get the label text content
+ * @param {string} t Optional, if not provided or not a string type, it will get the text
+ */
+ my.text = function (t) {
+ if (utils.validateString(t)) {
+ this.obj.lvLabelSetText(t)
+ } else {
+ return this.obj.lvLabelGetText()
+ }
+ }
+ /**
+ * Set the display mode when text is too long, such as scrolling, truncating, etc.
+ * @param {number} mode Enum reference utils.LABEL_LONG_MODE
+ */
+ my.longMode = function (mode) {
+ this.obj.lvLabelSetLongMode(mode)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default label;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiLine.js b/vf107/dxmodules/uiLine.js
new file mode 100644
index 0000000..04334c0
--- /dev/null
+++ b/vf107/dxmodules/uiLine.js
@@ -0,0 +1,24 @@
+//build: 20240311
+//Line component
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let line = {}
+
+line.build = function (id, parent) {
+ let temp = utils.validateBuild(line.all, id, parent, 'line')
+ let my = {type: 'line'}
+ my.obj = new utils.GG.NativeLine({ uid: id }, temp)
+ my.id = id
+ /**
+ * Set coordinates of all points for the line
+ * @param {Array} points Required, array of all points, e.g. [[x1,y1],[x2,y2]]
+ * @param {number} count Required, number of points to draw, note this value can be less than the length of points
+ */
+ my.setPoints = function (points, count) {
+ this.obj.lvLineSetPoints(points, count)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default line;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiList.js b/vf107/dxmodules/uiList.js
new file mode 100644
index 0000000..4dddb20
--- /dev/null
+++ b/vf107/dxmodules/uiList.js
@@ -0,0 +1,45 @@
+//build: 20240329
+//List control
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let list = {}
+
+list.build = function (id, parent) {
+ let temp = utils.validateBuild(list.all, id, parent, 'list')
+ let my = {type: 'list'}
+ my.obj = new utils.GG.NativeList({ uid: id }, temp)
+ my.id = id
+ /**
+ * Add a single text item
+ * @param {string} text Text content of the item
+ * @returns The item's own base object
+ */
+ my.addText = function (text) {
+ let res = {}
+ res.obj = this.obj.lvListAddText(text)
+ return Object.assign(res, base)
+ }
+ /**
+ * Add a single button item
+ * @param {string} src Icon path before the item
+ * @param {string} text Text content of the item
+ * @returns The item's own base object
+ */
+ my.addBtn = function (src, text) {
+ let res = {}
+ res.obj = this.obj.lvListAddBtn(src, text)
+ return Object.assign(res, base)
+ }
+ /**
+ * Get the text content of a button item
+ * @param {string} btn Button item
+ * @returns Text content of the button item
+ */
+ my.getBtnText = function (btn) {
+ return this.obj.lvListGetBtnText(btn.obj)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default list;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiSlider.js b/vf107/dxmodules/uiSlider.js
new file mode 100644
index 0000000..f699187
--- /dev/null
+++ b/vf107/dxmodules/uiSlider.js
@@ -0,0 +1,42 @@
+//build: 20240329
+//Slider component
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let slider = {}
+
+slider.build = function (id, parent) {
+ let temp = utils.validateBuild(slider.all, id, parent, 'slider')
+ let my = {type: 'slider'}
+ my.obj = new utils.GG.NativeSlider({ uid: id }, temp)
+ my.id = id
+
+ /**
+ * Get/set value
+ * @param {number} v Set value
+ * @param {boolean} en Whether to enable animation when setting value, i.e. easing effect
+ * @returns Get value
+ */
+ my.value = function (v, en) {
+ if (v == null || v == undefined) {
+ return this.obj.lvSliderGetValue()
+ } else {
+ if (!utils.validateNumber(en)) {
+ en = false
+ }
+ this.obj.lvSliderSetValue(v, en)
+ }
+ }
+ /**
+ * Set range
+ * @param {number} min Minimum value
+ * @param {number} max Maximum value
+ */
+ my.range = function (min, max) {
+ this.obj.lvSliderSetRange(min, max)
+ }
+
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default slider;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiStyle.js b/vf107/dxmodules/uiStyle.js
new file mode 100644
index 0000000..1d1f4a6
--- /dev/null
+++ b/vf107/dxmodules/uiStyle.js
@@ -0,0 +1,149 @@
+//build: 20240315
+//Control style - Each control can bind a style object and set multiple styles
+import utils from "./uiUtils.js"
+
+let style = {}
+style.build = function () {
+ let comp = {}
+ comp.obj = new utils.GG.NativeStyle()
+ comp.obj.lvStyleInit()
+ /**
+ * Set all padding (left, right, top, bottom) to one value
+ * @param {number} pad Padding value
+ */
+ comp.padAll = function (pad) {
+ this.obj.lvStyleSetPadAll(pad)
+ }
+ /**
+ * Set right padding to one value
+ * @param {number} pad Padding value
+ */
+ comp.padRight = function (pad) {
+ this.obj.lvStyleSetPadRight(pad)
+ }
+ /**
+ * Set left padding to one value
+ * @param {number} pad Padding value
+ */
+ comp.padLeft = function (pad) {
+ this.obj.lvStyleSetPadLeft(pad)
+ }
+ /**
+ * Set top padding to one value
+ * @param {number} pad Padding value
+ */
+ comp.padTop = function (pad) {
+ this.obj.lvStyleSetPadTop(pad)
+ }
+ /**
+ * Set bottom padding to one value
+ * @param {number} pad Padding value
+ */
+ comp.padBottom = function (pad) {
+ this.obj.lvStyleSetPadBottom(pad)
+ }
+ /**
+ * Set padding between columns to one value
+ * @param {number} pad Padding value
+ */
+ comp.padColumn = function (pad) {
+ this.obj.lvStyleSetPadColumn(pad)
+ }
+ /**
+ * Set padding between rows to one value
+ * @param {number} pad Padding value
+ */
+ comp.padRow = function (pad) {
+ this.obj.lvStyleSetPadRow(pad)
+ }
+ /**
+ * Set border width
+ * @param {number} w
+ */
+ comp.borderWidth = function (w) {
+ this.obj.lvStyleSetBorderWidth(w)
+ }
+ /**
+ * Set border radius
+ * @param {number} r
+ */
+ comp.radius = function (r) {
+ this.obj.lvStyleSetRadius(r)
+ }
+ /**
+ * Set background opacity, value range is 0-100, smaller value is more transparent
+ * @param {number} opa Must be 0-100
+ */
+ comp.bgOpa = function (opa) {
+ this.obj.lvStyleSetBgOpa(utils.OPA_MAPPING(opa))
+ }
+ /**
+ * Set self opacity, value range is 0-100, smaller value is more transparent
+ * @param {number} opa Must be 0-100
+ */
+ comp.opa = function (opa) {
+ this.obj.lvStyleSetOpa(utils.OPA_MAPPING(opa))
+ }
+ /**
+ * Set background color
+ * @param {any} color Supports number type: e.g. 0x34ffaa; string type (starting with #), e.g.: '#34ffaa'
+ */
+ comp.bgColor = function (color) {
+ this.obj.lvStyleSetBgColor(utils.colorParse(color))
+ }
+ /**
+ * Set text color
+ * @param {any} color Supports number type: e.g. 0x34ffaa; string type (starting with #), e.g.: '#34ffaa'
+ */
+ comp.textColor = function (color) {
+ this.obj.lvStyleSetTextColor(utils.colorParse(color))
+ }
+ /**
+ * Set text alignment
+ * @param {number} type Refer to utils.TEXT_ALIGN
+ */
+ comp.textAlign = function (type) {
+ this.obj.lvStyleSetTextAlign(type)
+ }
+ /**
+ * Set text font
+ * @param {object} font Font object returned by font.js build
+ */
+ comp.textFont = function (font) {
+ if (!font || !font.obj) {
+ throw new Error("style.textFont: 'font' parameter should not be null")
+ }
+ this.obj.lvStyleSetTextFont(font.obj)
+ }
+ /**
+ * Set gradient color
+ * @param {number} color Gradient color, e.g.: 0xffffff
+ */
+ comp.bgGradColor = function (color) {
+ this.obj.lvStyleSetBgGradColor(color)
+ }
+ /**
+ * Set gradient color direction
+ * @param {number} dir Direction, currently only supports horizontal and vertical
+ */
+ comp.bgGradDir = function (dir) {
+ this.obj.lvStyleSetBgGradDir(dir)
+ }
+ /**
+ * Background color end position (0-255)
+ * @param {number} value Distance, calculated from the left end
+ */
+ comp.bgMainStop = function (value) {
+ this.obj.lvStyleSetBgMainStop(value)
+ }
+ /**
+ * Gradient color distance (0-255)
+ * @param {number} value Distance, calculated from the end position of the background color
+ */
+ comp.bgGradStop = function (value) {
+ this.obj.lvStyleSetBgGradStop(value)
+ }
+ return comp;
+}
+
+export default style;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiSwitch.js b/vf107/dxmodules/uiSwitch.js
new file mode 100644
index 0000000..bf71006
--- /dev/null
+++ b/vf107/dxmodules/uiSwitch.js
@@ -0,0 +1,49 @@
+//build: 20240329
+//Switch component
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let _switch = {}
+
+_switch.build = function (id, parent) {
+ let temp = utils.validateBuild(_switch.all, id, parent, '_switch')
+ let my = {type: 'switch'}
+ my.obj = new utils.GG.NativeSwitch({ uid: id }, temp)
+ my.id = id
+
+ /**
+ * Get/set text
+ * @param {string} text Set text
+ * @returns Get text
+ */
+ my.text = function (text) {
+ if (text == null || text == undefined) {
+ return this.obj.getText()
+ } else {
+ this.obj.setText(text)
+ }
+ }
+ /**
+ * Check or uncheck
+ * @param {boolean} en true/false
+ */
+ my.select = function (en) {
+ if (en) {
+ if (!my.obj.hasState(utils.STATE.CHECKED)) {
+ my.obj.addState(utils.STATE.CHECKED)
+ }
+ } else {
+ my.obj.clearState(utils.STATE.CHECKED)
+ }
+ }
+ /**
+ * Check if selected
+ * @returns Returns true/false
+ */
+ my.isSelect = function () {
+ return my.obj.hasState(utils.STATE.CHECKED)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default _switch;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiTextarea.js b/vf107/dxmodules/uiTextarea.js
new file mode 100644
index 0000000..d900e46
--- /dev/null
+++ b/vf107/dxmodules/uiTextarea.js
@@ -0,0 +1,76 @@
+//build: 20240330
+//Textarea control
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let textarea = {}
+
+textarea.build = function (id, parent) {
+ let temp = utils.validateBuild(textarea.all, id, parent, 'textarea')
+ let my = {type: 'textarea'}
+ my.obj = new utils.GG.NativeTextarea({ uid: id }, temp)
+ my.id = id
+ /**
+ * Set single line mode, cannot wrap
+ * @param {boolean} en true/false
+ */
+ my.setOneLine = function (en) {
+ this.obj.lvTextareaSetOneLine(en)
+ }
+ /**
+ * Set password mode, content displays as 路 symbol
+ * @param {boolean} en true/false
+ */
+ my.setPasswordMode = function (en) {
+ this.obj.lvTextareaSetPasswordMode(en)
+ }
+ /**
+ * Set content alignment, center, left, right, etc.
+ * @param {number} align Alignment enum
+ */
+ my.setAlign = function (align) {
+ this.obj.lvTextareaSetAlign(align)
+ }
+ /**
+ * Set maximum content length, character count limit
+ * @param {number} length Length
+ */
+ my.setMaxLength = function (length) {
+ this.obj.lvTextareaSetMaxLength(length)
+ }
+ /**
+ * Set whether to enable cursor positioning, whether to display |
+ * @param {boolean} en true/false
+ */
+ my.setCursorClickPos = function (en) {
+ this.obj.lvTextareaSetCursorClickPos(en)
+ }
+ /**
+ * Insert text at current cursor position
+ * @param {string} txt Text content
+ */
+ my.lvTextareaAddText = function (txt) {
+ this.obj.lvTextareaAddText(txt)
+ }
+ /**
+ * Delete character to the left of current cursor position
+ */
+ my.lvTextareaDelChar = function () {
+ this.obj.lvTextareaDelChar()
+ }
+ /**
+ * Get/set text content
+ * @param {string} text Set text content
+ * @returns Get text content
+ */
+ my.text = function (text) {
+ if (text == null || text == undefined) {
+ return this.obj.lvTextareaGetText()
+ } else {
+ this.obj.lvTextareaSetText(text)
+ }
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default textarea;
\ No newline at end of file
diff --git a/vf107/dxmodules/uiUtils.js b/vf107/dxmodules/uiUtils.js
new file mode 100644
index 0000000..b3717f3
--- /dev/null
+++ b/vf107/dxmodules/uiUtils.js
@@ -0,0 +1,301 @@
+//build: 20240315
+//Common functions, constants, enums, etc.
+import { uiClass } from '../dxmodules/libvbar-m-dxui.so'
+import logger from './dxLogger.js'
+import dxDriver from './dxDriver.js'
+const ui = new uiClass();
+// Initialize UI component
+ui.init(dxDriver.DISPLAY.WIDTH, dxDriver.DISPLAY.HEIGHT, dxDriver.DISPLAY.DPI)
+
+let utils = {}
+utils.GG = NativeObject.APP.NativeComponents
+utils.ENUM = utils.GG.NativeEnum
+utils.LAYER = {
+ "MAIN": 0,
+ "SYS": 1,
+ "TOP": 2
+}
+utils.EVENT = {
+ "CLICK": 7,
+ "LONG_PRESSED": 5,
+ "SHORT_PRESSED": 4,
+ "PRESSING": utils.ENUM.LV_EVENT_PRESSING,
+ "FOCUSED": utils.ENUM.LV_EVENT_FOCUSED,
+ "DEFOCUSED": utils.ENUM.LV_EVENT_DEFOCUSED,
+ "VALUE_CHANGED": utils.ENUM.LV_EVENT_VALUE_CHANGED,
+ "INSERT": utils.ENUM.LV_EVENT_INSERT,
+ "REFRESH": utils.ENUM.LV_EVENT_REFRESH,
+ "READY": utils.ENUM.LV_EVENT_READY,
+ "CANCEL": utils.ENUM.LV_EVENT_CANCEL,
+}
+utils.TEXT_ALIGN = {
+ "AUTO": 0,
+ "LEFT": 1,
+ "CENTER": 2,
+ "RIGHT": 3
+}
+utils.STATE = {
+ "DEFAULT": utils.ENUM.LV_STATE_DEFAULT,
+ "CHECKED": utils.ENUM.LV_STATE_CHECKED,
+ "FOCUSED": utils.ENUM.LV_STATE_FOCUSED,
+ "FOCUS_KEY": utils.ENUM.LV_STATE_FOCUS_KEY,
+ "EDITED": utils.ENUM.LV_STATE_EDITED,
+ "HOVERED": utils.ENUM.LV_STATE_HOVERED,
+ "PRESSED": utils.ENUM.LV_STATE_PRESSED,
+ "SCROLLED": utils.ENUM.LV_STATE_SCROLLED,
+ "DISABLED": utils.ENUM.LV_STATE_DISABLED,
+}
+utils.OBJ_FLAG = {
+ "CLICKABLE": utils.ENUM.LV_OBJ_FLAG_CLICKABLE,
+}
+utils.ALIGN = {//Position relative to reference object, those with OUT are outside the reference object's boundary
+ "OUT_TOP_LEFT": utils.ENUM.LV_ALIGN_OUT_TOP_LEFT,
+ "OUT_TOP_MID": utils.ENUM.LV_ALIGN_OUT_TOP_MID,
+ "OUT_TOP_RIGHT": utils.ENUM.LV_ALIGN_OUT_TOP_RIGHT,
+ "OUT_BOTTOM_LEFT": utils.ENUM.LV_ALIGN_OUT_BOTTOM_LEFT,
+ "OUT_BOTTOM_MID": utils.ENUM.LV_ALIGN_OUT_BOTTOM_MID,
+ "OUT_BOTTOM_RIGHT": utils.ENUM.LV_ALIGN_OUT_BOTTOM_RIGHT,
+ "OUT_LEFT_TOP": utils.ENUM.LV_ALIGN_OUT_LEFT_TOP,
+ "OUT_LEFT_MID": utils.ENUM.LV_ALIGN_OUT_LEFT_MID,
+ "OUT_LEFT_BOTTOM": utils.ENUM.LV_ALIGN_OUT_LEFT_BOTTOM,
+ "OUT_RIGHT_TOP": utils.ENUM.LV_ALIGN_OUT_RIGHT_TOP,
+ "OUT_RIGHT_MID": utils.ENUM.LV_ALIGN_OUT_RIGHT_MID,
+ "OUT_RIGHT_BOTTOM": utils.ENUM.LV_ALIGN_OUT_RIGHT_BOTTOM,
+ "TOP_LEFT": utils.ENUM.LV_ALIGN_TOP_LEFT,
+ "TOP_MID": utils.ENUM.LV_ALIGN_TOP_MID,
+ "TOP_RIGHT": utils.ENUM.LV_ALIGN_TOP_RIGHT,
+ "BOTTOM_LEFT": utils.ENUM.LV_ALIGN_BOTTOM_LEFT,
+ "BOTTOM_MID": utils.ENUM.LV_ALIGN_BOTTOM_MID,
+ "BOTTOM_RIGHT": utils.ENUM.LV_ALIGN_BOTTOM_RIGHT,
+ "LEFT_MID": utils.ENUM.LV_ALIGN_LEFT_MID,
+ "RIGHT_MID": utils.ENUM.LV_ALIGN_RIGHT_MID,
+ "CENTER": utils.ENUM.LV_ALIGN_CENTER,
+ "DEFAULT": utils.ENUM.LV_ALIGN_DEFAULT
+}
+utils.FLEX_ALIGN = {//Flex layout, alignment method
+ "START": utils.ENUM.LV_FLEX_ALIGN_START,
+ "END": utils.ENUM.LV_FLEX_ALIGN_END,
+ "CENTER": utils.ENUM.LV_FLEX_ALIGN_CENTER,
+ "SPACE_EVENLY": utils.ENUM.LV_FLEX_ALIGN_SPACE_EVENLY,
+ "SPACE_AROUND": utils.ENUM.LV_FLEX_ALIGN_SPACE_AROUND,
+ "SPACE_BETWEEN": utils.ENUM.LV_FLEX_ALIGN_SPACE_BETWEEN,
+}
+utils.FLEX_FLOW = {//Flex layout, main and cross axis
+ "ROW": utils.ENUM.LV_FLEX_FLOW_ROW,
+ "COLUMN": utils.ENUM.LV_FLEX_FLOW_COLUMN,
+ "ROW_WRAP": utils.ENUM.LV_FLEX_FLOW_ROW_WRAP,
+ "ROW_REVERSE": utils.ENUM.LV_FLEX_FLOW_ROW_REVERSE,
+ "ROW_WRAP_REVERSE": utils.ENUM.LV_FLEX_FLOW_ROW_WRAP_REVERSE,
+ "COLUMN_WRAP": utils.ENUM.LV_FLEX_FLOW_COLUMN_WRAP,
+ "COLUMN_REVERSE": utils.ENUM.LV_FLEX_FLOW_COLUMN_REVERSE,
+ "COLUMN_WRAP_REVERSE": utils.ENUM.LV_FLEX_FLOW_COLUMN_WRAP_REVERSE,
+}
+utils.GRAD = {//Gradient color direction
+ "NONE": utils.ENUM.LV_GRAD_DIR_NONE,
+ "VER": utils.ENUM.LV_GRAD_DIR_VER,
+ "HOR": utils.ENUM.LV_GRAD_DIR_HOR,
+}
+utils.KEYBOARD = {//Keyboard mode
+ "TEXT_LOWER": utils.ENUM.LV_KEYBOARD_MODE_TEXT_LOWER,
+ "TEXT_UPPER": utils.ENUM.LV_KEYBOARD_MODE_TEXT_UPPER,
+ "SPECIAL": utils.ENUM.LV_KEYBOARD_MODE_SPECIAL,
+ "NUMBER": utils.ENUM.LV_KEYBOARD_MODE_NUMBER,
+ "K26": "K26",
+ "K9": "K9",
+}
+utils.FONT_STYLE = {
+ "NORMAL": utils.ENUM.FT_FONT_STYLE_NORMAL,
+ "ITALIC": utils.ENUM.FT_FONT_STYLE_ITALIC,
+ "BOLD": utils.ENUM.FT_FONT_STYLE_BOLD,
+}
+utils.BUTTONS_STATE = {
+ "HIDDEN": utils.ENUM.LV_BTNMATRIX_CTRL_HIDDEN,//Whether a button in the button matrix is hidden
+ "NO_REPEAT": utils.ENUM.LV_BTNMATRIX_CTRL_NO_REPEAT,//Whether buttons in the button matrix can be pressed repeatedly, won't trigger key events repeatedly
+ "DISABLED": utils.ENUM.LV_BTNMATRIX_CTRL_DISABLED,//Whether a button in the button matrix is disabled
+ "CHECKABLE": utils.ENUM.LV_BTNMATRIX_CTRL_CHECKABLE,//Whether buttons in the button matrix are checkable
+ "CHECKED": utils.ENUM.LV_BTNMATRIX_CTRL_CHECKED,//Whether a button in the button matrix is checked, displayed as checked state in the interface
+ "CLICK_TRIG": utils.ENUM.LV_BTNMATRIX_CTRL_CLICK_TRIG,//Whether buttons in the button matrix can be triggered by clicking
+ "POPOVER": utils.ENUM.LV_BTNMATRIX_CTRL_POPOVER,//Whether a button in the matrix pops up, will display more options or content when clicked
+ "RECOLOR": utils.ENUM.LV_BTNMATRIX_CTRL_RECOLOR//Whether buttons in the matrix can be recolored
+}
+//Style effective part
+utils.STYLE_PART = {
+ "MAIN": 0, //Object's current style takes effect
+ "ITEMS": 327680//Object's internal sub-items take effect, such as button groups in buttonMatrix
+}
+//Text overflow display mode
+utils.LABEL_LONG_MODE = {
+ "WRAP": utils.ENUM.LV_LABEL_LONG_WRAP,//Wrap text when it's long
+ "DOT": utils.ENUM.LV_LABEL_LONG_DOT,//Replace with ... when text is long
+ "SCROLL": utils.ENUM.LV_LABEL_LONG_SCROLL,//Auto scroll when text is long
+ "SCROLL_CIRCULAR": utils.ENUM.LV_LABEL_LONG_SCROLL_CIRCULAR,//Circular scroll when text is long
+ "CLIP": utils.ENUM.LV_LABEL_LONG_CLIP,//Auto clip when text is long
+}
+// Set object's base layout direction
+utils.BASE_DIR = {
+ "LTR": utils.ENUM.LV_BASE_DIR_LTR,//Left to right
+ "RTL": utils.ENUM.LV_BASE_DIR_RTL,//Right to left
+ "AUTO": utils.ENUM.LV_BASE_DIR_AUTO,//Automatically choose text direction based on text content
+ "NEUTRAL": utils.ENUM.LV_BASE_DIR_NEUTRAL,//Neutral direction, their display direction is determined by surrounding text direction
+ "WEAK": utils.ENUM.LV_BASE_DIR_WEAK,//Has slight directional tendency (usually LTR), but will change direction under the influence of strong directional text (such as Arabic)
+}
+// Map 0-100 to 0-255
+utils.OPA_MAPPING = function (value) {
+ return Math.round((value / 100) * 255);
+}
+/**
+* Validate if number is empty, if it's a number
+* @param {number} n Required
+* @param {err} Error message, optional, will throw Error if provided
+*/
+utils.validateNumber = function (n, err) {
+ return _valid(n, 'number', err)
+}
+/**
+* Validate if object is empty, if it's an object
+* @param {object} o Required
+* @param {err} Error message, optional, will throw Error if provided
+*/
+utils.validateObject = function (o, err) {
+ return _valid(o, 'object', err)
+}
+/**
+ * Validate UI object build parameters
+ * @param {array} all Required, all object references
+ * @param {string} id Cannot be empty, required
+ * @param {object} parent Optional, defaults to 0
+ */
+utils.validateBuild = function (all, id, parent, type) {
+ this.validateId(all, id)
+ if (parent === 0 || parent === 1 || parent === 2) {
+ return parent
+ }
+ if (!parent || !parent.obj) {
+ throw new Error(type + ".build: 'parent' paramter should not be null")
+ }
+ return parent.obj
+}
+/**
+ * Validate all UI control ids, cannot be duplicated
+ * @param {array} all
+ * @param {string} id
+ */
+utils.validateId = function (all, id) {
+ this.validateString(id, "The 'id' parameter should not be null.")
+ if (all[id]) {
+ throw new Error("The id(" + id + ") already exists. Please set a different id value.")
+ }
+}
+/**
+* Validate if string is empty
+* @param {string} s Required
+* @param {err} Error message, optional, will throw Error if provided
+*/
+utils.validateString = function (s, err) {
+ let res = _valid(s, 'string', err)
+ if (!res) {
+ return false
+ }
+ if (s.length <= 0) {
+ if (err) {
+ throw new Error(err)
+ }
+ return false
+ }
+ return true
+}
+/**
+ * Parse different types of color values
+ * @param {any} value Supports number type: 0x34ffaa, string type: '0x34ffaa', string type: '#34ffaa'
+ * @returns
+ */
+utils.colorParse = function (value) {
+ if (typeof value == 'string') {
+ value = value.replace('#', '0x')
+ value = parseInt(value, 16)
+ }
+ return value
+}
+/**
+ * Get touch point coordinates
+ * @returns {x: x-coordinate, y: y-coordinate}
+ */
+utils.getTouchPoint = function () {
+ let point = NativeObject.APP.NativeComponents.NativeIndev.lvIndevGetPoint()
+ return point
+}
+/**
+ * Provide animation
+ * @param {object} obj Animation operation object, can be any object, obtained from callback parameter
+ * @param {number} start Interval start value, usually used with end, start changes to end during animation
+ * @param {number} end Interval end value
+ * @param {function} cb Callback function (obj, v)=>{}, obj is the animation operation object, interval value (start-end)
+ * @param {number} duration Animation duration, milliseconds
+ * @param {number} backDuration Optional, animation playback time, milliseconds, defaults to no playback
+ * @param {number} repeat Optional, animation repeat count, defaults to 1 time
+ * @param {string} mode Rate curve, optional, defaults to linear, built-in functions: linear, ease_in, ease_out, ease_in_out, overshoot, bounce, step
+ * linear Linear animation
+ step Change at the last step
+ ease_in Slow at the beginning
+ ease_out Slow at the end
+ ease_in_out Slow at both beginning and end
+ overshoot Overshoot the final value
+ bounce Bounce a bit from the final value (like hitting a wall)
+ * @returns Animation instance, must be saved globally
+ */
+utils.anime = function (obj, start, end, cb, duration, backDuration, repeat, mode) {
+ // 1. Initialize animation
+ let anim = NativeObject.APP.NativeComponents.NativeAnim.lvAnimInit()
+ // 2. Set animation object
+ anim.lvAnimSetVar(obj)
+ // 3. Set start and end values
+ anim.lvAnimSetValues(start, end)
+ //4. Set animation callback function
+ anim.lvAnimSetExecCb(cb)
+ // 5. Set animation time
+ anim.lvAnimSetTime(duration)
+ // Optional, set animation playback time, won't play back if not set
+ if (backDuration) {
+ anim.lvAnimSetPlaybackTime(backDuration)
+ }
+ // Optional, set animation repeat count
+ if (repeat) {
+ anim.lvAnimSetRepeatCount(repeat)
+ }
+ // Optional, set animation rate curve
+ if (mode) {
+ anim.lvAnimSetPathCb(mode)
+ }
+ // 6. Run animation
+ anim.lvAnimStart()
+ return anim
+}
+//Set parent and children for each object
+utils.setParent = function (all, child, parent) {
+ if (!all || parent == null || parent == undefined || !child) {
+ return
+ }
+ if ((typeof parent) == 'number') {
+
+ }
+ const parentId = ((typeof parent) == 'number') ? '' + parent : parent.id//Convert 0, 1, 2 to string
+ if (!all[parentId]) {
+ all[parentId] = { id: parentId }//Root nodes 0, 1, 2
+ }
+ if (!all[parentId].children) {
+ all[parentId].children = []
+ }
+ all[parentId].children.push(child.id)
+ child.parent = parentId
+ all[child.id] = child
+}
+function _valid(n, type, err) {
+ if (n === undefined || n === null || (typeof n) != type) {
+ if (err) {
+ throw new Error(err)
+ }
+ return false
+ }
+ return true
+}
+export default utils
\ No newline at end of file
diff --git a/vf107/dxmodules/uiView.js b/vf107/dxmodules/uiView.js
new file mode 100644
index 0000000..c48b99d
--- /dev/null
+++ b/vf107/dxmodules/uiView.js
@@ -0,0 +1,27 @@
+//build: 20240314
+//Basic rectangular object, similar to div, can load any other components
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let view = {}
+/**
+ * Create a view and load it on the parent component object
+ * @param {string} id Component id, required
+ * @param {object} parent Parent object
+ * @returns The created view object
+ */
+view.build = function (id, parent) {
+ let temp = utils.validateBuild(view.all, id, parent, 'view')
+ let my = {type: 'view'}
+ if (temp === 0 || temp === 1 || temp === 2) {
+ my.obj = new utils.GG.NativeBasicComponent({ uid: id }, null, temp)
+ }
+ else {
+ my.obj = new utils.GG.NativeBasicComponent({ uid: id }, temp)
+ }
+ my.id = id
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all,comp,parent)
+ return comp;
+}
+
+export default view;
\ No newline at end of file
diff --git a/vf107/src/controller.js b/vf107/src/controller.js
index 26f747a..442134b 100644
--- a/vf107/src/controller.js
+++ b/vf107/src/controller.js
@@ -28,9 +28,7 @@
}
function loop() {
- if (dxDriver.DRIVER.MODEL != "vf105" || std.loadFile('/etc/app/nfc.conf')) {
- driver.nfc.loop()
- }
+ driver.nfc.loop()
driver.gpiokey.loop()
driver.face.loop()
if (!driver.device.finger && (dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf114")) {
@@ -63,6 +61,14 @@
}
function setCallbacks() {
+ driver.nfc.setCallbacks({
+ onCardDetected: (cardInfo) => {
+ bus.fire(driver.nfc.NFC_CARD_RECEIVE, cardInfo)
+ },
+ onEidDetected: (eidinfo) => {
+ bus.fire(driver.nfc.EID_RECEIVE, eidinfo)
+ }
+ });
driver.gpiokey.setCallbacks({
onKeyEvent: (event) => {
bus.fire(driver.gpiokey.RECEIVE_MSG, event)
diff --git a/vf107/src/driver.js b/vf107/src/driver.js
index d7a2f39..89037d3 100644
--- a/vf107/src/driver.js
+++ b/vf107/src/driver.js
@@ -13,7 +13,7 @@
import pwm from '../dxmodules/dxPwm.js'
import ntp from '../dxmodules/dxNtp.js'
import gpio from "../dxmodules/dxGpio.js"
-import nfc from "../dxmodules/dxNfc.js"
+import dxNfcCard from "../dxmodules/dxNfcCard.js"
import watchdog from "../dxmodules/dxWatchdog.js"
import dxGpioKey from "../dxmodules/dxGpioKey.js"
import net from "../dxmodules/dxNetwork.js"
@@ -176,21 +176,16 @@
driver.nfc = {
NFC_CARD_RECEIVE: "nfcCardReceive",
EID_RECEIVE: "eidReceive",
- options: { m1: true, psam: false },
init: function () {
- if (!config.get('sys.nfc')) {
- logger.debug("鍒峰崱宸插叧闂�")
- return
- }
- this.options.useEid = config.get("sys.nfcIdentityCardEnable") == 3 ? 1 : 0
- nfc.worker.beforeLoop(this.options)
+ dxNfcCard.init();
},
eidInit: function () {
- if (!config.get('sys.nfc')) {
- return
- }
- if (config.get("sys.nfcIdentityCardEnable") == 3) {
- nfc.eidUpdateConfig({ appid: "1621503", sn: config.get("sys.sn"), device_model: config.get("sys.appVersion") })
+ try {
+ dxNfcCard.eidInit({ config: {
+ device_model: dxDriver.DRIVER.MODEL
+ } })
+ } catch (error) {
+ logger.error(error)
}
},
eidActive: function (code) {
@@ -199,22 +194,23 @@
version: config.get("sys.appVersion"),
macAddr: config.get("sys.mac")
};
- return nfc.eidActive(options);
+ return dxNfcCard.eidActive(options);
},
getConfig: function () {
- return nfc.getConfig();
+ return dxNfcCard.getConfig();
},
setConfig: function (options) {
- nfc.updateConfig(options);
+ dxNfcCard.updateConfig(options);
+ },
+ setCallbacks: function (callbacks) {
+ dxNfcCard.setCallbacks(callbacks);
},
loop: function () {
- if (!config.get('sys.nfc')) {
- return
- }
- nfc.worker.loop(this.options)
+ dxNfcCard.loop();
},
}
+
driver.face = {
options: {
det_max: 1,
diff --git a/vf107/src/main.js b/vf107/src/main.js
index 3877e31..ffcb751 100644
--- a/vf107/src/main.js
+++ b/vf107/src/main.js
@@ -38,10 +38,8 @@
}
driver.net.init()
driver.sqlite.init()
- if (dxDriver.DRIVER.MODEL != "vf105" || std.loadFile('/etc/app/nfc.conf')) {
- driver.nfc.init()
- driver.nfc.eidInit()
- }
+ driver.nfc.init()
+ driver.nfc.eidInit()
driver.pwm.init()
driver.mqtt.init()
driver.ntp.init()
--
Gitblit v1.9.3