教你一招
Cocoscreator插件在编辑器启动时,如何自动加载并贴靠到编辑器内部?
Like This
1. package.json
配置package.json中panel的属性「popable->false」「type->‘dockable’」
{
"panel": {
//...
"type": "dockable",
"popable": false,
"title": "太帅了名称显示异常",
//...
}
}
2. main.js
判断插件是否加载、打开插件、注入贴靠脚本
load() {
//1.先判断扩展是否已经加载了
if (this.isPackageInUsing()) {
return;
}
let timer = setInterval(() => {
//2.等找到主窗口的时候,开始加载任务
if (Editor.Window && Editor.Window.main && Editor.Window.main.nativeWin) {
Editor.Window.main.nativeWin.__main__ = true;
let webContents = Editor.Window.main.nativeWin.webContents;
if (webContents) {
clearInterval(timer)
//3.打开自己的插件
Editor.Panel.open('my-package')
let windows = electron.BrowserWindow.getAllWindows();
windows.forEach((win) => {
if (!win.__main__) {
//4. 打开插件的同时,先隐藏掉插件,不然会很尬
win.hide()
}
});
//5.重点来了,由于贴靠插件需要在renderer进程,所以开始注入脚本,脚本内容「template-auto-dock.js」
webContents.executeJavaScript(fs.readFileSync(path.join(__dirname, 'template-auto-dock.js'), 'utf-8'));
}
}
}, 1000 / 30);
},
/**
* 判断扩展是否已经加载了,方法是,读取local://layout.editor.json
* 然后判断文件内是否有自己的插件名
**/
isPackageInUsing() {
let localProfile = Editor.Profile.load("local://layout.editor.json");
if (!localProfile) {
return false;
}
function getLocalPath() {
let result;
localProfile._chain.map((item) => {
if (item && item.type === 'local') {
result = item.path;
}
})
return result;
}
let fs = require('fire-fs');
let path = require('path')
let localPath = getLocalPath();
let fileName = localProfile._file;
let wholePath = path.join(localPath, fileName)
let has = fs.existsSync(wholePath)
let content;
if (!has) {
return false
} else {
content = fs.readFileSync(wholePath, 'utf-8');
}
try {
let data = JSON.parse(content);
// 1.重点就是这一句
if (!(data && data.windows && data.windows.main && data.windows.main.panels && data.windows.main.panels.indexOf('my-package') != -1)) {
return false
} else {
return true;
}
} catch (error) {}
},
3. template-auto-dock.js
贴靠插件到creator编辑器内的脚本,其中第3处注释是重点
(function(){
var timerLoadPackage = setInterval(() => {
// 1.判断是否已经贴靠
if (!window.__MY_PACKAGE_LOADED) {
try {
var dockUtil;
var dropMgr;
var panelMgr;
var tabs;
var package = 'my-package';
// 2.从renderer内存中找到这几个贴靠插件需要用到的助手,下面这段代码是核心,看不明白的留言
Object.keys(require.cache).map((file)=>{
if (/dock-utils\.js$|dock-utils\.ccc$/.test(file)) {
dockUtil = require(file);
}
if (/drag-drop\.js$|drag-drop\.ccc$/.test(file)) {
dropMgr = require(file);
}
if (/renderer\/panel\.js$|renderer\/panel\.ccc$|renderer\\panel\.js$|renderer\\panel\.ccc$/.test(file)) {
panelMgr = require(file);
}
});
[...document.getElementsByTagName('ui-dock-panel')].map((panel) => {
if (/inspector/.test(panel.innerHTML)) {
tabs = panel.$tabs;
}
})
if (dockUtil && tabs && panelMgr) {
panelMgr.close = (function(orgFunc){
return function(...args){
if ([...args][0] == package) {
let callback = [...args][1];
return orgFunc([...args][0], (error, others)=>{
callback(null, others)
});
}
return orgFunc(...args);
}
})(panelMgr.close);
dropMgr.items = (function(orgFunc){
return function(...args){
let result = window.__specified_panel ? [window.__specified_panel] : orgFunc(...args)
return result;
}
})(dropMgr.items);
window.__specified_panel = {
panelID: package,
panelPreferredHeight: 0,
panelPreferredWidth: 0,
panelRectHeight: 0,
panelRectWidth: 0
};
//3.贴靠插件,上文所有代码,都是为这句服务的
dockUtil.dropTab(tabs)
window.__specified_panel = null;
//4.可选,让自己的插件失去焦点,可以让用户无感知地加载
panelMgr.focus('inspector');
Editor.Selection.select("node");
}
} catch (error) {
console.log(error)
}
} else {
clearInterval(timerLoadPackage)
}
}, 1000 / 30);
})()