app/assets/htmls/gs-element-blockly.html in gobstones-blockly-0.31.0 vs app/assets/htmls/gs-element-blockly.html in gobstones-blockly-0.32.0

- old
+ new

@@ -79,10 +79,11 @@ <block type="OperadorNumerico"></block> <block type="OperadorDeComparacion"></block> <block type="OperadorLogico"></block> <block type="not"></block> <block type="OperadoresDeEnumeracion"></block> + <block type="AlternativaEnExpresiones"></block> </category> </category> <category name="Definiciones"> <category name="Programas"> <block type="Program"></block> @@ -4233,18 +4234,19 @@ f(newBlock); newBlock.initSvg(); newBlock.render(); }; -const createVariable = (parent, name) => { +const createVariable = (parent, name, callback = () => {}) => { const workspace = parent.workspace; Blockly.createBlockSvg(workspace, 'variables_get', b => { ATOMICALLY(() => { b.setFieldValue(name, 'VAR'); const posParent = parent.getRelativeToSurfaceXY(); const pos = b.getRelativeToSurfaceXY(); b.moveBy(posParent.x - pos.x + parent.width + 16, posParent.y - pos.y + b.height + 6); + callback(b); }); }); } const triggerRefresh = (block) => { @@ -4367,19 +4369,20 @@ const icon = "minus.png"; var removeButton = new Blockly.FieldImage( getLocalMediaUrl(this, icon), getLocalMediaSize(icon), getLocalMediaSize(icon), - "Eliminar", + "", function() { this.$init = false; this.removeInput("initlabel"); this.removeInput("init"); this.removeInput("statementsLabel"); triggerRefresh(this); }.bind(this) ); + setTimeout(() => { removeButton.setTooltip("Eliminar"); }); this.appendDummyInput("initlabel").appendField('Al inicializar:').appendField(removeButton); this.appendStatementInput('init').setCheck(["Statement"]); this.appendDummyInput("statementsLabel").appendField('Al apretar...'); this.moveInputBefore("init", "interactiveprogram"); @@ -4394,18 +4397,19 @@ const icon = "minus.png"; var removeButton = new Blockly.FieldImage( getLocalMediaUrl(this, icon), getLocalMediaSize(icon), getLocalMediaSize(icon), - "Eliminar", + "", function() { this.$timeout = undefined; this.removeInput("timeoutlabel"); this.removeInput("timeout"); triggerRefresh(this); }.bind(this) ); + setTimeout(() => { removeButton.setTooltip("Eliminar"); }); this.appendDummyInput("timeoutlabel").appendField(`Al estar inactivo ${timeout} milisegundos:`).appendField(removeButton); this.appendStatementInput('timeout').setCheck(["Statement"]); triggerRefresh(this); } @@ -4476,31 +4480,36 @@ const self = this; const input = this.inputList[0]; const plusIcon = "plus.png"; const cleanIcon = "clean.png"; - input.appendField(new Blockly.FieldImage( + const addModifier = new Blockly.FieldImage( getLocalMediaUrl(this, plusIcon), getLocalMediaSize(plusIcon), getLocalMediaSize(plusIcon), - "Agregar modificador", + "", function() { const modifiersCount = getModifierFields(self).length / 2; if (modifiersCount >= modifiers.length) return; self._addModifier(); } - )); - input.appendField(new Blockly.FieldImage( + ); + setTimeout(() => { addModifier.setTooltip("Agregar modificador"); }); + input.appendField(addModifier); + + const cleanModifiers = new Blockly.FieldImage( getLocalMediaUrl(this, cleanIcon), getLocalMediaSize(cleanIcon), getLocalMediaSize(cleanIcon), - "Limpiar modificadores", + "", function() { self._cleanModifiers(); } - )); + ); + setTimeout(() => { addModifier.setTooltip("Limpiar modificadores"); }); + input.appendField(cleanModifiers); }, customContextMenu: function(options) { const modifiersCount = getModifierFields(this).length / 2; @@ -5111,15 +5120,17 @@ const icon = "plus.png"; var addButton = new Blockly.FieldImage( getLocalMediaUrl(this, icon), getLocalMediaSize(icon), getLocalMediaSize(icon), - "Agregar elemento", + "", function() { this._addElement(); }.bind(this) ); + setTimeout(() => { addButton.setTooltip("Agregar elemento"); }); + const input = this.appendDummyInput(); input.appendField(addButton); input.name = "addButton"; const closingBracket = this.appendDummyInput(); @@ -5136,19 +5147,145 @@ const icon = "minus.png"; var removeButton = new Blockly.FieldImage( getLocalMediaUrl(this, icon), getLocalMediaSize(icon), getLocalMediaSize(icon), - "Quitar elemento", + "", function() { this._removeElement(input); }.bind(this) ); + setTimeout(() => { removeButton.setTooltip("Quitar elemento"); }); input.appendField(removeButton); } }; +Blockly.Blocks.AlternativaEnExpresiones = { + init: function () { + this.jsonInit({ + message0: "", + args0: [], + output: "*", + colour: Blockly.CUSTOM_COLORS.AlternativaEnExpresiones || Blockly.CUSTOM_COLORS.operator, + inputsInline: true + }); + this.length = 0; + + this._addOtherwise(); + this._addElement(); + }, + + mutationToDom: function() { + var container = document.createElement('mutation'); + container.setAttribute('extrabranches', this.length - 1); + return container; + }, + + domToMutation: function(xmlElement) { + var extraBranches = parseInt(xmlElement.getAttribute('extrabranches')) || 0; + for (let i = 0; i < extraBranches; i++) this._addElement(); + }, + + _addElement: function() { + this.length++; + this._removeOtherwise(); + this._removeAddButton(); + + if (this.length > 1) this._addNewline("newline" + this.length); + this.appendDummyInput().appendField('elegir').name = "label1" + this.length; + const input1 = this.appendValueInput('element' + this.length); + this.appendDummyInput().appendField('cuando').name = "label2" + this.length; + const input2 = this.appendValueInput('condition' + this.length); + + if (this.length > 1) this._addRemoveButtonFor(this.length, input2); + this._addAddButton(); + this._addOtherwise(); + triggerRefresh(this); + }, + + _removeElement: function(n) { + const isLastBranch = this.length === 2; + + const elements = ["newline", "label1", "element", "label2", "condition"]; + elements.forEach((element) => this.removeInput(element + n)); + this.length--; + + let id; + elements.forEach((element) => { + id = 1; + for (let input of this.inputList) { + if (input.name.startsWith(element)) { + input.name = element + id; + id++; + } + } + }); + + if (isLastBranch) this.removeInput("newline1"); + + triggerRefresh(this); + }, + + _addAddButton: function() { + const icon = "plus.png"; + var addButton = new Blockly.FieldImage( + getLocalMediaUrl(this, icon), + getLocalMediaSize(icon), + getLocalMediaSize(icon), + "", + function() { + this._addElement(); + }.bind(this) + ); + setTimeout(() => { addButton.setTooltip("Agregar opción"); }); + + const input = this.appendDummyInput(); + input.appendField(addButton); + input.name = "addButton"; + }, + + _removeAddButton: function() { + this.removeInput("addButton") + this.removeInput("closingBracket"); + }, + + _addOtherwise: function() { + this._addNewline("otherwiseNewline"); + + const textInput = this.appendDummyInput(); + textInput.appendField("o si no"); + textInput.name = "otherwiseText"; + + this.appendValueInput("otherwise"); + }, + + _removeOtherwise: function() { + this.removeInput("otherwiseText"); + this.removeInput("otherwise"); + this.removeInput("otherwiseNewline"); + }, + + _addNewline: function(name) { + this.appendStatementInput(name).setCheck(["NEWLINE"]); + }, + + _addRemoveButtonFor: function(n, input) { + const icon = "minus.png"; + var removeButton = new Blockly.FieldImage( + getLocalMediaUrl(this, icon), + getLocalMediaSize(icon), + getLocalMediaSize(icon), + "", + function() { + this._removeElement(n); + }.bind(this) + ); + setTimeout(() => { removeButton.setTooltip("Quitar opción"); }); + input.appendField(removeButton); + } +}; + Blockly.Blocks.ForEach = { init: function () { this.jsonInit({ type: "Statement", previousStatement: "Statement", @@ -5168,28 +5305,50 @@ "text": "en" }, ] }); + var self = this; + + const nameField = this.getField("varName"); + nameField.setValidator(function(name) { + // Strip leading and trailing whitespace. Beyond this, all names are legal. + name = name.replace(/^[\s\xa0]+|[\s\xa0]+$/g, ''); + + var oldName = this.text_; + if (oldName != name) { + // Rename any callers. + var blocks = this.sourceBlock_.workspace.getAllBlocks(false); + for (var i = 0; i < blocks.length; i++) { + if (blocks[i].$parent === self.id) { + blocks[i].setFieldValue(name, "VAR") + } + } + } + + return name; + }); + this.setColour(Blockly.CUSTOM_COLORS.ForEach || Blockly.CUSTOM_COLORS.controlStructure); this.appendValueInput('list'); this.appendStatementInput('block').setCheck(["Statement"]); this.setInputsInline(true); - var self = this; - const handIcon = "hand.png"; var createGetterButton = new Blockly.FieldImage( getLocalMediaUrl(this, handIcon), getLocalMediaSize(handIcon), getLocalMediaSize(handIcon), - "Obtener variable", + "", function() { var name = self.getFieldValue('varName'); - createVariable(self, name); + createVariable(self, name, (block) => { + block.$parent = self.id; + }); } ); + setTimeout(() => { createGetterButton.setTooltip("Obtener variable"); }); this.inputList[0].appendField(createGetterButton); } }; @@ -5351,16 +5510,17 @@ const handIcon = "hand.png"; var createGetterButton = new Blockly.FieldImage( getLocalMediaUrl(this, handIcon), getLocalMediaSize(handIcon), getLocalMediaSize(handIcon), - "Obtener variable", + "", function() { var name = self.getFieldValue('varName'); self.createVariableBlock(name); } ); + setTimeout(() => { createGetterButton.setTooltip("Obtener variable"); }); this.appendDummyInput().appendField(createGetterButton); }, customContextMenu: function(options) { @@ -5858,10 +6018,29 @@ const code = `[${elements}]`; return [code, Blockly.GobstonesLanguage.ORDER_ATOMIC]; }; +Blockly.GobstonesLanguage.AlternativaEnExpresiones = function(block) { + const elements = block + .inputList + .filter((it) => it.name.startsWith("element")) + .map((it) => { + const id = it.name.match(/element(\d+)/)[1]; + const value = Blockly.GobstonesLanguage.valueToCode(block, it.name, Blockly.GobstonesLanguage.ORDER_NONE); + const conditionValue = Blockly.GobstonesLanguage.valueToCode(block, `condition${id}`, Blockly.GobstonesLanguage.ORDER_NONE); + + return `${value} when (${conditionValue})`; + }) + .join("\n "); + + const otherwise = Blockly.GobstonesLanguage.valueToCode(block, "otherwise", Blockly.GobstonesLanguage.ORDER_NONE); + const code = `\n choose ${elements}\n ${otherwise} otherwise\n`; + + return [code, Blockly.GobstonesLanguage.ORDER_ATOMIC]; +}; + Blockly.GobstonesLanguage.ForEach = function (block) { let body = Blockly.GobstonesLanguage.statementToCode(block, 'block'); var varName = formatCallName(block.getFieldValue('varName'), false, Blockly.VARIABLE_CATEGORY_NAME); var list = Blockly.GobstonesLanguage.valueToCode(block, 'list', Blockly.GobstonesLanguage.ORDER_NONE) || ''; @@ -6719,10 +6898,15 @@ const self = this; // Bloque Blockly.Blocks[name] = { init: function () { + this.jsonInit({ + type: "Statement", + previousStatement: "Statement", + nextStatement: "Statement", + }); this.setColour(Blockly.CUSTOM_COLORS.primitiveProcedure); if (icon) { this.appendDummyInput().appendField(new Blockly.FieldImage( icon, @@ -6732,12 +6916,10 @@ )); } self._definePrimitiveHolesOrDropdown(this, parts, dropdownOptions); - this.setPreviousStatement(true); - this.setNextStatement(true); this.setInputsInline(true); this.setTooltip(definition.attributes && definition.attributes.tooltip || ""); } }; @@ -6794,9 +6976,10 @@ this.setPreviousStatement(false); this.setNextStatement(false); this.setInputsInline(true); this.setOutput('var'); + this.setTooltip(definition.attributes && definition.attributes.tooltip || ""); } }; let argsList = []; for(var i=1;i<parts.length;i++) { \ No newline at end of file