//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;
|