初始化提交
This commit is contained in:
398
common/modules/mixly-modules/common/boards.js
Normal file
398
common/modules/mixly-modules/common/boards.js
Normal file
@@ -0,0 +1,398 @@
|
||||
goog.loadJs('common', () => {
|
||||
|
||||
goog.require('tippy');
|
||||
goog.require('layui');
|
||||
goog.require('path');
|
||||
goog.require('Mixly.LayerExt');
|
||||
goog.require('Mixly.Config');
|
||||
goog.require('Mixly.XML');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.ToolboxSearcher');
|
||||
goog.require('Mixly.MString');
|
||||
goog.require('Mixly.Msg');
|
||||
goog.require('Mixly.BoardConfigItem');
|
||||
goog.require('Mixly.Profile');
|
||||
goog.require('Mixly.EditorBlockly');
|
||||
goog.require('Mixly.Debug');
|
||||
goog.require('Mixly.Nav');
|
||||
goog.provide('Mixly.Boards');
|
||||
|
||||
const {
|
||||
Config,
|
||||
LayerExt,
|
||||
XML,
|
||||
Env,
|
||||
ToolboxSearcher,
|
||||
MString,
|
||||
Msg,
|
||||
BoardConfigItem,
|
||||
Profile,
|
||||
EditorBlockly,
|
||||
Debug,
|
||||
Nav,
|
||||
Boards
|
||||
} = Mixly;
|
||||
|
||||
const { form } = layui;
|
||||
|
||||
const { BOARD, USER, SELECTED_BOARD } = Config;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* INFO = {
|
||||
* "boardName": {
|
||||
* "key": string | null,
|
||||
* "config": object | null,
|
||||
* "default": object | null
|
||||
* }
|
||||
* }
|
||||
**/
|
||||
Boards.INFO = {};
|
||||
|
||||
Boards.NAME = [];
|
||||
|
||||
Boards.HAS_CONFIG_SETTING = false;
|
||||
|
||||
Boards.init = () => {
|
||||
Boards.dict = {};
|
||||
if (BOARD.board instanceof Object || BOARD.board instanceof String) {
|
||||
for (let i in BOARD.board) {
|
||||
Boards.dict[i] = new BoardConfigItem(i, BOARD.board[i]);
|
||||
if (USER.board && USER.board[BOARD.boardType]) {
|
||||
Boards.dict[i].setSelectedOptions(USER.board[BOARD.boardType].default);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Boards.dict[BOARD.boardType] = new BoardConfigItem(BOARD.boardType, BOARD.boardType);
|
||||
}
|
||||
Boards.NAME = Object.keys(Boards.dict);
|
||||
const $boards = $('#boards-type');
|
||||
const $boardSelector = Nav.getMain().getBoardSelector();
|
||||
$boardSelector.empty();
|
||||
for (let name of Object.keys(Boards.dict)) {
|
||||
const { group } = Boards.dict[name];
|
||||
const option = new Option(name, Boards.dict[name].key);
|
||||
if (group) {
|
||||
let $optGroup = $boardSelector.children(`optgroup[label="${group}"]`);
|
||||
if (!$optGroup.length) {
|
||||
$optGroup = $(`<optgroup label="${group}"></optgroup>`);
|
||||
$boardSelector.append($optGroup);
|
||||
}
|
||||
$optGroup.append(option);
|
||||
} else {
|
||||
$boardSelector.append(option);
|
||||
}
|
||||
}
|
||||
Nav.getMain().bind('changeBoard', (data) => {
|
||||
Boards.changeTo(data.text);
|
||||
Boards.updateCategories(data.text);
|
||||
});
|
||||
}
|
||||
|
||||
Boards.addLayer = (boardConfigLayer) => {
|
||||
Boards.configMenu = boardConfigLayer;
|
||||
}
|
||||
|
||||
Boards.getType = () => {
|
||||
const { boardIndex = '' } = BOARD;
|
||||
return path.basename(path.dirname(boardIndex)) ?? BOARD.boardType;
|
||||
}
|
||||
|
||||
Boards.getSelectedBoardName = () => {
|
||||
return $('#boards-type option:selected').text();
|
||||
}
|
||||
|
||||
Boards.getSelectedBoardKey = () => {
|
||||
return $('#boards-type option:selected').val();
|
||||
}
|
||||
|
||||
Boards.setSelectedBoard = (name, userConfig) => {
|
||||
const charIndex = name.indexOf('@');
|
||||
if (charIndex !== -1) {
|
||||
name = name.substring(charIndex + 1, name.length);
|
||||
}
|
||||
if (!Boards.NAME.includes(name))
|
||||
return;
|
||||
const boardInfo = Boards.dict[name];
|
||||
$("#boards-type").val(boardInfo.key).trigger('change');
|
||||
boardInfo.setSelectedOptions(userConfig);
|
||||
Boards.changeTo(name);
|
||||
Boards.updateCategories(name);
|
||||
if (Profile[name]) {
|
||||
Profile['default'] = Profile[name];
|
||||
}
|
||||
}
|
||||
|
||||
Boards.getSelectedBoardConfig = () => {
|
||||
const boardName = Boards.getSelectedBoardName();
|
||||
return structuredClone(Boards.dict[boardName]?.selectedOptions ?? {});
|
||||
}
|
||||
|
||||
Boards.getSelectedBoardCommandParam = () => {
|
||||
return Boards.configMenu.getSelectedParams();
|
||||
}
|
||||
|
||||
Boards.getSelectedBoardConfigParam = (name) => {
|
||||
return Boards.configMenu.getSelectedParamByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @function 更新当前所选择板卡及其相关配置
|
||||
* @param boardName {string} 板卡名
|
||||
* @return {void}
|
||||
**/
|
||||
Boards.changeTo = (boardName) => {
|
||||
Boards.configMenu.changeTo(boardName);
|
||||
if (Profile[boardName]) {
|
||||
Profile['default'] = Profile[boardName];
|
||||
} else {
|
||||
Profile['default'] = Profile['default'] ?? {};
|
||||
}
|
||||
EditorBlockly.reloadWorkspace();
|
||||
const boardKey = Boards.dict[boardName].key;
|
||||
|
||||
for (let i in SELECTED_BOARD) {
|
||||
delete SELECTED_BOARD[i];
|
||||
}
|
||||
for (let i in BOARD) {
|
||||
if (BOARD[i] instanceof Object) {
|
||||
SELECTED_BOARD[i] = { ...BOARD[i] };
|
||||
} else {
|
||||
SELECTED_BOARD[i] = BOARD[i];
|
||||
}
|
||||
}
|
||||
SELECTED_BOARD['boardName'] = boardName;
|
||||
if (BOARD.web instanceof Object) {
|
||||
for (let value of [{
|
||||
type: 'burn',
|
||||
obj: BOARD.web.burn
|
||||
}, {
|
||||
type: 'upload',
|
||||
obj: BOARD.web.upload
|
||||
}]) {
|
||||
if (!(value.obj instanceof Object)) {
|
||||
continue;
|
||||
}
|
||||
let outObj;
|
||||
if (value.obj[boardKey]) {
|
||||
outObj = { ...value.obj, ...value.obj[boardKey] };
|
||||
} else {
|
||||
outObj = { ...value.obj };
|
||||
}
|
||||
for (let i in Boards.dict) {
|
||||
const key = Boards.dict[i].key;
|
||||
if (outObj[key]) {
|
||||
delete outObj[key];
|
||||
}
|
||||
}
|
||||
SELECTED_BOARD.web[value.type] = outObj;
|
||||
}
|
||||
}
|
||||
for (let value of [{
|
||||
type: 'burn',
|
||||
obj: BOARD.burn
|
||||
}, {
|
||||
type: 'upload',
|
||||
obj: BOARD.upload
|
||||
}, {
|
||||
type: 'serial',
|
||||
obj: BOARD.serial
|
||||
}]) {
|
||||
if (!(value.obj instanceof Object)) {
|
||||
continue;
|
||||
}
|
||||
let outObj;
|
||||
if (value.obj[boardKey]) {
|
||||
outObj = { ...value.obj, ...value.obj[boardKey] };
|
||||
} else {
|
||||
outObj = { ...value.obj };
|
||||
}
|
||||
for (let i in Boards.dict) {
|
||||
const key = Boards.dict[i].key;
|
||||
if (outObj[key]) {
|
||||
delete outObj[key];
|
||||
}
|
||||
}
|
||||
const pathObj = {
|
||||
path: Env.clientPath,
|
||||
indexPath: Env.boardDirPath,
|
||||
srcPath: Env.srcDirPath
|
||||
};
|
||||
switch (outObj.type) {
|
||||
case 'volume':
|
||||
if (Env.currentPlatform == "win32") {
|
||||
if (typeof outObj.volumeName == "string") {
|
||||
outObj.volume = "VolumeName='" + outObj.volumeName + "'";
|
||||
} else if (typeof outObj.volumeName == "object") {
|
||||
outObj.volume = "VolumeName='" + outObj.volumeName[0] + "'";
|
||||
for (let i = 1; i < outObj.volumeName.length; i++) {
|
||||
outObj.volume += " or VolumeName='" + outObj.volumeName[i] + "'";
|
||||
}
|
||||
} else {
|
||||
outObj.volume = "VolumeName='CIRCUITPY'";
|
||||
}
|
||||
} else {
|
||||
if (typeof outObj.volumeName == "string") {
|
||||
outObj.volume = outObj.volumeName;
|
||||
} else if (typeof outObj.volumeName == "object") {
|
||||
outObj.volume = outObj.volumeName[0];
|
||||
for (var i = 1; i < outObj.volumeName.length; i++) {
|
||||
outObj.volume += "/" + outObj.volumeName[i];
|
||||
}
|
||||
} else {
|
||||
outObj.volume = "CIRCUITPY";
|
||||
}
|
||||
}
|
||||
outObj.filePath = MString.tpl(outObj.filePath, pathObj);
|
||||
break;
|
||||
case 'command':
|
||||
let pyToolsPath = "{srcPath}/tools/python/";
|
||||
let obj = {};
|
||||
let pyTools = {
|
||||
'esptool': 'esptool/__init__.py',
|
||||
'kflash': 'kflash.py',
|
||||
'stm32loader': 'stm32loader.py',
|
||||
'stm32bl': 'stm32bl.py',
|
||||
'ampy': 'ampy/cli.py'
|
||||
};
|
||||
for (let key in pyTools) {
|
||||
obj[key] = Env.python3Path + "\" \"" + pyToolsPath + pyTools[key];
|
||||
}
|
||||
if (outObj.reset) {
|
||||
let resetStr = '{}';
|
||||
try {
|
||||
resetStr = JSON.stringify(outObj.reset);
|
||||
resetStr = resetStr.replaceAll('\"', '\\\"');
|
||||
obj.reset = resetStr;
|
||||
} catch (error) {
|
||||
Debug.error(error);
|
||||
}
|
||||
}
|
||||
outObj.command = MString.tpl(outObj.command, obj);
|
||||
outObj.command = MString.tpl(outObj.command, pathObj);
|
||||
if (outObj.special && outObj.special instanceof Array) {
|
||||
for (let key in outObj.special) {
|
||||
if (!outObj.special[key]?.name
|
||||
|| !outObj.special[key]?.command) {
|
||||
continue;
|
||||
}
|
||||
outObj.special[key].command = MString.tpl(outObj.special[key].command, obj);
|
||||
outObj.special[key].command = MString.tpl(outObj.special[key].command, pathObj);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (value.type === 'upload' && (goog.isElectron || Env.hasSocketServer) && outObj.copyLib) {
|
||||
if (outObj.libPath) {
|
||||
let libPath = [];
|
||||
for (let dirPath of outObj.libPath) {
|
||||
libPath.push(MString.tpl(dirPath, pathObj));
|
||||
}
|
||||
outObj.libPath = libPath;
|
||||
} else {
|
||||
outObj.libPath = [ path.join(Env.boardDirPath, 'build/lib/') ];
|
||||
}
|
||||
}
|
||||
if (value.type === 'upload' && (goog.isElectron || Env.hasSocketServer)) {
|
||||
if (outObj.filePath) {
|
||||
outObj.filePath = MString.tpl(outObj.filePath, pathObj);
|
||||
} else {
|
||||
outObj.filePath = path.join(Env.boardDirPath, 'build/main.py');
|
||||
}
|
||||
}
|
||||
SELECTED_BOARD[value.type] = outObj;
|
||||
}
|
||||
}
|
||||
|
||||
Boards.updateCategories = (boardName, enforce = false) => {
|
||||
if (Boards.selected === boardName && !enforce) return;
|
||||
Boards.selected = boardName;
|
||||
$('#mixly-footer-boardname').html(boardName);
|
||||
let thirdPartyStr = '';
|
||||
if (goog.isElectron) {
|
||||
thirdPartyStr = Env.thirdPartyXML.join('');
|
||||
}
|
||||
const searchCategoryStr = '<category id="catSearch" hidden="true" colour="#ff6666"><label text="'
|
||||
+ Msg.Lang['toolboxSearcher.empty']
|
||||
+ '"></label></category>';
|
||||
thirdPartyStr = Boards.selectCategories(boardName, thirdPartyStr);
|
||||
const toolboxDom = $('#toolbox');
|
||||
toolboxDom.html(
|
||||
Boards.selectCategories(boardName, XML.CATEGORIES_STR[boardName] ?? Env.defaultXML)
|
||||
);
|
||||
toolboxDom.append(thirdPartyStr);
|
||||
toolboxDom.append(searchCategoryStr);
|
||||
const categoriesDom = toolboxDom.find('category');
|
||||
for (let i = 0; categoriesDom[i]; i++) {
|
||||
if (categoriesDom[i].hasAttribute('toolboxitemid')) continue;
|
||||
categoriesDom[i].setAttribute('toolboxitemid', categoriesDom[i].id);
|
||||
}
|
||||
Msg.renderToolbox(false);
|
||||
EditorBlockly.updateToolbox();
|
||||
}
|
||||
|
||||
Boards.selectCategories = (boardName, categoriesStr) => {
|
||||
const boardKeyList = (Boards.dict[boardName] ? Boards.dict[boardName].key : '').split(':');
|
||||
if (!boardKeyList.length) return categoriesStr;
|
||||
const xmlDom = $('<xml></xml>');
|
||||
xmlDom.html(categoriesStr);
|
||||
const categories = xmlDom.find('category');
|
||||
for (let i = 0; categories[i]; i++) {
|
||||
const removed = Boards.removeBlocks($(categories[i]), boardKeyList);
|
||||
if (!removed) {
|
||||
const blocks = $(categories[i]).children('block');
|
||||
for (let j = 0; blocks[j]; j++) {
|
||||
Boards.removeBlocks($(blocks[j]), boardKeyList);
|
||||
}
|
||||
}
|
||||
}
|
||||
return xmlDom.html();
|
||||
}
|
||||
|
||||
Boards.removeBlocks = (blocksdom, boardKeyList) => {
|
||||
const mShow = blocksdom.attr('m-show');
|
||||
const mHide = blocksdom.attr('m-hide');
|
||||
if (mShow || mHide) {
|
||||
const select = mShow ? mShow : mHide;
|
||||
let needRemove = mShow ? true : false;
|
||||
const selectList = select.split(' ');
|
||||
for (let key of selectList) {
|
||||
const keyList = key.split(':');
|
||||
const len = keyList.length;
|
||||
if (![1, 2, 3].includes(len)) {
|
||||
continue;
|
||||
}
|
||||
if ([2, 3].includes(len)) {
|
||||
const param3 = (len === 3 ? String(keyList[2]).split(',') : []);
|
||||
if (keyList[0] === boardKeyList[0]
|
||||
&& keyList[1] === boardKeyList[1]) {
|
||||
if (!param3.length) {
|
||||
needRemove = mShow ? false : true;
|
||||
break;
|
||||
}
|
||||
for (let value of param3) {
|
||||
if (value === boardKeyList[2]) {
|
||||
needRemove = mShow ? false : true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (keyList[0] === boardKeyList[2]) {
|
||||
needRemove = mShow ? false : true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((!needRemove && mShow) || (needRemove && !mShow))
|
||||
break;
|
||||
}
|
||||
if (needRemove) {
|
||||
blocksdom.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user