Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Effectfun #72

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
298 changes: 298 additions & 0 deletions blockly/blocks/arduino/procedures.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,301 @@ Blockly.Blocks['arduino_functions'] = {
return true;
}
};

Blockly.Blocks['controls_effect'] = {
/**
* Block for effect condition.
* @this Blockly.Block
*/
init: function() {
var nameField = new Blockly.FieldTextInput(
Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE,
Blockly.Procedures.rename);
nameField.setSpellcheck(false);
this.arguments_ = [];
this.setHelpUrl(''); //Blockly.Msg.ARD_CONTROLS_EFFECT_HELPURL);
this.setColour(Blockly.Blocks.procedures.HUE);
this.appendValueInput('EFFECTDURATION')
.setCheck(Blockly.Types.NUMBER.checkList)
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_FIRST1)
.appendField(nameField, 'NAME')
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_FIRST2);
//this.appendStatementInput('IF0')
// .setCheck(Blockly.Types.NUMBER.checkList)
// .appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_IF);
this.appendStatementInput('DO0')
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_IF); //Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_THEN);
//this.setPreviousStatement(true, 'ARD_BLOCK');
//this.setNextStatement(true, 'ARD_BLOCK');
if (Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT) {
this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);
}
this.setMutator(new Blockly.Mutator(['controls_effect_elseif',
'controls_effect_else']));
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function() {
if (!thisBlock.elseifCount_ && !thisBlock.elseCount_) {
return Blockly.Msg.ARD_CONTROLS_EFFECT_TOOLTIP_1;
} else if (!thisBlock.elseifCount_ && thisBlock.elseCount_) {
return Blockly.Msg.ARD_CONTROLS_EFFECT_TOOLTIP_2;
} else if (thisBlock.elseifCount_ && !thisBlock.elseCount_) {
return Blockly.Msg.ARD_CONTROLS_EFFECT_TOOLTIP_3;
} else if (thisBlock.elseifCount_ && thisBlock.elseCount_) {
return Blockly.Msg.ARD_CONTROLS_EFFECT_TOOLTIP_4;
}
return '';
});
this.elseifCount_ = 0;
this.elseCount_ = 0;
},
/**
* Initialization of the block has completed, clean up anything that may be
* inconsistent as a result of the XML loading.
* @this Blockly.Block
*/
validate: function () {
var name = Blockly.Procedures.findLegalName(
this.getFieldValue('NAME'), this);
this.setFieldValue(name, 'NAME');
},
/**
* Create XML to represent the number of else-if and else inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function() {
if (!this.elseifCount_ && !this.elseCount_) {
return null;
}
var container = document.createElement('mutation');
if (this.elseifCount_) {
container.setAttribute('elseif', this.elseifCount_);
}
if (this.elseCount_) {
container.setAttribute('else', 1);
}
return container;
},
/**
* Parse XML to restore the else-if and else inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function(xmlElement) {
this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10) || 0;
this.elseCount_ = parseInt(xmlElement.getAttribute('else'), 10) || 0;
for (var i = 1; i <= this.elseifCount_; i++) {
this.appendValueInput('IF' + i)
.setCheck(Blockly.Types.NUMBER.checkList)
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_ELSEIF);
this.appendStatementInput('DO' + i)
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_THEN);
}
if (this.elseCount_) {
this.appendStatementInput('ELSE')
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_ELSE);
}
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function(workspace) {
var containerBlock = workspace.newBlock('controls_effect_if');
containerBlock.initSvg();
var connection = containerBlock.nextConnection;
for (var i = 1; i <= this.elseifCount_; i++) {
var elseifBlock = workspace.newBlock('controls_effect_elseif');
elseifBlock.initSvg();
connection.connect(elseifBlock.previousConnection);
connection = elseifBlock.nextConnection;
}
if (this.elseCount_) {
var elseBlock = workspace.newBlock('controls_effect_else');
elseBlock.initSvg();
connection.connect(elseBlock.previousConnection);
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function(containerBlock) {
// Disconnect the else input blocks and remove the inputs.
if (this.elseCount_) {
this.removeInput('ELSE');
}
this.elseCount_ = 0;
// Disconnect all the elseif input blocks and remove the inputs.
for (var i = this.elseifCount_; i > 0; i--) {
this.removeInput('IF' + i);
this.removeInput('DO' + i);
}
this.elseifCount_ = 0;
// Rebuild the block's optional inputs.
var clauseBlock = containerBlock.nextConnection.targetBlock();
while (clauseBlock) {
switch (clauseBlock.type) {
case 'controls_effect_elseif':
this.elseifCount_++;
var ifInput = this.appendValueInput('IF' + this.elseifCount_)
.setCheck(Blockly.Types.NUMBER.checkList)
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_ELSEIF);
var doInput = this.appendStatementInput('DO' + this.elseifCount_);
doInput.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_THEN);
// Reconnect any child blocks.
if (clauseBlock.valueConnection_) {
ifInput.connection.connect(clauseBlock.valueConnection_);
}
if (clauseBlock.statementConnection_) {
doInput.connection.connect(clauseBlock.statementConnection_);
}
break;
case 'controls_effect_else':
this.elseCount_++;
var elseInput = this.appendStatementInput('ELSE');
elseInput.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_MSG_ELSE);
// Reconnect any child blocks.
if (clauseBlock.statementConnection_) {
elseInput.connection.connect(clauseBlock.statementConnection_);
}
break;
default:
throw 'Unknown block type.';
}
clauseBlock = clauseBlock.nextConnection &&
clauseBlock.nextConnection.targetBlock();
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function(containerBlock) {
var clauseBlock = containerBlock.nextConnection.targetBlock();
var i = 1;
while (clauseBlock) {
switch (clauseBlock.type) {
case 'controls_effect_elseif':
var inputIf = this.getInput('IF' + i);
var inputDo = this.getInput('DO' + i);
clauseBlock.valueConnection_ =
inputIf && inputIf.connection.targetConnection;
clauseBlock.statementConnection_ =
inputDo && inputDo.connection.targetConnection;
i++;
break;
case 'controls_effect_else':
var inputDo = this.getInput('ELSE');
clauseBlock.statementConnection_ =
inputDo && inputDo.connection.targetConnection;
break;
default:
throw 'Unknown block type.';
}
clauseBlock = clauseBlock.nextConnection &&
clauseBlock.nextConnection.targetBlock();
}
},
/**
* Dispose of any callers.
* @this Blockly.Block
*/
dispose: function() {
var name = this.getFieldValue('NAME');
Blockly.Procedures.disposeCallers(name, this.workspace);
// Call parent's destructor.
this.constructor.prototype.dispose.apply(this, arguments);
},
/**
* Return the signature of this procedure definition.
* @return {!Array} Tuple containing three elements:
* - the name of the defined procedure,
* - a list of all its arguments,
* - that it DOES NOT have a return value.
* @this Blockly.Block
*/
getProcedureDef: function() {
return [this.getFieldValue('NAME'), this.arguments_, false];
},
/**
* Return all variables referenced by this block.
* @return {!Array.<string>} List of variable names.
* @this Blockly.Block
*/
getVars: function() {
return this.arguments_;
},
/**
* Add custom menu options to this block's context menu.
* @param {!Array} options List of menu options to add to.
* @this Blockly.Block
*/
customContextMenu: function(options) {
// Add option to create caller.
var option = {enabled: true};
var name = this.getFieldValue('NAME');
option.text = Blockly.Msg.PROCEDURES_CREATE_DO.replace('%1', name);
var xmlMutation = goog.dom.createDom('mutation');
xmlMutation.setAttribute('name', name);

var xmlBlock = goog.dom.createDom('block', null, xmlMutation);
xmlBlock.setAttribute('type', this.callType_);
option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
options.push(option);
},
callType_: 'procedures_callnoreturn'
};

Blockly.Blocks['controls_effect_if'] = {
/**
* Mutator block for if container.
* @this Blockly.Block
*/
init: function() {
this.setColour(Blockly.Blocks.procedures.HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_IF_TITLE_IF);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.ARD_CONTROLS_EFFECT_IF_TOOLTIP);
this.contextMenu = false;
}
};

Blockly.Blocks['controls_effect_elseif'] = {
/**
* Mutator bolck for else-if condition.
* @this Blockly.Block
*/
init: function() {
this.setColour(Blockly.Blocks.procedures.HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_ELSEIF_TITLE_ELSEIF);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.ARD_CONTROLS_EFFECT_ELSEIF_TOOLTIP);
this.contextMenu = false;
}
};

Blockly.Blocks['controls_effect_else'] = {
/**
* Mutator block for else condition.
* @this Blockly.Block
*/
init: function() {
this.setColour(Blockly.Blocks.procedures.HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_CONTROLS_EFFECT_ELSE_TITLE_ELSE);
this.setPreviousStatement(true);
this.setTooltip(Blockly.Msg.ARD_CONTROLS_EFFECT_ELSE_TOOLTIP);
this.contextMenu = false;
}
};

6 changes: 6 additions & 0 deletions blockly/core/procedures.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ Blockly.Procedures.flyoutCategory = function(workspace) {
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (Blockly.Blocks['controls_effect']) {
var block = goog.dom.createDom('block');
block.setAttribute('type', 'controls_effect');
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (xmlList.length) {
// Add slightly larger gap between system blocks and user calls.
xmlList[xmlList.length - 1].setAttribute('gap', 24);
Expand Down
Loading