1214 lines
52 KiB
JavaScript
1214 lines
52 KiB
JavaScript
|
editor_blockly = function () {
|
|||
|
|
|||
|
var editor_blockly = { entryType: 'event' };
|
|||
|
|
|||
|
editor.uivalues.disableBlocklyReplace = editor.config.get("disableBlocklyReplace", false);
|
|||
|
var replaceCheckbox = document.getElementById('blocklyReplace');
|
|||
|
replaceCheckbox.checked = !editor.uivalues.disableBlocklyReplace;
|
|||
|
|
|||
|
editor_blockly.triggerReplace = function () {
|
|||
|
editor.uivalues.disableBlocklyReplace = !replaceCheckbox.checked;
|
|||
|
editor.config.set("disableBlocklyReplace", !replaceCheckbox.checked);
|
|||
|
if (MotaActionFunctions) MotaActionFunctions.disableReplace = !replaceCheckbox.checked;
|
|||
|
alert("已" + (replaceCheckbox.checked ? "开启" : "关闭") + "中文变量名替换!\n关闭并重开事件编辑器以生效。");
|
|||
|
}
|
|||
|
|
|||
|
editor.uivalues.disableBlocklyExpandCompare = editor.config.get("disableBlocklyExpandCompare", false);
|
|||
|
var expandCompareCheckbox = document.getElementById('blocklyExpandCompare');
|
|||
|
expandCompareCheckbox.checked = !editor.uivalues.disableBlocklyExpandCompare;
|
|||
|
|
|||
|
editor_blockly.triggerExpandCompare = function () {
|
|||
|
editor.uivalues.disableBlocklyExpandCompare = !expandCompareCheckbox.checked;
|
|||
|
editor.config.set("disableBlocklyExpandCompare", !expandCompareCheckbox.checked);
|
|||
|
if (MotaActionFunctions) MotaActionFunctions.disableExpandCompare = !expandCompareCheckbox.checked;
|
|||
|
}
|
|||
|
|
|||
|
var input_ = '';
|
|||
|
editor_blockly.runOne = function () {
|
|||
|
//var printf = console.log;
|
|||
|
//var printf = function(){};
|
|||
|
var grammerFile = input_;
|
|||
|
converter = new Converter().init();
|
|||
|
converter.generBlocks(grammerFile);
|
|||
|
//printf(converter.blocks);
|
|||
|
converter.renderGrammerName();
|
|||
|
//converter.generToolbox();
|
|||
|
converter.generMainFile();
|
|||
|
//printf(converter.mainFile.join(''));
|
|||
|
//console.log(converter);
|
|||
|
|
|||
|
|
|||
|
var script = document.createElement('script');
|
|||
|
script.innerHTML = converter.mainFile[5] + editor_blocklyconfig;
|
|||
|
document.body.appendChild(script);
|
|||
|
}
|
|||
|
var xhr = new XMLHttpRequest();
|
|||
|
xhr.onreadystatechange = function () {
|
|||
|
if (xhr.readyState != 4) return;
|
|||
|
if (xhr.status != 200) {
|
|||
|
alert("图块描述文件加载失败, 请在'启动服务.exe'中打开编辑器");
|
|||
|
return;
|
|||
|
}
|
|||
|
input_ = xhr.responseText;
|
|||
|
editor_blockly.runOne();
|
|||
|
MotaActionFunctions.disableReplace = editor.uivalues.disableBlocklyReplace;
|
|||
|
MotaActionFunctions.disableExpandCompare = editor.uivalues.disableBlocklyExpandCompare;
|
|||
|
}
|
|||
|
xhr.open('GET', '_server/MotaAction.g4', true);
|
|||
|
xhr.send(null);
|
|||
|
|
|||
|
var codeAreaHL = CodeMirror.fromTextArea(document.getElementById("codeArea"), {
|
|||
|
lineNumbers: true,
|
|||
|
matchBrackets: true,
|
|||
|
lineWrapping: true,
|
|||
|
continueComments: "Enter",
|
|||
|
extraKeys: { "Ctrl-Q": "toggleComment" },
|
|||
|
});
|
|||
|
codeAreaHL.on('changes', function () {
|
|||
|
editor_blockly.highlightParse(!changeFromBlockly);
|
|||
|
changeFromBlockly = false;
|
|||
|
});
|
|||
|
var changeFromBlockly = false;
|
|||
|
var shouldNotifyParse = false;
|
|||
|
|
|||
|
editor_blockly.showXML = function () {
|
|||
|
var xml = Blockly.Xml.workspaceToDom(editor_blockly.workspace);
|
|||
|
var xml_text = Blockly.Xml.domToPrettyText(xml);
|
|||
|
console.log(xml_text);
|
|||
|
var xml_text = Blockly.Xml.domToText(xml);
|
|||
|
console.log(xml_text);
|
|||
|
console.log(xml);
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.runCode = function () {
|
|||
|
// Generate JavaScript code and run it.
|
|||
|
window.LoopTrap = 1000;
|
|||
|
Blockly.JavaScript.INFINITE_LOOP_TRAP =
|
|||
|
'if (--window.LoopTrap == 0) throw "Infinite loop.";\n';
|
|||
|
var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace);
|
|||
|
Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
|
|||
|
try {
|
|||
|
eval('obj=' + code);
|
|||
|
console.log(obj);
|
|||
|
} catch (e) {
|
|||
|
alert(e);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.setValue = function (value) {
|
|||
|
changeFromBlockly = true;
|
|||
|
codeAreaHL.setValue(value);
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.parse = function () {
|
|||
|
MotaActionFunctions.parse(
|
|||
|
eval('obj=' + codeAreaHL.getValue().replace(/[<>&]/g, function (c) {
|
|||
|
return { '<': '<', '>': '>', '&': '&' }[c];
|
|||
|
}).replace(/\\(r|f|i|c|d|e|g|z)/g, '\\\\$1')),
|
|||
|
editor_blockly.isCommonEntry() ? 'common' : editor_blockly.entryType
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.id = '';
|
|||
|
|
|||
|
var _lastOpenPosition = {};
|
|||
|
|
|||
|
editor_blockly.import = function (id_, args) {
|
|||
|
var thisTr = document.getElementById(id_);
|
|||
|
if (!thisTr) return false;
|
|||
|
var input = thisTr.children[2].children[0].children[0];
|
|||
|
var field = thisTr.children[0].getAttribute('title');
|
|||
|
var type = args.type;
|
|||
|
if (!type) return false;
|
|||
|
editor_blockly.id = id_;
|
|||
|
editor_blockly.setValue(input.value);
|
|||
|
editor_blockly.entryType = type;
|
|||
|
editor_blockly.parse();
|
|||
|
editor_blockly.show();
|
|||
|
var _offsetIndex = [editor_blockly.entryType, editor.pos.x, editor.pos.y, editor.currentFloorId].join(":");
|
|||
|
editor_blockly.workspace.scroll(0, _lastOpenPosition[_offsetIndex] || 0)
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
var blocklyWidgetDiv = document.getElementsByClassName('blocklyWidgetDiv');
|
|||
|
editor_blockly.show = function () {
|
|||
|
if (typeof (selectBox) !== typeof (undefined)) selectBox.isSelected(false);
|
|||
|
document.getElementById('left6').style = '';
|
|||
|
for (var ii = 0, node; node = blocklyWidgetDiv[ii]; ii++) {
|
|||
|
node.style.zIndex = 201;
|
|||
|
node.style.opacity = '';
|
|||
|
}
|
|||
|
}
|
|||
|
editor_blockly.hide = function () {
|
|||
|
document.getElementById('left6').style = 'z-index:-1;opacity: 0;';
|
|||
|
for (var ii = 0, node; node = blocklyWidgetDiv[ii]; ii++) {
|
|||
|
node.style.zIndex = -1;
|
|||
|
node.style.opacity = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var blocklyParseBtn = document.getElementById('blocklyParse');
|
|||
|
editor_blockly.highlightParse = function (shouldHighLight) {
|
|||
|
if (shouldNotifyParse == shouldHighLight) return;
|
|||
|
shouldNotifyParse = shouldHighLight;
|
|||
|
if (shouldHighLight) blocklyParseBtn.classList.add('highlight');
|
|||
|
else blocklyParseBtn.classList.remove('highlight');
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.cancel = function () {
|
|||
|
var _offsetIndex = [editor_blockly.entryType, editor.pos.x, editor.pos.y, editor.currentFloorId].join(":");
|
|||
|
_lastOpenPosition[_offsetIndex] = editor_blockly.workspace.scrollY;
|
|||
|
|
|||
|
editor_blockly.id = '';
|
|||
|
editor_blockly.hide();
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.confirm = function (keep) {
|
|||
|
if (!editor_blockly.id) {
|
|||
|
editor_blockly.id = '';
|
|||
|
return;
|
|||
|
}
|
|||
|
if (shouldNotifyParse) {
|
|||
|
alert('你尚未解析修改后的内容,请进行解析或放弃操作');
|
|||
|
return;
|
|||
|
}
|
|||
|
if (editor_blockly.workspace.topBlocks_.length >= 2) {
|
|||
|
editor_blockly.setValue('入口方块只能有一个');
|
|||
|
return;
|
|||
|
}
|
|||
|
var eventType = editor_blockly.entryType;
|
|||
|
if (editor_blockly.workspace.topBlocks_.length == 1) {
|
|||
|
var blockType = editor_blockly.workspace.topBlocks_[0].type;
|
|||
|
if (blockType !== eventType + '_m' && !(editor_blockly.isCommonEntry() && blockType == 'common_m')) {
|
|||
|
editor_blockly.setValue('入口方块类型错误');
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
var setvalue = function (value) {
|
|||
|
var thisTr = document.getElementById(editor_blockly.id);
|
|||
|
var input = thisTr.children[2].children[0].children[0];
|
|||
|
input.value = value;
|
|||
|
if (!keep) {
|
|||
|
editor_blockly.id = '';
|
|||
|
editor_blockly.hide();
|
|||
|
}
|
|||
|
else alert('保存成功!');
|
|||
|
input.onchange();
|
|||
|
}
|
|||
|
if (codeAreaHL.getValue() === '') {
|
|||
|
eventType === 'shop' ? setvalue('[]') : setvalue('null');
|
|||
|
return;
|
|||
|
}
|
|||
|
var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace);
|
|||
|
code = code.replace(/\\(i|c|d|e|g|z)/g, '\\\\$1');
|
|||
|
eval('var obj=' + code);
|
|||
|
if (this.checkAsync(obj) && confirm("警告!存在不等待执行完毕的事件但却没有用【等待所有异步事件处理完毕】来等待" +
|
|||
|
"它们执行完毕,这样可能会导致录像检测系统出问题。\n你要返回修改么?")) return;
|
|||
|
|
|||
|
var _offsetIndex = [editor_blockly.entryType, editor.pos.x, editor.pos.y, editor.currentFloorId].join(":");
|
|||
|
_lastOpenPosition[_offsetIndex] = editor_blockly.workspace.scrollY;
|
|||
|
setvalue(JSON.stringify(obj));
|
|||
|
}
|
|||
|
|
|||
|
// 检查"不等待处理完毕"
|
|||
|
editor_blockly.checkAsync = function (obj) {
|
|||
|
if (!(obj instanceof Array)) return false;
|
|||
|
var hasAsync = false;
|
|||
|
for (var i = 0; i < obj.length; ++i) {
|
|||
|
var one = obj[i];
|
|||
|
if (one.type == 'if' && (this.checkAsync(one['true']) || this.checkAsync(one['false'])))
|
|||
|
return true;
|
|||
|
if ((one.type == 'while' || one.type == 'dowhile') && this.checkAsync(one.data))
|
|||
|
return true;
|
|||
|
if (one.type == 'confirm' && (this.checkAsync(one.yes) || this.checkAsync(one.no)))
|
|||
|
return true;
|
|||
|
if (one.type == 'choices') {
|
|||
|
var list = one.choices;
|
|||
|
if (list instanceof Array) {
|
|||
|
for (var j = 0; j < list.length; j++) {
|
|||
|
if (this.checkAsync(list[j].action)) return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (one.type == 'switch') {
|
|||
|
var list = one.caseList;
|
|||
|
if (list instanceof Array) {
|
|||
|
for (var j = 0; j < list.length; j++) {
|
|||
|
if (this.checkAsync(list[j].action)) return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (one.type == 'wait') {
|
|||
|
var list = one.data;
|
|||
|
if (list instanceof Array) {
|
|||
|
for (var j = 0; j < list.length; j++) {
|
|||
|
if (this.checkAsync(list[j].action)) return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (one.type == 'previewUI' && this.checkAsync(one.action)) return true;
|
|||
|
if (one.async && one.type != 'animate' && one.type != 'function' && one.type != 'text') hasAsync = true;
|
|||
|
if (one.type == 'waitAsync' || one.type == 'stopAsync') hasAsync = false;
|
|||
|
}
|
|||
|
return hasAsync;
|
|||
|
}
|
|||
|
|
|||
|
var _isTextAttributeSet = false;
|
|||
|
|
|||
|
editor_blockly.previewBlock = function (b, args) {
|
|||
|
|
|||
|
var previewTextDrawing = function (content) {
|
|||
|
var arr = [];
|
|||
|
content.replace(/(\f|\\f)\[(.*?)]/g, function (text, sympol, str) {
|
|||
|
var list = str.split(",");
|
|||
|
if (list.length == 3 || list.length == 5 || list.length >= 9) {
|
|||
|
var name = list[0];
|
|||
|
var obj = { "type": "drawImage" };
|
|||
|
if (name.endsWith(":o") || name.endsWith(":x") || name.endsWith(":y")) {
|
|||
|
obj.reverse = name.substring(name.length - 2);
|
|||
|
name = name.substring(0, name.length - 2);
|
|||
|
}
|
|||
|
obj.image = name;
|
|||
|
obj.x = parseFloat(list[1]);
|
|||
|
obj.y = parseFloat(list[2]);
|
|||
|
if (list.length >= 5) {
|
|||
|
obj.w = parseFloat(list[3]);
|
|||
|
obj.h = parseFloat(list[4]);
|
|||
|
}
|
|||
|
if (list.length >= 9) {
|
|||
|
obj.x1 = parseFloat(list[5]);
|
|||
|
obj.y1 = parseFloat(list[6]);
|
|||
|
obj.w1 = parseFloat(list[7]);
|
|||
|
obj.h1 = parseFloat(list[8]);
|
|||
|
}
|
|||
|
if (list.length >= 10) {
|
|||
|
arr.push({ "type": "setAttribute", "alpha": parseFloat(list[9]) });
|
|||
|
}
|
|||
|
if (list.length >= 11) {
|
|||
|
obj.angle = parseFloat(list[10]);
|
|||
|
}
|
|||
|
arr.push(obj);
|
|||
|
}
|
|||
|
return "";
|
|||
|
});
|
|||
|
editor.uievent.previewUI(arr);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
// 特殊处理立绘
|
|||
|
if (b.type == 'textDrawing') {
|
|||
|
previewTextDrawing(Blockly.JavaScript.blockToCode(b));
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\(i|c|d|e|g|z)/g, '\\\\$1') + "]";
|
|||
|
eval("var obj=" + code);
|
|||
|
if (obj.length == 0) return true;
|
|||
|
obj = obj[0];
|
|||
|
switch (b.type) {
|
|||
|
case 'text_0_s':
|
|||
|
case 'text_1_s':
|
|||
|
case 'text_2_s':
|
|||
|
case 'choices_s':
|
|||
|
case 'confirm_s':
|
|||
|
if (!_isTextAttributeSet) {
|
|||
|
alert('警告!你尚未设置用于预览的剧情文本的属性,将采用默认属性进行预览。\n你可以双击“设置剧情文本的属性”事件来设置用于预览的属性。');
|
|||
|
core.status.textAttribute = core.clone(core.initStatus.textAttribute);
|
|||
|
_isTextAttributeSet = true;
|
|||
|
}
|
|||
|
editor.uievent.previewUI([obj]);
|
|||
|
break;
|
|||
|
case 'setText_s': // 设置剧情文本的属性
|
|||
|
_isTextAttributeSet = true;
|
|||
|
core.status.textAttribute = core.clone(core.initStatus.textAttribute);
|
|||
|
core.setTextAttribute(obj);
|
|||
|
alert('已成功设置此属性为显示文章的预览属性!')
|
|||
|
break;
|
|||
|
case 'waitContext_2': // 等待用户操作坐标预览
|
|||
|
editor.uievent.previewUI([{
|
|||
|
"type": "fillRect", "x": obj.px[0], "y": obj.py[0],
|
|||
|
"width": "(" + obj.px[1] + ")-(" + obj.px[0] + ")", "height": "(" + obj.py[1] + ")-(" + obj.py[0] + ")",
|
|||
|
"style": "rgba(255,0,0,0.5)"
|
|||
|
}]);
|
|||
|
break;
|
|||
|
case 'showImage_s': // 显示图片
|
|||
|
case 'showImage_1_s':
|
|||
|
if (obj.sloc) {
|
|||
|
editor.uievent.previewUI([
|
|||
|
{ type: "setAttribute", alpha: obj.opacity },
|
|||
|
{
|
|||
|
type: "drawImage", image: obj.image, x: obj.sloc[0], y: obj.sloc[1], w: obj.sloc[2], h: obj.sloc[3],
|
|||
|
x1: obj.loc[0], y1: obj.loc[1], w1: obj.loc[2], h1: obj.loc[3], reverse: obj.reverse
|
|||
|
}
|
|||
|
]);
|
|||
|
} else {
|
|||
|
editor.uievent.previewUI([
|
|||
|
{ type: "setAttribute", alpha: obj.opacity },
|
|||
|
{ type: "drawImage", image: obj.image, x: obj.loc[0], y: obj.loc[1], w: obj.loc[2], h: obj.loc[3], reverse: obj.reverse }
|
|||
|
]);
|
|||
|
}
|
|||
|
break;
|
|||
|
case 'showGif_s': // 显示动图
|
|||
|
if (obj.name && obj.loc) {
|
|||
|
editor.uievent.previewUI([{ type: "drawImage", image: obj.name, x: obj.loc[0], y: obj.loc[1] }]);
|
|||
|
}
|
|||
|
break;
|
|||
|
case 'setCurtain_0_s': // 更改色调
|
|||
|
if (obj.color) {
|
|||
|
editor.uievent.previewUI([{ type: "fillRect", x: 0, y: 0, width: core.__PIXELS__, height: core.__PIXELS__, style: obj.color }]);
|
|||
|
}
|
|||
|
break;
|
|||
|
case 'floorOneImage': // 楼层贴图
|
|||
|
obj.w = obj.w / (obj.frame || 1);
|
|||
|
editor.uievent.previewUI([
|
|||
|
{
|
|||
|
type: "drawImage", image: obj.name, x: obj.sx || 0, y: obj.sy || 0, w: obj.w, h: obj.h,
|
|||
|
x1: obj.x, y1: obj.y, w1: obj.w, h1: obj.h, reverse: obj.reverse
|
|||
|
}
|
|||
|
]);
|
|||
|
break;
|
|||
|
case 'previewUI_s': // 预览
|
|||
|
editor.uievent.previewUI(obj.action);
|
|||
|
break;
|
|||
|
default:
|
|||
|
if (b.type.startsWith(obj.type)) {
|
|||
|
editor.uievent.previewUI([obj]);
|
|||
|
}
|
|||
|
}
|
|||
|
} catch (ee) { console.error(ee) }
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.selectMaterial = function (b, material) {
|
|||
|
var value = b.getFieldValue(material[1]);
|
|||
|
value = main.nameMap[value] || value;
|
|||
|
editor.uievent.selectMaterial([value], '请选择素材', material[0], function (one) {
|
|||
|
if (b.type == 'animate_s' || b.type == 'animate_1_s' || b.type == 'nameMapAnimate') {
|
|||
|
return /^[-A-Za-z0-9_.]+\.animate$/.test(one) ? one.substring(0, one.length - 8) : null;
|
|||
|
}
|
|||
|
return /^[-A-Za-z0-9_.]+$/.test(one) ? one : null;
|
|||
|
}, function (value) {
|
|||
|
if (value instanceof Array && value.length > 0) {
|
|||
|
value = value[0];
|
|||
|
// 检测是否别名替换
|
|||
|
for (var name in main.nameMap) {
|
|||
|
if (main.nameMap[name] == value) {
|
|||
|
if (confirm("检测到该文件存在别名:" + name + "\n是否使用别名进行替换?")) {
|
|||
|
b.setFieldValue(name, material[1]);
|
|||
|
return;
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
b.setFieldValue(value, material[1]);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.doubleclicktext = function (b, f) {
|
|||
|
var value = b.getFieldValue(f);
|
|||
|
//多行编辑
|
|||
|
editor_multi.multiLineEdit(value, b, f, { 'lint': f === 'RawEvalString_0' }, function (newvalue, b, f) {
|
|||
|
if (!f.startsWith('EvalString_Multi')) {
|
|||
|
newvalue = newvalue.split('\n').join('\\n');
|
|||
|
}
|
|||
|
b.setFieldValue(newvalue, f);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.doubleClickBlock = function (blockId) {
|
|||
|
var b = editor_blockly.workspace.getBlockById(blockId);
|
|||
|
|
|||
|
if (b && MotaActionBlocks[b.type].previewBlock) {
|
|||
|
editor_blockly.previewBlock(b, MotaActionBlocks[b.type].previewBlock)
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (b && MotaActionBlocks[b.type].selectPoint) { // selectPoint
|
|||
|
editor_blockly.selectPoint(b, eval(MotaActionBlocks[b.type].selectPoint));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (b && MotaActionBlocks[b.type].material) {
|
|||
|
editor_blockly.selectMaterial(b, JSON.parse(MotaActionBlocks[b.type].material));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (b && MotaActionBlocks[b.type].doubleclicktext) { //多行编辑
|
|||
|
editor_blockly.doubleclicktext(b, MotaActionBlocks[b.type].doubleclicktext);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.selectPointFromButton = function () {
|
|||
|
var b = Blockly.selected;
|
|||
|
if (b && MotaActionBlocks[b.type].selectPoint) {
|
|||
|
editor_blockly.selectPoint(b, eval(MotaActionBlocks[b.type].selectPoint));
|
|||
|
return;
|
|||
|
} else {
|
|||
|
editor.uievent.selectPoint();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.showKeyCodes = function () {
|
|||
|
alert('键值查询表:\nA65 B66 C67 D68 E69 F70 G71 H72 I73 J74 K75 L76 M77\n'
|
|||
|
+ 'N78 O79 P80 Q81 R82 S83 T84 U85 V86 W87 X88 Y89 Z90\n0:48 1:49 2:50 3:51 4:52 5:53 6:54 7:55 8:56 9:57\n'
|
|||
|
+ '空格:13 回车:32 ESC:27 后退:8 Tab:9 Shift:16 Ctrl:17 Alt:18\nPgUp:33 PgDn:34 左:37 上:38 右:39 下:40\n更多键值请自行百度查表')
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.lastUsedType = [
|
|||
|
'text_0_s',
|
|||
|
'comment_s',
|
|||
|
'show_s',
|
|||
|
'hide_s',
|
|||
|
'setValue_s',
|
|||
|
'if_s',
|
|||
|
'while_s',
|
|||
|
'battle_s',
|
|||
|
'openDoor_s',
|
|||
|
'choices_s',
|
|||
|
'setText_s',
|
|||
|
'exit_s',
|
|||
|
'sleep_s',
|
|||
|
'setBlock_s',
|
|||
|
'insert_1_s'
|
|||
|
]; // 最常用的15个事件
|
|||
|
editor_blockly.lastUsedTypeNum = 15;
|
|||
|
|
|||
|
editor_blockly.addIntoLastUsedType = function (blockId) {
|
|||
|
var b = editor_blockly.workspace.getBlockById(blockId);
|
|||
|
if (!b) return;
|
|||
|
var blockType = b.type;
|
|||
|
if (!blockType || blockType.indexOf("_s") !== blockType.length - 2 || blockType === 'pass_s') return;
|
|||
|
editor_blockly.lastUsedType = editor_blockly.lastUsedType.filter(function (v) { return v !== blockType; });
|
|||
|
if (editor_blockly.lastUsedType.length >= editor_blockly.lastUsedTypeNum)
|
|||
|
editor_blockly.lastUsedType.pop();
|
|||
|
editor_blockly.lastUsedType.unshift(blockType);
|
|||
|
|
|||
|
document.getElementById("searchBlock").value = '';
|
|||
|
}
|
|||
|
|
|||
|
// Index from 1 - 9
|
|||
|
editor_blockly.openToolbox = function (index) {
|
|||
|
if (index < 0) index += editor_blockly.workspace.toolbox_.tree_.children_.length;
|
|||
|
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index]);
|
|||
|
}
|
|||
|
editor_blockly.reopenToolbox = function (index) {
|
|||
|
if (index < 0) index += editor_blockly.workspace.toolbox_.tree_.children_.length;
|
|||
|
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index]);
|
|||
|
editor_blockly.workspace.getFlyout().show(editor_blockly.workspace.toolbox_.tree_.children_[index].blocks);
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.closeToolbox = function () {
|
|||
|
editor_blockly.workspace.toolbox_.clearSelection();
|
|||
|
}
|
|||
|
|
|||
|
var searchInput = document.getElementById("searchBlock");
|
|||
|
searchInput.onfocus = function () {
|
|||
|
editor_blockly.reopenToolbox(-1);
|
|||
|
}
|
|||
|
|
|||
|
searchInput.oninput = function () {
|
|||
|
editor_blockly.reopenToolbox(-1);
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.searchBlock = function (value) {
|
|||
|
if (value == null) value = searchInput.value;
|
|||
|
value = value.toLowerCase();
|
|||
|
if (value == '') return editor_blockly.lastUsedType;
|
|||
|
var results = [];
|
|||
|
for (var name in MotaActionBlocks) {
|
|||
|
if (typeof name !== 'string' || name.indexOf("_s") !== name.length - 2) continue;
|
|||
|
var block = MotaActionBlocks[name];
|
|||
|
if (block && block.json) {
|
|||
|
if ((block.json.type || "").toLowerCase().indexOf(value) >= 0
|
|||
|
|| (block.json.message0 || "").toLowerCase().indexOf(value) >= 0
|
|||
|
|| (block.json.tooltip || "").toLowerCase().indexOf(value) >= 0) {
|
|||
|
results.push(name);
|
|||
|
if (results.length >= editor_blockly.lastUsedTypeNum)
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return results.length == 0 ? editor_blockly.lastUsedType : results;
|
|||
|
}
|
|||
|
|
|||
|
// ------ select point ------
|
|||
|
|
|||
|
editor_blockly.selectPoint = function (block, arr) {
|
|||
|
|
|||
|
var floorId = editor.currentFloorId, pos = editor.pos, x = pos.x, y = pos.y;
|
|||
|
|
|||
|
var xv = block.getFieldValue(arr[0]), yv = block.getFieldValue(arr[1]);
|
|||
|
if (xv != null) x = xv;
|
|||
|
if (yv != null) y = yv;
|
|||
|
if (arr[2] != null) floorId = block.getFieldValue(arr[2]) || floorId;
|
|||
|
|
|||
|
editor.uievent.selectPoint(floorId, x, y, false, function (fv, xv, yv) {
|
|||
|
if (!arr) return;
|
|||
|
if (arr[2] != null) {
|
|||
|
if (fv != editor.currentFloorId || editor_blockly.entryType == 'commonEvent') block.setFieldValue(fv, arr[2]);
|
|||
|
else block.setFieldValue(arr[3] ? fv : "", arr[2]);
|
|||
|
}
|
|||
|
block.setFieldValue(xv + "", arr[0]);
|
|||
|
block.setFieldValue(yv + "", arr[1]);
|
|||
|
if (block.type == 'changeFloor_m' || block.type == 'changeFloor_s') {
|
|||
|
block.setFieldValue("floorId", "Floor_List_0");
|
|||
|
block.setFieldValue("loc", "Stair_List_0");
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.getAutoCompletions = function (content, type, name, pb) {
|
|||
|
// --- content为当前框中输入内容;将返回一个列表,为后续所有可补全内容
|
|||
|
|
|||
|
// console.log(type, name);
|
|||
|
|
|||
|
// 检查 status:xxx,item:xxx和flag:xxx
|
|||
|
var index = Math.max(content.lastIndexOf(":"), content.lastIndexOf(":"));
|
|||
|
if (index >= 0) {
|
|||
|
var ch = content.charAt(index);
|
|||
|
var before = content.substring(0, index), token = content.substring(index + 1);
|
|||
|
if (/^[a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]*$/.test(token)) {
|
|||
|
if (before.endsWith("状态") || (ch == ':' && before.endsWith("status"))) {
|
|||
|
var list = Object.keys(core.status.hero);
|
|||
|
if (before.endsWith("状态") && MotaActionFunctions) {
|
|||
|
list = MotaActionFunctions.pattern.replaceStatusList.map(function (v) {
|
|||
|
return v[1];
|
|||
|
}).concat(list);
|
|||
|
}
|
|||
|
return list.filter(function (one) {
|
|||
|
return one != token && one.startsWith(token);
|
|||
|
}).sort();
|
|||
|
}
|
|||
|
else if (before.endsWith("物品") || (ch == ':' && before.endsWith("item"))) {
|
|||
|
var list = Object.keys(core.material.items);
|
|||
|
if (before.endsWith("物品") && MotaActionFunctions) {
|
|||
|
list = MotaActionFunctions.pattern.replaceItemList.map(function (v) {
|
|||
|
return v[1];
|
|||
|
}).concat(list);
|
|||
|
}
|
|||
|
return list.filter(function (one) {
|
|||
|
return one != token && one.startsWith(token);
|
|||
|
}).sort();
|
|||
|
}
|
|||
|
else if (before.endsWith("变量") || (ch == ':' && before.endsWith("flag"))) {
|
|||
|
return Object.keys(editor.used_flags || {}).filter(function (one) {
|
|||
|
return one != token && one.startsWith(token);
|
|||
|
}).sort();
|
|||
|
} else if (before.endsWith("怪物") || (ch == ':' && before.endsWith("enemy"))) {
|
|||
|
var list = Object.keys(core.material.enemys);
|
|||
|
if (before.endsWith("怪物") && MotaActionFunctions) {
|
|||
|
list = MotaActionFunctions.pattern.replaceEnemyList.map(function (v) {
|
|||
|
return v[1];
|
|||
|
}).concat(list);
|
|||
|
}
|
|||
|
return list.filter(function (one) {
|
|||
|
return one != token && one.startsWith(token);
|
|||
|
})
|
|||
|
} else {
|
|||
|
var index2 = Math.max(content.lastIndexOf(":", index - 1), content.lastIndexOf(":", index - 1));
|
|||
|
var ch2 = content.charAt(index2);
|
|||
|
if (index2 >= 0) {
|
|||
|
before = content.substring(0, index2);
|
|||
|
if (before.endsWith("怪物") || (ch == ':' && ch2 == ':' && before.endsWith("enemy"))) {
|
|||
|
var list = MotaActionBlocks['EnemyId_List'].options.map(function (v) { return v[1] });
|
|||
|
if (before.endsWith("怪物") && MotaActionFunctions) {
|
|||
|
list = MotaActionFunctions.pattern.replaceEnemyValueList.map(function (v) {
|
|||
|
return v[1];
|
|||
|
}).concat(list);
|
|||
|
}
|
|||
|
return list.filter(function (one) {
|
|||
|
return one != token && one.startsWith(token);
|
|||
|
})
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 提供 core.xxx 的补全
|
|||
|
index = content.lastIndexOf("core.");
|
|||
|
if (index >= 0) {
|
|||
|
var s = content.substring(index + 5);
|
|||
|
if (/^[\w.]*$/.test(s)) {
|
|||
|
var tokens = s.split(".");
|
|||
|
var now = core, prefix = tokens[tokens.length - 1];
|
|||
|
for (var i = 0; i < tokens.length - 1; ++i) {
|
|||
|
now = now[tokens[i]];
|
|||
|
if (now == null) break;
|
|||
|
}
|
|||
|
if (now != null) {
|
|||
|
var candidates = [];
|
|||
|
for (var i in now) {
|
|||
|
candidates.push(i);
|
|||
|
}
|
|||
|
return candidates.filter(function (one) {
|
|||
|
return one != prefix && one.startsWith(prefix);
|
|||
|
}).sort();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 提供 flags.xxx 补全
|
|||
|
index = content.lastIndexOf("flags.");
|
|||
|
if (index >= 0) {
|
|||
|
var token = content.substring(index + 6);
|
|||
|
return Object.keys(editor.used_flags || {}).filter(function (one) {
|
|||
|
return one != token && one.startsWith(token)
|
|||
|
&& /^[a-zA-Z_]\w*$/.test(one);
|
|||
|
}).sort();
|
|||
|
}
|
|||
|
|
|||
|
// 提供 hero.xxx 补全
|
|||
|
index = content.lastIndexOf("hero.");
|
|||
|
if (index >= 0) {
|
|||
|
var token = content.substring(index + 6);
|
|||
|
return Object.keys(core.status.hero).filter(function (one) {
|
|||
|
return one != token && one.startsWith(token);
|
|||
|
}).sort();
|
|||
|
}
|
|||
|
|
|||
|
// 提供 IdText_0 的补全
|
|||
|
if (type == 'idIdList_e' && name == 'IdText_0') {
|
|||
|
var list = [];
|
|||
|
switch (pb.getFieldValue('Id_List_0')) {
|
|||
|
case 'status':
|
|||
|
list = Object.keys(core.status.hero);
|
|||
|
if (MotaActionFunctions && replaceCheckbox.checked) {
|
|||
|
list = MotaActionFunctions.pattern.replaceStatusList.map(function (v) {
|
|||
|
return v[1];
|
|||
|
}).concat(list);
|
|||
|
}
|
|||
|
break;
|
|||
|
case 'item':
|
|||
|
list = Object.keys(core.material.items);
|
|||
|
if (MotaActionFunctions && replaceCheckbox.checked) {
|
|||
|
list = MotaActionFunctions.pattern.replaceItemList.map(function (v) {
|
|||
|
return v[1];
|
|||
|
}).concat(list);
|
|||
|
}
|
|||
|
break;
|
|||
|
case 'flag':
|
|||
|
list = Object.keys(editor.used_flags || {});
|
|||
|
break;
|
|||
|
}
|
|||
|
return list.filter(function (one) {
|
|||
|
return one != content && one.startsWith(content);
|
|||
|
}).sort();
|
|||
|
}
|
|||
|
|
|||
|
var namesObj = {};
|
|||
|
|
|||
|
namesObj.allIds = ["this"].concat(core.getAllIconIds());
|
|||
|
namesObj.allIconIds = namesObj.allIds.concat(Object.keys(core.statusBar.icons).filter(function (x) {
|
|||
|
return core.statusBar.icons[x] instanceof Image;
|
|||
|
}));
|
|||
|
namesObj.allImages = Object.keys(core.material.images.images)
|
|||
|
.concat(Object.keys(main.nameMap).filter(function (one) { return core.material.images.images[main.nameMap[one]]; }));
|
|||
|
namesObj.allEnemys = Object.keys(core.material.enemys);
|
|||
|
if (MotaActionFunctions && !MotaActionFunctions.disableReplace) {
|
|||
|
namesObj.allEnemys = namesObj.allEnemys.concat(MotaActionFunctions.pattern.replaceEnemyList.map(function (x) {
|
|||
|
return x[1];
|
|||
|
}))
|
|||
|
}
|
|||
|
namesObj.allItems = Object.keys(core.material.items);
|
|||
|
namesObj.allEquips = namesObj.allItems.filter(function (one) { return core.material.items[one].cls == 'equips' });
|
|||
|
if (MotaActionFunctions && !MotaActionFunctions.disableReplace) {
|
|||
|
namesObj.allItems = namesObj.allItems.concat(MotaActionFunctions.pattern.replaceItemList.map(function (x) {
|
|||
|
return x[1];
|
|||
|
}));
|
|||
|
namesObj.allEquips = namesObj.allEquips.concat(MotaActionFunctions.pattern.replaceItemList.filter(function (x) {
|
|||
|
return namesObj.allEquips.includes(x[0]);
|
|||
|
}).map(function (x) { return x[1]; }));
|
|||
|
}
|
|||
|
namesObj.allAnimates = Object.keys(core.material.animates)
|
|||
|
.concat(Object.keys(main.nameMap).filter(function (one) { return core.material.animates[main.nameMap[one]]; }));
|
|||
|
namesObj.allBgms = Object.keys(core.material.bgms)
|
|||
|
.concat(Object.keys(main.nameMap).filter(function (one) { return core.material.bgms[main.nameMap[one]]; }));
|
|||
|
namesObj.allSounds = Object.keys(core.material.sounds)
|
|||
|
.concat(Object.keys(main.nameMap).filter(function (one) { return core.material.sounds[main.nameMap[one]]; }));;
|
|||
|
namesObj.allShops = Object.keys(core.status.shops);
|
|||
|
namesObj.allFloorIds = core.floorIds;
|
|||
|
namesObj.allColors = ["aqua(青色)", "black(黑色)", "blue(蓝色)", "fuchsia(品红色)", "gray(灰色)", "green(深绿色)", "lime(绿色)",
|
|||
|
"maroon(深红色)", "navy(深蓝色)", "gold(金色)", "olive(黄褐色)", "orange(橙色)", "purple(品红色)",
|
|||
|
"red(红色)", "silver(淡灰色)", "teal(深青色)", "white(白色)", "yellow(黄色)"];
|
|||
|
namesObj.allFonts = [main.styles.font].concat(main.fonts);
|
|||
|
namesObj.allDoors = ["this"].concat(Object.keys(maps_90f36752_8815_4be8_b32b_d7fad1d0542e)
|
|||
|
.map(function (key) { return maps_90f36752_8815_4be8_b32b_d7fad1d0542e[key]; })
|
|||
|
.filter(function (one) { return one.doorInfo != null; })
|
|||
|
.map(function (one) { return one.id; }));
|
|||
|
namesObj.allEvents = Object.keys(core.events.commonEvent);
|
|||
|
var filter = function (list, content) {
|
|||
|
return list.filter(function (one) {
|
|||
|
return one != content && one.startsWith(content);
|
|||
|
}).sort();
|
|||
|
}
|
|||
|
|
|||
|
// 对任意图块提供补全
|
|||
|
// 对怪物ID提供补全
|
|||
|
// 对道具ID进行补全
|
|||
|
// 对图片名进行补全
|
|||
|
// 对动画进行补全
|
|||
|
// 对音乐进行补全
|
|||
|
// 对音效进行补全
|
|||
|
// 对全局商店进行补全
|
|||
|
// 对楼层名进行补全
|
|||
|
for (var ii = 0, names; names = ['allIds', 'allEnemys', 'allItems', 'allEquips', 'allImages', 'allAnimates', 'allBgms', 'allSounds', 'allShops', 'allFloorIds', 'allDoors', 'allEvents'][ii]; ii++) {
|
|||
|
if (MotaActionBlocks[type][names] && eval(MotaActionBlocks[type][names]).indexOf(name) !== -1) {
|
|||
|
return filter(namesObj[names], content);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 对\f进行自动补全
|
|||
|
index = Math.max(content.lastIndexOf("\f["), content.lastIndexOf("\\f["));
|
|||
|
if (index >= 0) {
|
|||
|
if (content.charAt(index) == '\\') index++;
|
|||
|
var after = content.substring(index + 2);
|
|||
|
if (after.indexOf(",") < 0 && after.indexOf("]") < 0) {
|
|||
|
return filter(namesObj.allImages, after);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 对\\i进行补全
|
|||
|
index = content.lastIndexOf("\\i[");
|
|||
|
if (index >= 0) {
|
|||
|
var after = content.substring(index + 3);
|
|||
|
if (after.indexOf("]") < 0) {
|
|||
|
return filter(namesObj.allIconIds, after);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 对\r进行补全
|
|||
|
index = Math.max(content.lastIndexOf("\r["), content.lastIndexOf("\\r["));
|
|||
|
if (index >= 0) {
|
|||
|
if (content.charAt(index) == '\\') index++;
|
|||
|
var after = content.substring(index + 2);
|
|||
|
if (after.indexOf("]") < 0) {
|
|||
|
return filter(namesObj.allColors, after);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 对\g进行补全
|
|||
|
index = content.lastIndexOf("\\g[");
|
|||
|
if (index >= 0) {
|
|||
|
var after = content.substring(index + 3);
|
|||
|
if (after.indexOf("]") < 0) {
|
|||
|
return filter(namesObj.allFonts, after);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 对\进行补全!
|
|||
|
if (content.charAt(content.length - 1) == '\\') {
|
|||
|
return ["n(换行)", "f(立绘)", "r(变色)", "i(图标)", "z(暂停打字)", "t(标题图标)", "b(对话框)", "c(字体大小)", "d(粗体)", "e(斜体)", "g(字体)"];
|
|||
|
}
|
|||
|
|
|||
|
return [];
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.completeItems = [];
|
|||
|
|
|||
|
editor_blockly.onTextFieldCreate = function (self, htmlInput) {
|
|||
|
var pb = self.sourceBlock_
|
|||
|
var args = MotaActionBlocks[pb.type].args
|
|||
|
var targetf = args[args.indexOf(self.name) + 1]
|
|||
|
|
|||
|
// ------ colour
|
|||
|
|
|||
|
if (targetf && targetf.slice(0, 7) === 'Colour_') {
|
|||
|
var inputDom = htmlInput;
|
|||
|
// var getValue=function(){ // 获得自己的字符串
|
|||
|
// return pb.getFieldValue(self.name);
|
|||
|
// }
|
|||
|
var setValue = function (newValue) { // 设置右边颜色块的css颜色
|
|||
|
pb.setFieldValue(newValue, targetf)
|
|||
|
}
|
|||
|
// 给inputDom绑事件
|
|||
|
inputDom.oninput = function () {
|
|||
|
var value = inputDom.value
|
|||
|
if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(value)) {
|
|||
|
setValue('rgba(' + value + ')')
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
htmlInput.onkeydown = function (e) {
|
|||
|
if (e.keyCode == 13 && awesomplete.opened && awesomplete.selected) {
|
|||
|
e.stopPropagation();
|
|||
|
e.stopImmediatePropagation();
|
|||
|
e.preventDefault();
|
|||
|
awesomplete.select();
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// --- awesomplete
|
|||
|
var awesomplete = new Awesomplete(htmlInput, {
|
|||
|
minChars: 1,
|
|||
|
maxItems: 12,
|
|||
|
autoFirst: true,
|
|||
|
replace: function (text) {
|
|||
|
text = text.toString();
|
|||
|
var index = text.indexOf("(");
|
|||
|
if (index >= 0) text = text.substring(0, index);
|
|||
|
var value = this.input.value, index = this.input.selectionEnd;
|
|||
|
if (index == null) index = value.length;
|
|||
|
if (index < awesomplete.prefix.length) index = awesomplete.prefix.length;
|
|||
|
var str = value.substring(0, index - awesomplete.prefix.length) + text + value.substring(index);
|
|||
|
this.input.value = str;
|
|||
|
pb.setFieldValue(str, self.name);
|
|||
|
self.forceRerender();
|
|||
|
self.resizeEditor_();
|
|||
|
index += text.length - awesomplete.prefix.length;
|
|||
|
this.input.setSelectionRange(index, index);
|
|||
|
|
|||
|
editor_blockly.completeItems = editor_blockly.completeItems.filter(function (x) {
|
|||
|
return x != text;
|
|||
|
});
|
|||
|
editor_blockly.completeItems.unshift(text);
|
|||
|
},
|
|||
|
filter: function () { return true; },
|
|||
|
item: function (text, input) {
|
|||
|
var id = text.label, info = core.getBlockInfo(id);
|
|||
|
var li = document.createElement("li");
|
|||
|
li.setAttribute("role", "option");
|
|||
|
li.setAttribute("aria-selected", "false");
|
|||
|
input = awesomplete.prefix.trim();
|
|||
|
if (input != "") text = text.replace(new RegExp("^" + input, "i"), "<mark>$&</mark>");
|
|||
|
li.innerHTML = text;
|
|||
|
if (info) {
|
|||
|
var height = (info.height || 32), width = 32;
|
|||
|
var scale = 75;
|
|||
|
height *= scale / 100;
|
|||
|
width *= scale / 100;
|
|||
|
var ctx = core.createCanvas('list_' + id, 0, 0, width, height),
|
|||
|
canvas = ctx.canvas;
|
|||
|
canvas.style.display = 'inline';
|
|||
|
canvas.style.marginRight = '8px';
|
|||
|
core.drawIcon(ctx, id, 0, 0, width, height);
|
|||
|
canvas.style.position = '';
|
|||
|
li.insertBefore(canvas, li.children[0]);
|
|||
|
}
|
|||
|
return li;
|
|||
|
},
|
|||
|
sort: function (a, b) {
|
|||
|
a = a.toString(); b = b.toString();
|
|||
|
var ia = editor_blockly.completeItems.indexOf(a), ib = editor_blockly.completeItems.indexOf(b);
|
|||
|
if (ia < 0) ia = editor_blockly.completeItems.length;
|
|||
|
if (ib < 0) ib = editor_blockly.completeItems.length;
|
|||
|
if (ia != ib) return ia - ib;
|
|||
|
if (a.length != b.length) return a.length - b.length;
|
|||
|
return a < b ? -1 : 1;
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
htmlInput.oninput = function () {
|
|||
|
var value = htmlInput.value, index = htmlInput.selectionEnd;
|
|||
|
if (index == null) index = value.length;
|
|||
|
value = value.substring(0, index);
|
|||
|
// cal prefix
|
|||
|
awesomplete.prefix = value;
|
|||
|
for (var i = index - 1; i >= 0; i--) {
|
|||
|
var c = value.charAt(i);
|
|||
|
if (!/^[a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]$/.test(c)) {
|
|||
|
awesomplete.prefix = value.substring(i + 1);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var list = editor_blockly.getAutoCompletions(value, pb.type, self.name, pb);
|
|||
|
|
|||
|
awesomplete.list = list;
|
|||
|
var caretPosition = getCaretCoordinates(htmlInput, htmlInput.selectionStart);
|
|||
|
awesomplete.ul.style.marginLeft = caretPosition.left - htmlInput.scrollLeft - 20 + "px";
|
|||
|
var totalHeight = parseFloat(Blockly.WidgetDiv.DIV.style.height.replace('px', ''));
|
|||
|
awesomplete.ul.style.marginTop = caretPosition.top + caretPosition.height - totalHeight + 10 + 'px';
|
|||
|
awesomplete.evaluate();
|
|||
|
}
|
|||
|
|
|||
|
awesomplete.container.style.width = "100%";
|
|||
|
|
|||
|
window.awesomplete = awesomplete;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
editor_blockly.isBlockCollapsedSupported = function (block) {
|
|||
|
var supportedDisabledBlocks = [
|
|||
|
'text_0_s', 'text_1_s', 'text_2_s', 'if_s', 'if_1_s', 'confirm_s', 'switch_s', 'choices_s',
|
|||
|
'for_s', 'forEach_s', 'while_s', 'dowhile_s', 'wait_s', 'previewUI_s',
|
|||
|
'waitContext_1', 'waitContext_2', 'waitContext_3', 'switchCase', 'choicesContext'
|
|||
|
];
|
|||
|
return supportedDisabledBlocks.indexOf(block.type || "") >= 0;
|
|||
|
}
|
|||
|
|
|||
|
return editor_blockly;
|
|||
|
}
|
|||
|
|
|||
|
// --- modify Blockly
|
|||
|
|
|||
|
Blockly.FieldColour.prototype.showEditor_ = function () {
|
|||
|
Blockly.WidgetDiv.hide();
|
|||
|
|
|||
|
// console.log('here')
|
|||
|
var self = this;
|
|||
|
var pb = self.sourceBlock_
|
|||
|
var args = MotaActionBlocks[pb.type].args
|
|||
|
var targetf = args[args.indexOf(self.name) - 1]
|
|||
|
|
|||
|
var getValue = function () {
|
|||
|
// return self.getValue() // css颜色
|
|||
|
var f = pb.getFieldValue(targetf);
|
|||
|
if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(f)) {
|
|||
|
return f;
|
|||
|
}
|
|||
|
return "";
|
|||
|
// 也可以用 pb.getFieldValue(targetf) 获得颜色块左边的域的内容
|
|||
|
}
|
|||
|
|
|||
|
var setValue = function (newValue) { // css颜色
|
|||
|
self.setValue(newValue)
|
|||
|
pb.setFieldValue(newValue.replace("rgba(", "").replace(")", ""), targetf) // 放在颜色块左边的域中
|
|||
|
}
|
|||
|
|
|||
|
setTimeout(function () {
|
|||
|
document.getElementById("colorPicker").value = getValue();
|
|||
|
// 设置位置
|
|||
|
var scaledBBox = self.getScaledBBox();
|
|||
|
openColorPicker(scaledBBox.left, scaledBBox.bottom, setValue);
|
|||
|
});
|
|||
|
|
|||
|
return document.createElement('table');
|
|||
|
};
|
|||
|
|
|||
|
Blockly.FieldColour.prototype.setValue = function (colour) {
|
|||
|
this.doValueUpdate_(colour);
|
|||
|
}
|
|||
|
|
|||
|
Blockly.FieldColour.prototype.initView = function () {
|
|||
|
this.size_ = new Blockly.utils.Size(
|
|||
|
this.getConstants().FIELD_COLOUR_DEFAULT_WIDTH,
|
|||
|
this.getConstants().FIELD_COLOUR_DEFAULT_HEIGHT);
|
|||
|
if (!this.getConstants().FIELD_COLOUR_FULL_BLOCK) {
|
|||
|
this.createBorderRect_();
|
|||
|
this.borderRect_.style['fillOpacity'] = '1';
|
|||
|
this.borderRect_.classList.add('blocklyColourFieldRect');
|
|||
|
} else {
|
|||
|
this.clickTarget_ = this.sourceBlock_.getSvgRoot();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Blockly.FieldTextInput.prototype.showInlineEditor_ = function (quietInput) {
|
|||
|
Blockly.WidgetDiv.show(
|
|||
|
this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this));
|
|||
|
this.htmlInput_ = this.widgetCreate_();
|
|||
|
this.isBeingEdited_ = true;
|
|||
|
|
|||
|
editor_blockly.onTextFieldCreate(this, this.htmlInput_);
|
|||
|
|
|||
|
if (!quietInput) {
|
|||
|
this.htmlInput_.focus({ preventScroll: true });
|
|||
|
this.htmlInput_.select();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_ = function (e) {
|
|||
|
if (e.keyCode == Blockly.utils.KeyCodes.ENTER && !(window.awesomplete && window.awesomplete.opened)) {
|
|||
|
Blockly.WidgetDiv.hide();
|
|||
|
Blockly.DropDownDiv.hideWithoutAnimation();
|
|||
|
} else if (e.keyCode == Blockly.utils.KeyCodes.ESC) {
|
|||
|
this.htmlInput_.value = this.htmlInput_.defaultValue;
|
|||
|
Blockly.WidgetDiv.hide();
|
|||
|
Blockly.DropDownDiv.hideWithoutAnimation();
|
|||
|
} else if (e.keyCode == Blockly.utils.KeyCodes.TAB) {
|
|||
|
Blockly.WidgetDiv.hide();
|
|||
|
Blockly.DropDownDiv.hideWithoutAnimation();
|
|||
|
this.sourceBlock_.tab(this, !e.shiftKey);
|
|||
|
e.preventDefault();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Blockly.FieldMultilineInput.prototype.showInlineEditor_ = function (quietInput) {
|
|||
|
Blockly.FieldMultilineInput.superClass_.showInlineEditor_.call(this, quietInput);
|
|||
|
// force to resize the input
|
|||
|
this.htmlInput_.style.height = Blockly.WidgetDiv.DIV.style.height;
|
|||
|
};
|
|||
|
|
|||
|
Blockly.FieldMultilineInput.prototype.onHtmlInputChange_ = function (e) {
|
|||
|
Blockly.FieldMultilineInput.superClass_.onHtmlInputChange_.call(this, e);
|
|||
|
// force to resize the input
|
|||
|
this.htmlInput_.style.height = Blockly.WidgetDiv.DIV.style.height;
|
|||
|
};
|
|||
|
|
|||
|
Blockly.copy_ = function (toCopy) {
|
|||
|
if (toCopy.isComment) {
|
|||
|
var xml = toCopy.toXmlWithXY();
|
|||
|
} else {
|
|||
|
var xml = Blockly.Xml.blockToDom(toCopy, true);
|
|||
|
// Copy only the selected block and internal blocks.
|
|||
|
Blockly.Xml.deleteNext(xml);
|
|||
|
// Encode start position in XML.
|
|||
|
var xy = toCopy.getRelativeToSurfaceXY();
|
|||
|
xml.setAttribute('x', toCopy.RTL ? -xy.x : xy.x);
|
|||
|
xml.setAttribute('oy', xy.y);
|
|||
|
xml.setAttribute('sy', toCopy.workspace.scrollY);
|
|||
|
}
|
|||
|
Blockly.clipboardXml_ = xml;
|
|||
|
Blockly.clipboardSource_ = toCopy.workspace;
|
|||
|
Blockly.clipboardTypeCounts_ = toCopy.isComment ? null :
|
|||
|
Blockly.utils.getBlockTypeCounts(toCopy, true);
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* Paste the provided block onto the workspace.
|
|||
|
* @param {!Element} xmlBlock XML block element.
|
|||
|
*/
|
|||
|
Blockly.WorkspaceSvg.prototype.paste = function (xmlBlock) {
|
|||
|
if (!this.rendered || xmlBlock.getElementsByTagName('block').length >=
|
|||
|
this.remainingCapacity()) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (this.currentGesture_) {
|
|||
|
this.currentGesture_.cancel(); // Dragging while pasting? No.
|
|||
|
}
|
|||
|
if (xmlBlock.tagName.toLowerCase() == 'comment') {
|
|||
|
this.pasteWorkspaceComment_(xmlBlock);
|
|||
|
} else {
|
|||
|
if (xmlBlock.hasAttribute('oy') && xmlBlock.hasAttribute('sy')) {
|
|||
|
xmlBlock.setAttribute('y', parseFloat(xmlBlock.getAttribute('oy')) + parseFloat(xmlBlock.getAttribute('sy')) - this.scrollY);
|
|||
|
}
|
|||
|
this.pasteBlock_(xmlBlock);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// -- Support showing disabled blocks
|
|||
|
|
|||
|
Blockly.Generator.prototype.blockToCode = function (block, opt_thisOnly) {
|
|||
|
if (this.isInitialized === false) {
|
|||
|
console.warn(
|
|||
|
'Generator init was not called before blockToCode was called.');
|
|||
|
}
|
|||
|
if (!block) {
|
|||
|
return '';
|
|||
|
}
|
|||
|
if (!block.isEnabled() && !editor_blockly.isBlockCollapsedSupported(block)) {
|
|||
|
// Skip past this block if it is disabled.
|
|||
|
return opt_thisOnly ? '' : this.blockToCode(block.getNextBlock());
|
|||
|
}
|
|||
|
if (block.isInsertionMarker()) {
|
|||
|
// Skip past insertion markers.
|
|||
|
return opt_thisOnly ? '' : this.blockToCode(block.getChildren(false)[0]);
|
|||
|
}
|
|||
|
|
|||
|
var func = this[block.type];
|
|||
|
if (typeof func != 'function') {
|
|||
|
throw Error('Language "' + this.name_ + '" does not know how to generate ' +
|
|||
|
'code for block type "' + block.type + '".');
|
|||
|
}
|
|||
|
// First argument to func.call is the value of 'this' in the generator.
|
|||
|
// Prior to 24 September 2013 'this' was the only way to access the block.
|
|||
|
// The current preferred method of accessing the block is through the second
|
|||
|
// argument to func.call, which becomes the first parameter to the generator.
|
|||
|
var code = func.call(block, block);
|
|||
|
if (Array.isArray(code)) {
|
|||
|
// Value blocks return tuples of code and operator order.
|
|||
|
if (!block.outputConnection) {
|
|||
|
throw TypeError('Expecting string from statement block: ' + block.type);
|
|||
|
}
|
|||
|
return [this.scrub_(block, code[0], opt_thisOnly), code[1]];
|
|||
|
} else if (typeof code == 'string') {
|
|||
|
if (this.STATEMENT_PREFIX && !block.suppressPrefixSuffix) {
|
|||
|
code = this.injectId(this.STATEMENT_PREFIX, block) + code;
|
|||
|
}
|
|||
|
if (this.STATEMENT_SUFFIX && !block.suppressPrefixSuffix) {
|
|||
|
code = code + this.injectId(this.STATEMENT_SUFFIX, block);
|
|||
|
}
|
|||
|
return this.scrub_(block, code, opt_thisOnly);
|
|||
|
} else if (code === null) {
|
|||
|
// Block has handled code generation itself.
|
|||
|
return '';
|
|||
|
}
|
|||
|
throw SyntaxError('Invalid code generated: ' + code);
|
|||
|
};
|
|||
|
|
|||
|
Blockly.BlockSvg.prototype.generateContextMenu = function () {
|
|||
|
if (this.workspace.options.readOnly || !this.contextMenu) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
// Save the current block in a variable for use in closures.
|
|||
|
var block = this;
|
|||
|
var menuOptions = [];
|
|||
|
|
|||
|
if (!this.isInFlyout) {
|
|||
|
// 删除
|
|||
|
if (this.isDeletable() && this.isMovable()) {
|
|||
|
menuOptions.push(Blockly.ContextMenu.blockDuplicateOption(block));
|
|||
|
}
|
|||
|
|
|||
|
if (editor_blockly.isBlockCollapsedSupported(this)) {
|
|||
|
menuOptions.push({
|
|||
|
text: this.isCollapsed() ? Blockly.Msg['EXPAND_BLOCK'] : Blockly.Msg['COLLAPSE_BLOCK'],
|
|||
|
enabled: true,
|
|||
|
callback: function () { block.setCollapsed(!block.collapsed_); }
|
|||
|
});
|
|||
|
|
|||
|
menuOptions.push({
|
|||
|
text: this.isEnabled() ? Blockly.Msg['DISABLE_BLOCK'] : Blockly.Msg['ENABLE_BLOCK'],
|
|||
|
enabled: !this.getInheritedDisabled(),
|
|||
|
callback: function () {
|
|||
|
var group = Blockly.Events.getGroup();
|
|||
|
if (!group) {
|
|||
|
Blockly.Events.setGroup(true);
|
|||
|
}
|
|||
|
block.setEnabled(!block.isEnabled());
|
|||
|
if (!group) {
|
|||
|
Blockly.Events.setGroup(false);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
if (this.isDeletable()) {
|
|||
|
menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
menuOptions.push(Blockly.ContextMenu.blockHelpOption(block));
|
|||
|
if (this.customContextMenu) this.customContextMenu(menuOptions);
|
|||
|
return menuOptions;
|
|||
|
};
|
|||
|
|
|||
|
Blockly.FieldDropdown.prototype.doClassValidation_ = function (opt_newValue) {
|
|||
|
return opt_newValue;
|
|||
|
}
|
|||
|
|
|||
|
Blockly.FieldDropdown.prototype.doValueUpdate_ = function (newValue) {
|
|||
|
Blockly.FieldDropdown.superClass_.doValueUpdate_.call(this, newValue);
|
|||
|
var options = this.getOptions(true);
|
|||
|
for (var i = 0, option; (option = options[i]); i++) {
|
|||
|
if (option[1] == this.value_) {
|
|||
|
this.selectedOption_ = option;
|
|||
|
}
|
|||
|
}
|
|||
|
if (this.selectedOption_[1] != this.value_) {
|
|||
|
options.push([this.value_, this.value_]);
|
|||
|
this.selectedOption_ = options[options.length - 1];
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Blockly.FieldMultilineInput.prototype.getDisplayText_ = function () {
|
|||
|
var value = this.value_;
|
|||
|
if (!value) return Blockly.Field.NBSP;
|
|||
|
var curr = '', text = '';
|
|||
|
for (var i = 0; i < value.length; ++i) {
|
|||
|
if (value[i] == '\n' || curr.length == this.maxDisplayLength) {
|
|||
|
text += curr.replace(/\s/g, Blockly.Field.NBSP) + '\n';
|
|||
|
curr = value[i] == '\n' ? '' : value[i];
|
|||
|
} else curr += value[i];
|
|||
|
}
|
|||
|
return text + curr;
|
|||
|
};
|