sumorobot-web/assets/js/blockly.js

261 lines
9.4 KiB
JavaScript
Raw Normal View History

2018-08-12 10:37:02 +00:00
window.addEventListener('load', function() {
2018-07-08 18:52:16 +00:00
// To remember the control_if blockId
2018-08-12 10:37:02 +00:00
var controlBlockId = '';
2018-07-08 18:52:16 +00:00
// Change the if block to be more cheerful
Blockly.Msg.LOGIC_HUE = '#44CC00';
// Remote previous and next statement from control_if block
Blockly.defineBlocksWithJsonArray([
{
"type": "controls_if",
"message0": "%{BKY_CONTROLS_IF_MSG_IF} %1",
"args0": [
{
"type": "input_value",
"name": "IF0",
"check": "Boolean"
}
],
"message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
"args1": [
{
"type": "input_statement",
"name": "DO0"
}
],
"colour": "%{BKY_LOGIC_HUE}",
"helpUrl": "%{BKY_CONTROLS_IF_HELPURL}",
"mutator": "controls_if_mutator",
"extensions": ["controls_if_tooltip"]
}
]);
// Make control_if mutator icon bigger
Blockly.Icon.prototype.renderIcon = function(cursorX) {
if (this.collapseHidden && this.block_.isCollapsed()) {
this.iconGroup_.setAttribute('display', 'none');
return cursorX;
}
this.iconGroup_.setAttribute('display', 'block');
var SIZE = 1.7;
var TOP_MARGIN = 2;
var LEFT_MARGIN = 5;
var width = this.SIZE;
if (this.block_.RTL) {
cursorX -= width;
}
this.iconGroup_.setAttribute('transform',
'translate(' + LEFT_MARGIN + ',' + TOP_MARGIN + ') scale(' + SIZE + ')');
this.computeIconLocation();
if (this.block_.RTL) {
cursorX -= Blockly.BlockSvg.SEP_SPACE_X;
} else {
cursorX += width + Blockly.BlockSvg.SEP_SPACE_X;
}
return cursorX;
};
// When mouse click occures on Blockly workspace
Blockly.utils.isRightButton = function(e) {
var target = e.target;
// When control_if block is in use
2018-08-12 10:37:02 +00:00
if (controlBlockId != '') {
2018-07-08 18:52:16 +00:00
// When the user clicks anywhere outside the mutator and not on the mutator icon
if (!$(target).is('.blocklyBubbleCanvas') && !$(target).parents().is('.blocklyBubbleCanvas')) {
if (!$(target).is('.blocklyIconGroup') && !$(target).parents().is('.blocklyIconGroup')) {
// Hide the mutator
workspace.getBlockById(controlBlockId).mutator.setVisible(false);
}
}
}
// Disable right click on Blockly workspace
return false;
};
Blockly.Blocks['sumorobot_sleep'] = {
init: function() {
2018-08-12 10:37:02 +00:00
this.setColour('#E64C00');
2018-07-08 18:52:16 +00:00
this.appendDummyInput()
2018-08-12 10:37:02 +00:00
.appendField('sleep')
2018-07-08 18:52:16 +00:00
.appendField(new Blockly.FieldTextInput('1000',
Blockly.FieldNumber.numberValidator), 'SLEEP');
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
Blockly.Blocks['sumorobot_move'] = {
init: function() {
var OPERATORS = [
['move stop', 'STOP'],
['move left', 'LEFT'],
['move right', 'RIGHT'],
['move search', 'SEARCH'],
['move forward', 'FORWARD'],
['move backward', 'BACKWARD']
];
2018-08-12 10:37:02 +00:00
this.setColour('#E60000');
2018-07-08 18:52:16 +00:00
var dropdown = new Blockly.FieldDropdown(OPERATORS);
this.appendDummyInput().appendField(dropdown, 'MOVE');
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
Blockly.Blocks['sumorobot_opponent'] = {
init: function() {
2018-08-12 10:37:02 +00:00
this.setColour('#0099E6');
2018-07-08 18:52:16 +00:00
this.appendDummyInput().appendField('opponent');
this.setOutput(true, 'Boolean');
}
};
Blockly.Blocks['sumorobot_line'] = {
init: function() {
var OPERATORS = [
['line left', 'LEFT'],
['line right', 'RIGHT']
];
2018-08-12 10:37:02 +00:00
this.setColour('#E6BF00');
2018-07-08 18:52:16 +00:00
var dropdown = new Blockly.FieldDropdown(OPERATORS);
this.appendDummyInput().appendField(dropdown, 'LINE');
this.setOutput(true, 'Boolean');
}
};
Blockly.Python['sumorobot_sleep'] = function(block) {
2018-08-12 10:37:02 +00:00
var code = 'sumorobot.sleep(' + parseFloat(block.getFieldValue('SLEEP')) + ');;' + block.id + '\n';
2018-07-08 18:52:16 +00:00
return code;
};
Blockly.Python['sumorobot_move'] = function(block) {
2018-08-12 10:37:02 +00:00
var code = 'sumorobot.move(' + block.getFieldValue('MOVE') + ');;' + block.id + '\n';
2018-07-08 18:52:16 +00:00
return code;
};
Blockly.Python['sumorobot_opponent'] = function(block) {
2018-08-15 17:53:10 +00:00
var code = 'sumorobot.is_opponent();;' + block.id;
2018-07-08 18:52:16 +00:00
return [code, Blockly.Python.ORDER_ATOMIC];
};
Blockly.Python['sumorobot_line'] = function(block) {
2018-08-15 17:53:10 +00:00
var code = 'sumorobot.is_line(' + block.getFieldValue('LINE') + ');;' + block.id;
2018-07-08 18:52:16 +00:00
return [code, Blockly.Python.ORDER_ATOMIC];
};
// Inject Blockly
var blocklyArea = document.getElementById('blocklyArea');
var blocklyDiv = document.getElementById('blocklyDiv');
2018-08-12 10:37:02 +00:00
workspace = Blockly.inject(blocklyDiv, {
2018-07-08 18:52:16 +00:00
scrollbars: false,
media: 'assets/blockly/media/',
trashcan: true,
sounds: true,
zoom: {
controls: true,
startScale: 1.2
},
toolbox: document.getElementById('toolbox')
});
// On Blockly resize
var onresize = function(e) {
// Compute the absolute coordinates and dimensions of blocklyArea.
var element = blocklyArea;
var x = 0;
var y = 0;
do {
x += element.offsetLeft;
y += element.offsetTop;
element = element.offsetParent;
} while (element);
// Position blocklyDiv over blocklyArea
blocklyDiv.style.left = x + 'px';
blocklyDiv.style.top = y + 'px';
blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
};
window.addEventListener('resize', onresize, false);
onresize();
Blockly.svgResize(workspace);
// Retrieve the blocks
2018-08-12 10:37:02 +00:00
var xml = Blockly.Xml.textToDom(getLocalStorageItem('sumorobot.blockly'));
2018-07-08 18:52:16 +00:00
// Resume the blocks
Blockly.Xml.domToWorkspace(xml, workspace);
2018-08-15 18:07:26 +00:00
// Show the code in the ace editor, filter out block IDs
readOnlyCodingEditor.setValue('\n' + Blockly.Python.workspaceToCode(workspace).replace(/;;.{20}/g, ''));
2018-08-15 18:07:26 +00:00
readOnlyCodingEditor.clearSelection();
// Disable the if condition block in the toolbox if it's already used
if (/controls_if/.test(xml)) {
2018-08-15 18:07:26 +00:00
workspace.updateToolbox(document.getElementById('toolbox_no_if'));
}
2018-07-08 18:52:16 +00:00
// On Blockly code change
function onCodeChanged(event) {
// When the if condition block was created
2018-08-12 10:37:02 +00:00
if (event.type == Blockly.Events.CREATE &&
event.xml.getAttributeNode('type').nodeValue == 'controls_if') {
2018-07-08 18:52:16 +00:00
// Remember the control_if block id
controlBlockId = event.blockId;
// Get the control_if block object
var block = workspace.getBlockById(event.blockId);
// When the control_if block doesn't already have an else
if (block.elseCount_ == 0) {
// Automatically add the else statement input
block.elseCount_ = 1;
block.updateShape_();
}
// When the if condition block was removed
2018-08-12 10:37:02 +00:00
} else if (event.type == Blockly.Events.DELETE &&
event.oldXml.getAttributeNode('type').nodeValue == 'controls_if') {
2018-07-08 18:52:16 +00:00
// Remove the control_if block id
2018-08-12 10:37:02 +00:00
controlBlockId = '';
2018-07-08 18:52:16 +00:00
// Enable the if condition block
2018-08-12 10:37:02 +00:00
workspace.updateToolbox(document.getElementById('toolbox'));
2018-07-08 18:52:16 +00:00
}
// Only process change and move commands
if (event.type != Blockly.Events.CHANGE && event.type != Blockly.Events.MOVE) return;
2018-08-12 10:37:02 +00:00
2018-07-08 18:52:16 +00:00
// Generate code from the used blocks
sumorobot.setBlocklyCode(Blockly.Python.workspaceToCode(workspace));
// Show the code in the ace editor, filter out block IDs
2018-08-12 10:37:02 +00:00
readOnlyCodingEditor.setValue('\n' + sumorobot.getBlocklyCode().replace(/;;.{20}/g, ''));
2018-07-08 18:52:16 +00:00
readOnlyCodingEditor.clearSelection();
// Save the code to the local storage
var xml = Blockly.Xml.workspaceToDom(workspace);
2018-08-12 10:37:02 +00:00
localStorage.setItem('sumorobot.blockly', Blockly.Xml.domToText(xml));
2018-07-08 18:52:16 +00:00
// When control_if block is used
2018-08-12 10:37:02 +00:00
if (controlBlockId != '') {
2018-07-08 18:52:16 +00:00
// Disable the if condition block
2018-08-12 10:37:02 +00:00
workspace.updateToolbox(document.getElementById('toolbox_no_if'));
2018-07-08 18:52:16 +00:00
}
}
// Add a change listener to Blockly
workspace.addChangeListener(onCodeChanged);
// Set a click listener on the document
$(document).click(function(e) {
var target = e.target;
// When control_if block is in use
2018-08-12 10:37:02 +00:00
if (controlBlockId != '') {
2018-07-08 18:52:16 +00:00
// When the user clicks anywhere outside the mutator and not on the mutator icon
if (!$(target).is('.blocklyBubbleCanvas') && !$(target).parents().is('.blocklyBubbleCanvas')) {
if (!$(target).is('.blocklyIconGroup') && !$(target).parents().is('.blocklyIconGroup')) {
// Hide the mutator
workspace.getBlockById(controlBlockId).mutator.setVisible(false);
}
}
}
});
});