commit
67cc477d28
41
package-lock.json
generated
41
package-lock.json
generated
@ -1097,14 +1097,27 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@blockly/block-plus-minus": {
|
"@blockly/block-plus-minus": {
|
||||||
"version": "2.0.8",
|
"version": "2.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/@blockly/block-plus-minus/-/block-plus-minus-2.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@blockly/block-plus-minus/-/block-plus-minus-2.0.10.tgz",
|
||||||
"integrity": "sha512-LRn+Js2rZ14XyrSoEf7wTz6/ESNW2MI5TkXJ2wWFJVA+/E4lTfBwXeZpRFYRP9DZwNEv9alZETyEcBbK+FCZKw=="
|
"integrity": "sha512-YWEQd9xHAAn1aJgIuZsAdx2t9ZSjinaSEzbN1c43iU584TvaiPsGq5JcnLpoDIyGgJI90Nk+o4erWyQR+kqLyQ=="
|
||||||
},
|
},
|
||||||
"@blockly/field-slider": {
|
"@blockly/field-slider": {
|
||||||
"version": "2.0.7",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-2.1.1.tgz",
|
||||||
"integrity": "sha512-kSFeeyfJboj2zOz55hgunFzRHQZUTWmKgw695GOwOGvt4wTG5SQ2/pNnd+C41vdjaOdjaI8tlwiyWg4oJ/MPeA=="
|
"integrity": "sha512-VclXqKRs94iHl7yhFNCK+a1uyiHtPHgoAYXugr7hbZ6BZWGdI9tV1iMeiILz4pNlhy6llM+QvbJopjYA+4oCFQ=="
|
||||||
|
},
|
||||||
|
"@blockly/plugin-modal": {
|
||||||
|
"version": "1.20200427.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@blockly/plugin-modal/-/plugin-modal-1.20200427.4.tgz",
|
||||||
|
"integrity": "sha512-eA9p+W3mtcWLJQZ23D0Le/Uw3JdxFxwJqTUYtAiRlVON4qnuDXrHQLlvxEiWctNXJZGUTh57zqbvO6ZxNRQPrA=="
|
||||||
|
},
|
||||||
|
"@blockly/plugin-typed-variable-modal": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@blockly/plugin-typed-variable-modal/-/plugin-typed-variable-modal-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-+g/lQ3HrCcivBNOtgvQEvfZCPq9VeP1Zgs7J02zxAfw4f+s4aOQb+hChv7qAb5AnzEnMk0BoB5vKgQmaP6Wkuw==",
|
||||||
|
"requires": {
|
||||||
|
"@blockly/plugin-modal": "^1.20200427.4"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"@cnakazawa/watch": {
|
"@cnakazawa/watch": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
@ -3065,9 +3078,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"blockly": {
|
"blockly": {
|
||||||
"version": "3.20200625.2",
|
"version": "3.20200924.0",
|
||||||
"resolved": "https://registry.npmjs.org/blockly/-/blockly-3.20200625.2.tgz",
|
"resolved": "https://registry.npmjs.org/blockly/-/blockly-3.20200924.0.tgz",
|
||||||
"integrity": "sha512-+0aUynP4kAFjg+m9uSyctWB+KwT3/BDmqy4Fm7vwWq7cuMtgIsqqA8VGb6INVpFx9WZUXSZ5enFAco6CM85bpA==",
|
"integrity": "sha512-mOZiXi908oNFAcVb8Q5LKJNRZ5jtBJtgNilddqTYMAXEdqSY/BhcnU2rgytWARDnu2iSQlI374kEafCNuUEWKQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"jsdom": "^15.2.1"
|
"jsdom": "^15.2.1"
|
||||||
},
|
},
|
||||||
@ -5947,6 +5960,11 @@
|
|||||||
"schema-utils": "^2.5.0"
|
"schema-utils": "^2.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-saver": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw=="
|
||||||
|
},
|
||||||
"file-uri-to-path": {
|
"file-uri-to-path": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
@ -8702,6 +8720,11 @@
|
|||||||
"minimist": "^1.2.5"
|
"minimist": "^1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.29.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
|
||||||
|
"integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA=="
|
||||||
|
},
|
||||||
"move-concurrently": {
|
"move-concurrently": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blockly/block-plus-minus": "^2.0.8",
|
"@blockly/block-plus-minus": "^2.0.10",
|
||||||
"@blockly/field-slider": "^2.0.7",
|
"@blockly/field-slider": "^2.1.1",
|
||||||
|
"@blockly/plugin-typed-variable-modal": "^3.1.1",
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.14.0",
|
"@fortawesome/free-solid-svg-icons": "^5.14.0",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.11",
|
"@fortawesome/react-fontawesome": "^0.1.11",
|
||||||
@ -12,7 +13,7 @@
|
|||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.5.0",
|
"@testing-library/react": "^9.5.0",
|
||||||
"@testing-library/user-event": "^7.2.1",
|
"@testing-library/user-event": "^7.2.1",
|
||||||
"blockly": "^3.20200625.2",
|
"blockly": "^3.20200924.0",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"moment": "^2.28.0",
|
"moment": "^2.28.0",
|
||||||
"prismjs": "^1.20.0",
|
"prismjs": "^1.20.0",
|
||||||
|
@ -34,10 +34,12 @@ import { Card } from '@material-ui/core';
|
|||||||
Blockly.setLocale(locale);
|
Blockly.setLocale(locale);
|
||||||
|
|
||||||
class BlocklyComponent extends React.Component {
|
class BlocklyComponent extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.blocklyDiv = React.createRef();
|
this.blocklyDiv = React.createRef();
|
||||||
this.toolbox = React.createRef();
|
this.toolbox = React.createRef();
|
||||||
|
this.state = {workspace: undefined};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -49,6 +51,7 @@ class BlocklyComponent extends React.Component {
|
|||||||
...rest
|
...rest
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
this.setState({workspace: this.primaryWorkspace})
|
||||||
|
|
||||||
if (initialXml) {
|
if (initialXml) {
|
||||||
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(initialXml), this.primaryWorkspace);
|
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(initialXml), this.primaryWorkspace);
|
||||||
@ -64,11 +67,9 @@ class BlocklyComponent extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<Card ref={this.blocklyDiv} id="blocklyDiv" style={this.props.style ? this.props.style : {}}/>
|
<Card ref={this.blocklyDiv} id="blocklyDiv" style={this.props.style ? this.props.style : {}}/>
|
||||||
<Toolbox toolbox={this.toolbox} />
|
<Toolbox toolbox={this.toolbox} workspace={this.state.workspace} />
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
61
src/components/Blockly/blocks/audio.js
Normal file
61
src/components/Blockly/blocks/audio.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import Blockly from 'blockly/core';
|
||||||
|
import { selectedBoard } from '../helpers/board'
|
||||||
|
import * as Types from '../helpers/types'
|
||||||
|
import { getColour } from '../helpers/colour';
|
||||||
|
|
||||||
|
|
||||||
|
Blockly.Blocks['io_tone'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.ARD_SETTONE)
|
||||||
|
.appendField(new Blockly.FieldDropdown(
|
||||||
|
selectedBoard().digitalPins), "TONEPIN");
|
||||||
|
this.appendValueInput("FREQUENCY")
|
||||||
|
.setCheck(Types.getCompatibleTypes('int'))
|
||||||
|
.appendField(Blockly.Msg.ARD_TONEFREQ);
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField("Hz");
|
||||||
|
this.setInputsInline(true);
|
||||||
|
this.setPreviousStatement(true);
|
||||||
|
this.setNextStatement(true);
|
||||||
|
this.setColour(getColour().audio);
|
||||||
|
this.setTooltip(Blockly.Msg.ARD_TONE_TIP);
|
||||||
|
this.setHelpUrl('https://www.arduino.cc/en/Reference/tone');
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Called whenever anything on the workspace changes.
|
||||||
|
* It checks frequency values and sets a warning if out of range.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
onchange: function (event) {
|
||||||
|
if (!this.workspace || event.type === Blockly.Events.MOVE ||
|
||||||
|
event.type === Blockly.Events.UI) {
|
||||||
|
return; // Block deleted or irrelevant event
|
||||||
|
}
|
||||||
|
var freq = Blockly.Arduino.valueToCode(
|
||||||
|
this, "FREQUENCY", Blockly.Arduino.ORDER_ATOMIC)
|
||||||
|
if (freq < 31 || freq > 65535) {
|
||||||
|
this.setWarningText(Blockly.Msg.ARD_TONE_WARNING, 'io_tone');
|
||||||
|
} else {
|
||||||
|
this.setWarningText(null, 'io_tone');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['io_notone'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.ARD_NOTONE)
|
||||||
|
.appendField(new Blockly.FieldDropdown(
|
||||||
|
selectedBoard().digitalPins), "TONEPIN");
|
||||||
|
this.setPreviousStatement(true);
|
||||||
|
this.setNextStatement(true);
|
||||||
|
this.setColour(getColour().audio);
|
||||||
|
this.setTooltip(Blockly.Msg.ARD_NOTONE_TIP);
|
||||||
|
this.setHelpUrl('https://www.arduino.cc/en/Reference/noTone');
|
||||||
|
},
|
||||||
|
/** @return {!string} The type of input value for the block, an integer. */
|
||||||
|
getBlockType: function () {
|
||||||
|
return Blockly.Types.NUMBER;
|
||||||
|
}
|
||||||
|
};
|
@ -8,11 +8,14 @@ import './sensebox-web';
|
|||||||
import './sensebox-display';
|
import './sensebox-display';
|
||||||
import './sensebox-lora';
|
import './sensebox-lora';
|
||||||
import './sensebox-led';
|
import './sensebox-led';
|
||||||
|
import './sensebox-sd';
|
||||||
|
import './text';
|
||||||
import './io';
|
import './io';
|
||||||
|
import './audio';
|
||||||
import './math';
|
import './math';
|
||||||
import './map';
|
import './map';
|
||||||
import './procedures';
|
import './procedures';
|
||||||
import './time';
|
import './time';
|
||||||
|
import './variables';
|
||||||
|
|
||||||
import '../helpers/types'
|
import '../helpers/types'
|
@ -56,7 +56,7 @@ Blockly.Blocks['io_digitalread'] = {
|
|||||||
.appendField(Blockly.Msg.ARD_DIGITALREAD)
|
.appendField(Blockly.Msg.ARD_DIGITALREAD)
|
||||||
.appendField(new Blockly.FieldDropdown(
|
.appendField(new Blockly.FieldDropdown(
|
||||||
selectedBoard().digitalPins), 'PIN');
|
selectedBoard().digitalPins), 'PIN');
|
||||||
this.setOutput(true, Types.BOOLEAN);
|
this.setOutput(true, 'boolean');
|
||||||
this.setTooltip(Blockly.Msg.ARD_DIGITALREAD_TIP);
|
this.setTooltip(Blockly.Msg.ARD_DIGITALREAD_TIP);
|
||||||
},
|
},
|
||||||
/** @return {!string} The type of return value for the block, an integer. */
|
/** @return {!string} The type of return value for the block, an integer. */
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import Blockly from 'blockly/core';
|
import Blockly from 'blockly/core';
|
||||||
|
import { getColour } from '../helpers/colour';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
|
Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
|
||||||
@ -232,4 +231,169 @@ Blockly.defineBlocksWithJsonArray([ // Mutator blocks. Do not extract.
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
Blockly.Blocks['switch_case'] = {
|
||||||
|
init: function () {
|
||||||
|
this.setColour(getColour().logic);
|
||||||
|
this.setPreviousStatement(true);
|
||||||
|
this.setNextStatement(true);
|
||||||
|
this.appendValueInput('CONDITION')
|
||||||
|
.appendField(Blockly.Msg.cases_switch);
|
||||||
|
this.appendValueInput('CASECONDITION0')
|
||||||
|
.appendField(Blockly.Msg.cases_condition);
|
||||||
|
this.appendStatementInput('CASE0')
|
||||||
|
.appendField(Blockly.Msg.cases_do);
|
||||||
|
this.setMutator(new Blockly.Mutator(['case_incaseof', 'case_default']));
|
||||||
|
this.setTooltip('Does something if the condition is true. If there isn\'t a matching case the default function will be executed.');
|
||||||
|
this.caseCount_ = 0;
|
||||||
|
this.defaultCount_ = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
mutationToDom: function () {
|
||||||
|
if (!this.caseCount_ && !this.defaultCount_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var container = document.createElement('mutation');
|
||||||
|
if (this.caseCount_) {
|
||||||
|
container.setAttribute('case', this.caseCount_);
|
||||||
|
}
|
||||||
|
if (this.defaultCount_) {
|
||||||
|
container.setAttribute('default', 1);
|
||||||
|
}
|
||||||
|
return container;
|
||||||
|
},
|
||||||
|
|
||||||
|
domToMutation: function (xmlElement) {
|
||||||
|
this.caseCount_ = parseInt(xmlElement.getAttribute('case'), 10);
|
||||||
|
this.defaultCount_ = parseInt(xmlElement.getAttribute('default'), 10);
|
||||||
|
for (var x = 0; x <= this.caseCount_; x++) {
|
||||||
|
this.appendValueInput('CASECONDITION' + x)
|
||||||
|
.appendField(Blockly.Msg.cases_condition);
|
||||||
|
this.appendStatementInput('CASE' + x)
|
||||||
|
.appendField(Blockly.Msg.cases_do);
|
||||||
|
}
|
||||||
|
if (this.defaultCount_) {
|
||||||
|
this.appendStatementInput('ONDEFAULT')
|
||||||
|
.appendField('default');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
decompose: function (workspace) {
|
||||||
|
var containerBlock = workspace.newBlock('control_case');
|
||||||
|
containerBlock.initSvg();
|
||||||
|
var connection = containerBlock.getInput('STACK').connection;
|
||||||
|
for (var x = 1; x <= this.caseCount_; x++) {
|
||||||
|
var caseBlock = workspace.newBlock('case_incaseof');
|
||||||
|
caseBlock.initSvg();
|
||||||
|
connection.connect(caseBlock.previousConnection);
|
||||||
|
connection = caseBlock.nextConnection;
|
||||||
|
}
|
||||||
|
if (this.defaultCount_) {
|
||||||
|
var defaultBlock = Blockly.Block.obtain(workspace, 'case_default');
|
||||||
|
defaultBlock.initSvg();
|
||||||
|
connection.connect(defaultBlock.previousConnection);
|
||||||
|
}
|
||||||
|
return containerBlock;
|
||||||
|
},
|
||||||
|
|
||||||
|
compose: function (containerBlock) {
|
||||||
|
//Disconnect all input blocks and remove all inputs.
|
||||||
|
if (this.defaultCount_) {
|
||||||
|
this.removeInput('ONDEFAULT');
|
||||||
|
}
|
||||||
|
this.defaultCount_ = 0;
|
||||||
|
for (var x = this.caseCount_; x > 0; x--) {
|
||||||
|
this.removeInput('CASECONDITION' + x);
|
||||||
|
this.removeInput('CASE' + x);
|
||||||
|
}
|
||||||
|
this.caseCount_ = 0;
|
||||||
|
var caseBlock = containerBlock.getInputTargetBlock('STACK');
|
||||||
|
while (caseBlock) {
|
||||||
|
switch (caseBlock.type) {
|
||||||
|
case 'case_incaseof':
|
||||||
|
this.caseCount_++;
|
||||||
|
var caseconditionInput = this.appendValueInput('CASECONDITION' + this.caseCount_)
|
||||||
|
.appendField(Blockly.Msg.cases_condition);
|
||||||
|
var caseInput = this.appendStatementInput('CASE' + this.caseCount_)
|
||||||
|
.appendField(Blockly.Msg.cases_do);
|
||||||
|
if (caseBlock.valueConnection_) {
|
||||||
|
caseconditionInput.connection.connect(caseBlock.valueConnection_);
|
||||||
|
}
|
||||||
|
if (caseBlock.statementConnection_) {
|
||||||
|
caseInput.connection.connect(caseBlock.statementConnection_);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'case_default':
|
||||||
|
this.defaultCount_++;
|
||||||
|
var defaultInput = this.appendStatementInput('ONDEFAULT')
|
||||||
|
.appendField('default');
|
||||||
|
if (caseBlock.statementConnection_) {
|
||||||
|
defaultInput.connection.connect(caseBlock.statementConnection_);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unknown block type.');
|
||||||
|
}
|
||||||
|
caseBlock = caseBlock.nextConnection &&
|
||||||
|
caseBlock.nextConnection.targetBlock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
saveConnections: function (containerBlock) {
|
||||||
|
var caseBlock = containerBlock.getInputTargetBlock('STACK');
|
||||||
|
var x = 1;
|
||||||
|
while (caseBlock) {
|
||||||
|
switch (caseBlock.type) {
|
||||||
|
case 'case_incaseof':
|
||||||
|
var caseconditionInput = this.getInput('CASECONDITION' + x);
|
||||||
|
var caseInput = this.getInput('CASE' + x);
|
||||||
|
caseBlock.valueConnection_ = caseconditionInput && caseconditionInput.connection.targetConnection;
|
||||||
|
caseBlock.statementConnection_ = caseInput && caseInput.connection.targetConnection;
|
||||||
|
x++;
|
||||||
|
break;
|
||||||
|
case 'case_default':
|
||||||
|
var defaultInput = this.getInput('ONDEFAULT');
|
||||||
|
caseBlock.satementConnection_ = defaultInput && defaultInput.connection.targetConnection;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unknown block type');
|
||||||
|
}
|
||||||
|
caseBlock = caseBlock.nextConnection &&
|
||||||
|
caseBlock.nextConnection.targetBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['control_case'] = {
|
||||||
|
init: function () {
|
||||||
|
this.setColour(getColour().logic);
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.cases_switch);
|
||||||
|
this.appendStatementInput('STACK');
|
||||||
|
this.setTooltip('--Placeholder--');
|
||||||
|
this.contextMenu = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['case_incaseof'] = {
|
||||||
|
init: function () {
|
||||||
|
this.setColour(getColour().logic);
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.cases_add);
|
||||||
|
this.setPreviousStatement(true);
|
||||||
|
this.setNextStatement(true);
|
||||||
|
this.setTooltip('--Placeholder--');
|
||||||
|
this.contextMenu = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['case_default'] = {
|
||||||
|
init: function () {
|
||||||
|
this.setColour(getColour().logic);
|
||||||
|
this.appendValueInput('default')
|
||||||
|
.appendField('default');
|
||||||
|
this.setPreviousStatement(true);
|
||||||
|
this.setNextStatement(false);
|
||||||
|
this.setTooltip('This function will run if there aren\'t any matching cases.');
|
||||||
|
this.contextMenu = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -0,0 +1,528 @@
|
|||||||
|
import * as Blockly from 'blockly/core';
|
||||||
|
import { getColour } from '../helpers/colour';
|
||||||
|
import * as Types from '../helpers/types'
|
||||||
|
|
||||||
|
Blockly.Blocks['math_number'] = {
|
||||||
|
/**
|
||||||
|
* Block for numeric value.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.setHelpUrl(Blockly.Msg.MATH_NUMBER_HELPURL);
|
||||||
|
this.setColour(getColour().math);
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(
|
||||||
|
new Blockly.FieldTextInput(
|
||||||
|
'0', Blockly.FieldTextInput.numberValidator),
|
||||||
|
'NUM');
|
||||||
|
this.setOutput(true, Types.NUMBER.typeName);
|
||||||
|
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||||
|
var thisBlock = this;
|
||||||
|
// Number block is trivial. Use tooltip of parent block if it exists.
|
||||||
|
this.setTooltip(function () {
|
||||||
|
var parent = thisBlock.getParent();
|
||||||
|
return (parent && parent.getInputsInline() && parent.tooltip) ||
|
||||||
|
Blockly.Msg.MATH_NUMBER_TOOLTIP;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_arithmetic'] = {
|
||||||
|
/**
|
||||||
|
* Block for basic arithmetic operator.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": "%1 %2 %3",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "A",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "OP",
|
||||||
|
"options":
|
||||||
|
[[Blockly.Msg.MATH_ADDITION_SYMBOL, 'ADD'],
|
||||||
|
[Blockly.Msg.MATH_SUBTRACTION_SYMBOL, 'MINUS'],
|
||||||
|
[Blockly.Msg.MATH_MULTIPLICATION_SYMBOL, 'MULTIPLY'],
|
||||||
|
[Blockly.Msg.MATH_DIVISION_SYMBOL, 'DIVIDE'],
|
||||||
|
[Blockly.Msg.MATH_POWER_SYMBOL, 'POWER']]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "B",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": true,
|
||||||
|
"output": Types.NUMBER.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_ARITHMETIC_HELPURL
|
||||||
|
});
|
||||||
|
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||||
|
var thisBlock = this;
|
||||||
|
this.setTooltip(function () {
|
||||||
|
var mode = thisBlock.getFieldValue('OP');
|
||||||
|
var TOOLTIPS = {
|
||||||
|
'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
|
||||||
|
'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
|
||||||
|
'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
|
||||||
|
'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
|
||||||
|
'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
|
||||||
|
};
|
||||||
|
return TOOLTIPS[mode];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//TODO: a getBlockType based on the two input types following C++ rules
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_single'] = {
|
||||||
|
/**
|
||||||
|
* Block for advanced math operators with single operand.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": "%1 %2",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "OP",
|
||||||
|
"options": [
|
||||||
|
[Blockly.Msg.MATH_SINGLE_OP_ROOT, 'ROOT'],
|
||||||
|
[Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE, 'ABS'],
|
||||||
|
['-', 'NEG'],
|
||||||
|
['ln', 'LN'],
|
||||||
|
['log10', 'LOG10'],
|
||||||
|
['e^', 'EXP'],
|
||||||
|
['10^', 'POW10']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "NUM",
|
||||||
|
"check": Types.getCompatibleTypes('float')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": Types.DECIMAL.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_SINGLE_HELPURL
|
||||||
|
});
|
||||||
|
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||||
|
var thisBlock = this;
|
||||||
|
this.setTooltip(function () {
|
||||||
|
var mode = thisBlock.getFieldValue('OP');
|
||||||
|
var TOOLTIPS = {
|
||||||
|
'ROOT': Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT,
|
||||||
|
'ABS': Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS,
|
||||||
|
'NEG': Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG,
|
||||||
|
'LN': Blockly.Msg.MATH_SINGLE_TOOLTIP_LN,
|
||||||
|
'LOG10': Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10,
|
||||||
|
'EXP': Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP,
|
||||||
|
'POW10': Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10
|
||||||
|
};
|
||||||
|
return TOOLTIPS[mode];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_trig'] = {
|
||||||
|
/**
|
||||||
|
* Block for trigonometry operators.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": "%1 %2",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "OP",
|
||||||
|
"options": [
|
||||||
|
[Blockly.Msg.MATH_TRIG_SIN, 'SIN'],
|
||||||
|
[Blockly.Msg.MATH_TRIG_COS, 'COS'],
|
||||||
|
[Blockly.Msg.MATH_TRIG_TAN, 'TAN'],
|
||||||
|
[Blockly.Msg.MATH_TRIG_ASIN, 'ASIN'],
|
||||||
|
[Blockly.Msg.MATH_TRIG_ACOS, 'ACOS'],
|
||||||
|
[Blockly.Msg.MATH_TRIG_ATAN, 'ATAN']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "NUM",
|
||||||
|
"check": Types.getCompatibleTypes('float')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": Types.DECIMAL.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_TRIG_HELPURL
|
||||||
|
});
|
||||||
|
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||||
|
var thisBlock = this;
|
||||||
|
this.setTooltip(function () {
|
||||||
|
var mode = thisBlock.getFieldValue('OP');
|
||||||
|
var TOOLTIPS = {
|
||||||
|
'SIN': Blockly.Msg.MATH_TRIG_TOOLTIP_SIN,
|
||||||
|
'COS': Blockly.Msg.MATH_TRIG_TOOLTIP_COS,
|
||||||
|
'TAN': Blockly.Msg.MATH_TRIG_TOOLTIP_TAN,
|
||||||
|
'ASIN': Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN,
|
||||||
|
'ACOS': Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS,
|
||||||
|
'ATAN': Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN
|
||||||
|
};
|
||||||
|
return TOOLTIPS[mode];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_constant'] = {
|
||||||
|
/**
|
||||||
|
* Block for constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": "%1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "CONSTANT",
|
||||||
|
"options": [
|
||||||
|
['\u03c0', 'PI'],
|
||||||
|
['e', 'E'],
|
||||||
|
['\u03c6', 'GOLDEN_RATIO'],
|
||||||
|
['sqrt(2)', 'SQRT2'],
|
||||||
|
['sqrt(\u00bd)', 'SQRT1_2'],
|
||||||
|
['\u221e', 'INFINITY']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": Types.DECIMAL.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"tooltip": Blockly.Msg.MATH_CONSTANT_TOOLTIP,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_CONSTANT_HELPURL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_number_property'] = {
|
||||||
|
/**
|
||||||
|
* Block for checking if a number is even, odd, prime, whole, positive,
|
||||||
|
* negative or if it is divisible by certain number.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
var PROPERTIES =
|
||||||
|
[[Blockly.Msg.MATH_IS_EVEN, 'EVEN'],
|
||||||
|
[Blockly.Msg.MATH_IS_ODD, 'ODD'],
|
||||||
|
[Blockly.Msg.MATH_IS_PRIME, 'PRIME'],
|
||||||
|
[Blockly.Msg.MATH_IS_WHOLE, 'WHOLE'],
|
||||||
|
[Blockly.Msg.MATH_IS_POSITIVE, 'POSITIVE'],
|
||||||
|
[Blockly.Msg.MATH_IS_NEGATIVE, 'NEGATIVE'],
|
||||||
|
[Blockly.Msg.MATH_IS_DIVISIBLE_BY, 'DIVISIBLE_BY']];
|
||||||
|
this.setColour(getColour().math);
|
||||||
|
this.appendValueInput('NUMBER_TO_CHECK')
|
||||||
|
.setCheck(Types.getCompatibleTypes('int'));
|
||||||
|
var dropdown = new Blockly.FieldDropdown(PROPERTIES, function (option) {
|
||||||
|
var divisorInput = (option === 'DIVISIBLE_BY');
|
||||||
|
this.sourceBlock_.updateShape_(divisorInput);
|
||||||
|
});
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(dropdown, 'PROPERTY');
|
||||||
|
this.setInputsInline(true);
|
||||||
|
this.setOutput(true, Types.BOOLEAN.typeName);
|
||||||
|
this.setTooltip(Blockly.Msg.MATH_IS_TOOLTIP);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Create XML to represent whether the 'divisorInput' should be present.
|
||||||
|
* @return {Element} XML storage element.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
mutationToDom: function () {
|
||||||
|
var container = document.createElement('mutation');
|
||||||
|
var divisorInput = (this.getFieldValue('PROPERTY') === 'DIVISIBLE_BY');
|
||||||
|
container.setAttribute('divisor_input', divisorInput);
|
||||||
|
return container;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Parse XML to restore the 'divisorInput'.
|
||||||
|
* @param {!Element} xmlElement XML storage element.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
domToMutation: function (xmlElement) {
|
||||||
|
var divisorInput = (xmlElement.getAttribute('divisor_input') === 'true');
|
||||||
|
this.updateShape_(divisorInput);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Modify this block to have (or not have) an input for 'is divisible by'.
|
||||||
|
* @param {boolean} divisorInput True if this block has a divisor input.
|
||||||
|
* @private
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
updateShape_: function (divisorInput) {
|
||||||
|
// Add or remove a Value Input.
|
||||||
|
var inputExists = this.getInput('DIVISOR');
|
||||||
|
if (divisorInput) {
|
||||||
|
if (!inputExists) {
|
||||||
|
this.appendValueInput('DIVISOR')
|
||||||
|
.setCheck(Types.getCompatibleTypes('int'));
|
||||||
|
}
|
||||||
|
} else if (inputExists) {
|
||||||
|
this.removeInput('DIVISOR');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_change'] = {
|
||||||
|
/**
|
||||||
|
* Block for adding to a variable in place.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": Blockly.Msg.MATH_CHANGE_TITLE,
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "field_variable",
|
||||||
|
"name": "VAR",
|
||||||
|
"variable": Blockly.Msg.MATH_CHANGE_TITLE_ITEM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "DELTA",
|
||||||
|
"check": Types.getCompatibleTypes('int'),
|
||||||
|
"align": "RIGHT"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_CHANGE_HELPURL
|
||||||
|
});
|
||||||
|
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||||
|
var thisBlock = this;
|
||||||
|
this.setTooltip(function () {
|
||||||
|
return Blockly.Msg.MATH_CHANGE_TOOLTIP.replace('%1',
|
||||||
|
thisBlock.getFieldValue('VAR'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_round'] = {
|
||||||
|
/**
|
||||||
|
* Block for rounding functions.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": "%1 %2",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "OP",
|
||||||
|
"options": [
|
||||||
|
[Blockly.Msg.MATH_ROUND_OPERATOR_ROUND, 'ROUND'],
|
||||||
|
[Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP, 'ROUNDUP'],
|
||||||
|
[Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN, 'ROUNDDOWN']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "NUM",
|
||||||
|
"check": Types.getCompatibleTypes('float')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": Types.DECIMAL.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"tooltip": Blockly.Msg.MATH_ROUND_TOOLTIP,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_ROUND_HELPURL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_on_list'] = {
|
||||||
|
/**
|
||||||
|
* Block for evaluating a list of numbers to return sum, average, min, max,
|
||||||
|
* etc. Some functions also work on text (min, max, mode, median).
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
var OPERATORS =
|
||||||
|
[[Blockly.Msg.MATH_ONLIST_OPERATOR_SUM, 'SUM'],
|
||||||
|
[Blockly.Msg.MATH_ONLIST_OPERATOR_MIN, 'MIN'],
|
||||||
|
[Blockly.Msg.MATH_ONLIST_OPERATOR_MAX, 'MAX'],
|
||||||
|
[Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE, 'AVERAGE'],
|
||||||
|
[Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN, 'MEDIAN'],
|
||||||
|
[Blockly.Msg.MATH_ONLIST_OPERATOR_MODE, 'MODE'],
|
||||||
|
[Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV, 'STD_DEV'],
|
||||||
|
[Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM, 'RANDOM']];
|
||||||
|
// Assign 'this' to a variable for use in the closures below.
|
||||||
|
var thisBlock = this;
|
||||||
|
this.setHelpUrl(Blockly.Msg.MATH_ONLIST_HELPURL);
|
||||||
|
this.setColour(getColour().math);
|
||||||
|
this.setOutput(true, Types.NUMBER.typeName);
|
||||||
|
var dropdown = new Blockly.FieldDropdown(OPERATORS, function (newOp) {
|
||||||
|
thisBlock.updateType_(newOp);
|
||||||
|
});
|
||||||
|
this.appendValueInput('LIST')
|
||||||
|
.setCheck(Types.getCompatibleTypes('array'))
|
||||||
|
.appendField(dropdown, 'OP');
|
||||||
|
this.setTooltip(function () {
|
||||||
|
var mode = thisBlock.getFieldValue('OP');
|
||||||
|
var TOOLTIPS = {
|
||||||
|
'SUM': Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM,
|
||||||
|
'MIN': Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN,
|
||||||
|
'MAX': Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX,
|
||||||
|
'AVERAGE': Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE,
|
||||||
|
'MEDIAN': Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN,
|
||||||
|
'MODE': Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE,
|
||||||
|
'STD_DEV': Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV,
|
||||||
|
'RANDOM': Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM
|
||||||
|
};
|
||||||
|
return TOOLTIPS[mode];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Modify this block to have the correct output type.
|
||||||
|
* @param {string} newOp Either 'MODE' or some op than returns a number.
|
||||||
|
* @private
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
updateType_: function (newOp) {
|
||||||
|
if (newOp === 'MODE') {
|
||||||
|
this.outputConnection.setCheck(Types.getCompatibleTypes('array'));
|
||||||
|
} else {
|
||||||
|
this.outputConnection.setCheck(Types.getCompatibleTypes('int'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Create XML to represent the output type.
|
||||||
|
* @return {Element} XML storage element.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
mutationToDom: function () {
|
||||||
|
var container = document.createElement('mutation');
|
||||||
|
container.setAttribute('op', this.getFieldValue('OP'));
|
||||||
|
return container;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Parse XML to restore the output type.
|
||||||
|
* @param {!Element} xmlElement XML storage element.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
domToMutation: function (xmlElement) {
|
||||||
|
this.updateType_(xmlElement.getAttribute('op'));
|
||||||
|
}
|
||||||
|
//TODO: a getBlockType once the list code is finished.
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_modulo'] = {
|
||||||
|
/**
|
||||||
|
* Block for remainder of a division.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": Blockly.Msg.MATH_MODULO_TITLE,
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "DIVIDEND",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "DIVISOR",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": true,
|
||||||
|
"output": Types.NUMBER.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"tooltip": Blockly.Msg.MATH_MODULO_TOOLTIP,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_MODULO_HELPURL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_constrain'] = {
|
||||||
|
/**
|
||||||
|
* Block for constraining a number between two limits.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": Blockly.Msg.MATH_CONSTRAIN_TITLE,
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "VALUE",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "LOW",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "HIGH",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": true,
|
||||||
|
"output": Types.NUMBER.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"tooltip": Blockly.Msg.MATH_CONSTRAIN_TOOLTIP,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_CONSTRAIN_HELPURL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//TODO: a getBlockType of the same type as the inputs.
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_random_int'] = {
|
||||||
|
/**
|
||||||
|
* Block for random integer between [X] and [Y].
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": Blockly.Msg.MATH_RANDOM_INT_TITLE,
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "FROM",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "TO",
|
||||||
|
"check": Types.getCompatibleTypes('int')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": true,
|
||||||
|
"output": Types.NUMBER.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"tooltip": Blockly.Msg.MATH_RANDOM_INT_TOOLTIP,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_RANDOM_INT_HELPURL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['math_random_float'] = {
|
||||||
|
/**
|
||||||
|
* Block for random fraction between 0 and 1.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit({
|
||||||
|
"message0": Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM,
|
||||||
|
"output": Types.DECIMAL.typeName,
|
||||||
|
"colour": getColour().math,
|
||||||
|
"tooltip": Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP,
|
||||||
|
"helpUrl": Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -50,6 +50,8 @@ Blockly.Blocks['sensebox_display_printDisplay'] = {
|
|||||||
.setCheck(null);
|
.setCheck(null);
|
||||||
this.setPreviousStatement(true, null);
|
this.setPreviousStatement(true, null);
|
||||||
this.setNextStatement(true, null);
|
this.setNextStatement(true, null);
|
||||||
|
let variableName = this.getField('COLOR');
|
||||||
|
console.log(variableName.getValue());
|
||||||
this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip);
|
this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip);
|
||||||
this.setHelpUrl('https://sensebox.de/books');
|
this.setHelpUrl('https://sensebox.de/books');
|
||||||
},
|
},
|
||||||
|
80
src/components/Blockly/blocks/sensebox-sd.js
Normal file
80
src/components/Blockly/blocks/sensebox-sd.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import * as Blockly from 'blockly/core';
|
||||||
|
import { getColour } from '../helpers/colour';
|
||||||
|
|
||||||
|
|
||||||
|
Blockly.Blocks['sensebox_sd_open_file'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.senseBox_sd_open_file)
|
||||||
|
.setAlign(Blockly.ALIGN_LEFT)
|
||||||
|
.appendField(
|
||||||
|
new Blockly.FieldTextInput('Data.txt'),
|
||||||
|
'Filename');
|
||||||
|
this.appendStatementInput('SD')
|
||||||
|
.setCheck(null);
|
||||||
|
this.setPreviousStatement(true, null);
|
||||||
|
this.setNextStatement(true, null);
|
||||||
|
this.setColour(getColour().sensebox);
|
||||||
|
this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip);
|
||||||
|
this.setHelpUrl('https://sensebox.de/books');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['sensebox_sd_create_file'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.senseBox_sd_create_file)
|
||||||
|
.setAlign(Blockly.ALIGN_LEFT)
|
||||||
|
.appendField(Blockly.Msg.senseBox_output_filename)
|
||||||
|
.appendField(
|
||||||
|
new Blockly.FieldTextInput('Data.txt'),
|
||||||
|
'Filename');
|
||||||
|
this.setPreviousStatement(true, null);
|
||||||
|
this.setNextStatement(true, null);
|
||||||
|
this.setColour(getColour().sensebox);
|
||||||
|
this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip);
|
||||||
|
this.setHelpUrl('https://sensebox.de/books');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['sensebox_sd_write_file'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.senseBox_sd_write_file)
|
||||||
|
.setAlign(Blockly.ALIGN_LEFT);
|
||||||
|
this.appendValueInput('DATA')
|
||||||
|
.setCheck(null);
|
||||||
|
this.appendDummyInput('CheckboxText')
|
||||||
|
.appendField(Blockly.Msg.senseBox_output_linebreak)
|
||||||
|
.appendField(new Blockly.FieldCheckbox('TRUE'), 'linebreak');
|
||||||
|
this.setPreviousStatement(true, null);
|
||||||
|
this.setNextStatement(true, null);
|
||||||
|
this.setColour(getColour().sensebox);
|
||||||
|
this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip);
|
||||||
|
this.setHelpUrl('https://sensebox.de/books');
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Called whenever anything on the workspace changes.
|
||||||
|
* Add warning if block is not nested inside a the correct loop.
|
||||||
|
* @param {!Blockly.Events.Abstract} e Change event.
|
||||||
|
* @this Blockly.Block
|
||||||
|
*/
|
||||||
|
onchange: function (e) {
|
||||||
|
var legal = false;
|
||||||
|
// Is the block nested in a loop?
|
||||||
|
var block = this;
|
||||||
|
do {
|
||||||
|
if (this.LOOP_TYPES.indexOf(block.type) !== -1) {
|
||||||
|
legal = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block = block.getSurroundParent();
|
||||||
|
} while (block);
|
||||||
|
if (legal) {
|
||||||
|
this.setWarningText(null);
|
||||||
|
} else {
|
||||||
|
this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
LOOP_TYPES: ['sensebox_sd_open_file'],
|
||||||
|
};
|
@ -16,14 +16,11 @@ Blockly.Blocks['sensebox_sensor_temp_hum'] = {
|
|||||||
.setAlign(Blockly.ALIGN_RIGHT)
|
.setAlign(Blockly.ALIGN_RIGHT)
|
||||||
.appendField(Blockly.Msg.senseBox_value)
|
.appendField(Blockly.Msg.senseBox_value)
|
||||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_hum, "Humidity"]]), "NAME");
|
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_hum, "Humidity"]]), "NAME");
|
||||||
this.setOutput(true, Types.NUMBER.typeId);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_temp_hum_tip);
|
this.setTooltip(Blockly.Msg.senseBox_temp_hum_tip);
|
||||||
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
|
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
|
||||||
},
|
}
|
||||||
getBlockType: function () {
|
|
||||||
return Blockly.Types.DECIMAL;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,14 +37,11 @@ Blockly.Blocks['sensebox_sensor_uv_light'] = {
|
|||||||
.setAlign(Blockly.ALIGN_RIGHT)
|
.setAlign(Blockly.ALIGN_RIGHT)
|
||||||
.appendField(Blockly.Msg.senseBox_value)
|
.appendField(Blockly.Msg.senseBox_value)
|
||||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_light, "Illuminance"], [Blockly.Msg.senseBox_uv, "UvIntensity"]]), "NAME");
|
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_light, "Illuminance"], [Blockly.Msg.senseBox_uv, "UvIntensity"]]), "NAME");
|
||||||
this.setOutput(true, Types.NUMBER.typeId);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_uv_light_tip);
|
this.setTooltip(Blockly.Msg.senseBox_uv_light_tip);
|
||||||
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
|
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
|
||||||
},
|
}
|
||||||
getBlockType: function () {
|
|
||||||
return Blockly.Types.DECIMAL;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -66,14 +60,11 @@ Blockly.Blocks['sensebox_sensor_bmx055_accelerometer'] = {
|
|||||||
.setAlign(Blockly.ALIGN_LEFT)
|
.setAlign(Blockly.ALIGN_LEFT)
|
||||||
.appendField(Blockly.Msg.senseBox_bmx055_accelerometer_range)
|
.appendField(Blockly.Msg.senseBox_bmx055_accelerometer_range)
|
||||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_bmx055_accelerometer_range_2g, "0x3"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_4g, "0x5"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_8g, "0x8"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_16g, "0x0C"]]), "RANGE");
|
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_bmx055_accelerometer_range_2g, "0x3"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_4g, "0x5"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_8g, "0x8"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_16g, "0x0C"]]), "RANGE");
|
||||||
this.setOutput(true, Types.NUMBER.typeId);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tip);
|
this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tip);
|
||||||
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
|
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
|
||||||
},
|
}
|
||||||
getBlockType: function () {
|
|
||||||
return Types.NUMBER.typeId;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,14 +82,11 @@ Blockly.Blocks['sensebox_sensor_sds011'] = {
|
|||||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_pm25, "Pm25"], [Blockly.Msg.senseBox_sds011_pm10, "Pm10"]]), "NAME")
|
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_pm25, "Pm25"], [Blockly.Msg.senseBox_sds011_pm10, "Pm10"]]), "NAME")
|
||||||
.appendField(Blockly.Msg.senseBox_sds011_dimension)
|
.appendField(Blockly.Msg.senseBox_sds011_dimension)
|
||||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_serial1, "Serial1"], [Blockly.Msg.senseBox_sds011_serial2, "Serial2"]]), "SERIAL");
|
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_serial1, "Serial1"], [Blockly.Msg.senseBox_sds011_serial2, "Serial2"]]), "SERIAL");
|
||||||
this.setOutput(true, Types.NUMBER.typeId);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_sds011_tip);
|
this.setTooltip(Blockly.Msg.senseBox_sds011_tip);
|
||||||
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
|
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
|
||||||
},
|
}
|
||||||
getBlockType: function () {
|
|
||||||
return Blockly.Types.DECIMAL;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -121,7 +109,7 @@ Blockly.Blocks['sensebox_sensor_pressure'] = {
|
|||||||
.appendField(Blockly.Msg.senseBox_value)
|
.appendField(Blockly.Msg.senseBox_value)
|
||||||
.appendField(dropdown, "NAME");
|
.appendField(dropdown, "NAME");
|
||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setOutput(true, Types.NUMBER.typeId);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_pressure_tip);
|
this.setTooltip(Blockly.Msg.senseBox_pressure_tip);
|
||||||
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/luftdruck.html');
|
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/luftdruck.html');
|
||||||
},
|
},
|
||||||
@ -167,15 +155,7 @@ Blockly.Blocks['sensebox_sensor_pressure'] = {
|
|||||||
if ((input === 'Pressure' || input === 'Temperature') && extraFieldExist !== null) {
|
if ((input === 'Pressure' || input === 'Temperature') && extraFieldExist !== null) {
|
||||||
this.removeInput('extraField');
|
this.removeInput('extraField');
|
||||||
}
|
}
|
||||||
},
|
|
||||||
getBlockType: function () {
|
|
||||||
var input = this.getFieldValue('NAME');
|
|
||||||
if (input === 'Temperature') {
|
|
||||||
return Types.DECIMAL.typeId;
|
|
||||||
} else {
|
|
||||||
return Types.LARGE_NUMBER.typeId;
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -193,13 +173,10 @@ Blockly.Blocks['sensebox_sensor_bme680_bsec'] = {
|
|||||||
.setAlign(Blockly.ALIGN_RIGHT)
|
.setAlign(Blockly.ALIGN_RIGHT)
|
||||||
.appendField(Blockly.Msg.senseBox_value)
|
.appendField(Blockly.Msg.senseBox_value)
|
||||||
.appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown")
|
.appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown")
|
||||||
this.setOutput(true, Types.NUMBER.typeId);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_bme_tip);
|
this.setTooltip(Blockly.Msg.senseBox_bme_tip);
|
||||||
},
|
}
|
||||||
getBlockType: function () {
|
|
||||||
return Types.DECIMAL.typeId;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -231,7 +208,7 @@ Blockly.Blocks['sensebox_sensor_ultrasonic_ranger'] = {
|
|||||||
.appendField(Blockly.Msg.senseBox_ultrasonic_echo)
|
.appendField(Blockly.Msg.senseBox_ultrasonic_echo)
|
||||||
.appendField(new Blockly.FieldDropdown(
|
.appendField(new Blockly.FieldDropdown(
|
||||||
selectedBoard().digitalPins), 'ultrasonic_echo');
|
selectedBoard().digitalPins), 'ultrasonic_echo');
|
||||||
this.setOutput(true, Types.NUMBER.typeId);
|
this.setOutput(true, Types.NUMBER.typeName);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tip);
|
this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tip);
|
||||||
this.setHelpUrl('https://sensebox.de/books');
|
this.setHelpUrl('https://sensebox.de/books');
|
||||||
},
|
},
|
||||||
@ -280,10 +257,6 @@ Blockly.Blocks['sensebox_sensor_ultrasonic_ranger'] = {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
getBlockType: function () {
|
|
||||||
return Blockly.Types.NUMBER;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -300,13 +273,10 @@ Blockly.Blocks['sensebox_sensor_sound'] = {
|
|||||||
.appendField(Blockly.Msg.senseBox_sound)
|
.appendField(Blockly.Msg.senseBox_sound)
|
||||||
.appendField("Pin:")
|
.appendField("Pin:")
|
||||||
.appendField(new Blockly.FieldDropdown(selectedBoard().analogPins), "PIN")
|
.appendField(new Blockly.FieldDropdown(selectedBoard().analogPins), "PIN")
|
||||||
this.setOutput(true, Types.NUMBER.typeId);
|
this.setOutput(true, Types.NUMBER.typeName);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_sound_tip);
|
this.setHelpUrl(Blockly.Msg.senseBox_sound_tip);
|
||||||
this.setTooltip('Dieser Sensor mist den Geräuschpegel.');
|
this.setTooltip('Dieser Sensor mist den Geräuschpegel.');
|
||||||
},
|
}
|
||||||
getBlockType: function () {
|
|
||||||
return Types.NUMBER.typeId;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
1
src/components/Blockly/blocks/text.js
Normal file
1
src/components/Blockly/blocks/text.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
43
src/components/Blockly/blocks/variables.js
Normal file
43
src/components/Blockly/blocks/variables.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import Blockly from 'blockly/core';
|
||||||
|
import { getColour } from '../helpers/colour';
|
||||||
|
import { getCompatibleTypes } from '../helpers/types'
|
||||||
|
|
||||||
|
|
||||||
|
Blockly.Blocks['variables_set_dynamic'] = {
|
||||||
|
init: function () {
|
||||||
|
|
||||||
|
// const type = myVar.type;
|
||||||
|
this.setColour(getColour().variables);
|
||||||
|
this.setPreviousStatement(true, null);
|
||||||
|
this.setNextStatement(true, null);
|
||||||
|
this.appendValueInput('VALUE')
|
||||||
|
.appendField('set', 'set')
|
||||||
|
.appendField('', 'type')
|
||||||
|
.appendField(new Blockly.FieldVariable('VAR'), 'VAR')
|
||||||
|
.appendField('to');
|
||||||
|
},
|
||||||
|
onchange: function (e) {
|
||||||
|
let variableID = this.getFieldValue('VAR');
|
||||||
|
let variable = Blockly.getMainWorkspace().getVariableMap().getVariableById(variableID)
|
||||||
|
this.getField('type').setValue(variable.type);
|
||||||
|
this.getInput('VALUE').setCheck(getCompatibleTypes(variable.type));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Blockly.Blocks['variables_get_dynamic'] = {
|
||||||
|
init: function () {
|
||||||
|
this.setColour(getColour().variables);
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField('', 'type')
|
||||||
|
.appendField(new Blockly.FieldVariable('VAR'), 'VAR');
|
||||||
|
this.setOutput(true);
|
||||||
|
},
|
||||||
|
onchange: function (e) {
|
||||||
|
let variableID = this.getFieldValue('VAR');
|
||||||
|
let variable = Blockly.getMainWorkspace().getVariableMap().getVariableById(variableID)
|
||||||
|
this.getField('type').setValue(variable.type);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
src/components/Blockly/generator/audio.js
Normal file
25
src/components/Blockly/generator/audio.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import * as Blockly from 'blockly/core';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function for turning the tone library on on a given pin (X).
|
||||||
|
* Arduino code: setup { pinMode(X, OUTPUT) }
|
||||||
|
* loop { tone(X, frequency) }
|
||||||
|
* @param {!Blockly.Block} block Block to generate the code from.
|
||||||
|
* @return {array} Completed code with order of operation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Blockly.Arduino['io_tone'] = function (block) {
|
||||||
|
var pin = block.getFieldValue('TONEPIN');
|
||||||
|
var freq = Blockly.Arduino.valueToCode(block, 'FREQUENCY', Blockly.Arduino.ORDER_ATOMIC);
|
||||||
|
Blockly.Arduino.setupCode_['io_tone' + pin] = 'pinMode(' + pin + ', OUTPUT);\n';
|
||||||
|
var code = 'tone(' + pin + ',' + freq + ');\n';
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Arduino['io_notone'] = function (block) {
|
||||||
|
var pin = block.getFieldValue("TONEPIN");
|
||||||
|
Blockly.Arduino.setupCode_['io_tone' + pin] = 'pinMode(' + pin + ', OUTPUT);\n';
|
||||||
|
var code = 'noTone(' + pin + ');\n';
|
||||||
|
return code;
|
||||||
|
};
|
@ -7,11 +7,15 @@ import './sensebox-web';
|
|||||||
import './sensebox-display';
|
import './sensebox-display';
|
||||||
import './sensebox-lora';
|
import './sensebox-lora';
|
||||||
import './sensebox-led';
|
import './sensebox-led';
|
||||||
|
import './sensebox-sd';
|
||||||
import './logic';
|
import './logic';
|
||||||
|
import './text';
|
||||||
import './math';
|
import './math';
|
||||||
import './map';
|
import './map';
|
||||||
import './io';
|
import './io';
|
||||||
|
import './audio';
|
||||||
import './procedures';
|
import './procedures';
|
||||||
import './time';
|
import './time';
|
||||||
|
import './variables';
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,7 +86,37 @@ Blockly.Arduino['controls_if'] = function (Block) {
|
|||||||
return code + '\n';
|
return code + '\n';
|
||||||
};
|
};
|
||||||
|
|
||||||
Blockly.Arduino['controls_ifelse'] = Blockly.Arduino['control_if'];
|
Blockly.Arduino['controls_ifelse'] = function (Block) {
|
||||||
|
// If/elseif/else condition.
|
||||||
|
let n = 0;
|
||||||
|
let code = '',
|
||||||
|
branchCode,
|
||||||
|
conditionCode;
|
||||||
|
do {
|
||||||
|
conditionCode =
|
||||||
|
Blockly.Arduino.valueToCode(
|
||||||
|
Block,
|
||||||
|
'IF' + n,
|
||||||
|
Blockly.Arduino.ORDER_NONE
|
||||||
|
) || 'false';
|
||||||
|
branchCode = Blockly.Arduino.statementToCode(Block, 'DO' + n);
|
||||||
|
code +=
|
||||||
|
(n > 0 ? ' else ' : '') +
|
||||||
|
'if (' +
|
||||||
|
conditionCode +
|
||||||
|
') {\n' +
|
||||||
|
branchCode +
|
||||||
|
'}';
|
||||||
|
|
||||||
|
++n;
|
||||||
|
} while (Block.getInput('IF' + n));
|
||||||
|
|
||||||
|
if (Block.getInput('ELSE')) {
|
||||||
|
branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE');
|
||||||
|
code += ' else {\n' + branchCode + '}';
|
||||||
|
}
|
||||||
|
return code + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
Blockly.Arduino['logic_negate'] = function (Block) {
|
Blockly.Arduino['logic_negate'] = function (Block) {
|
||||||
// Negation.
|
// Negation.
|
||||||
@ -95,3 +125,30 @@ Blockly.Arduino['logic_negate'] = function (Block) {
|
|||||||
const code = '!' + argument0;
|
const code = '!' + argument0;
|
||||||
return [code, order];
|
return [code, order];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Blockly.Arduino['switch_case'] = function (block) {
|
||||||
|
var n = 0;
|
||||||
|
var argument = Blockly.Arduino.valueToCode(this, 'CONDITION',
|
||||||
|
Blockly.Arduino.ORDER_NONE) || '';
|
||||||
|
var branch = Blockly.Arduino.statementToCode(block, 'CASECONDITON0' + n);
|
||||||
|
var cases = '';
|
||||||
|
var default_code = '';
|
||||||
|
var DO = Blockly.Arduino.statementToCode(block, ('CASE' + n));
|
||||||
|
for (n = 0; n <= block.caseCount_; n++) {
|
||||||
|
DO = Blockly.Arduino.statementToCode(block, ('CASE' + n));
|
||||||
|
branch = Blockly.Arduino.valueToCode(block, ('CASECONDITION' + n), Blockly.Arduino.ORDER_NONE) || '0';
|
||||||
|
cases += 'case ' + branch + ':\n';
|
||||||
|
cases += DO + '\nbreak;\n';
|
||||||
|
}
|
||||||
|
if (block.defaultCount_) {
|
||||||
|
branch = Blockly.Arduino.statementToCode(block, 'ONDEFAULT');
|
||||||
|
default_code = 'default: \n' + branch + '\n break;\n';
|
||||||
|
}
|
||||||
|
var code = 'switch (' + argument + ') {\n' + cases + default_code + '}';
|
||||||
|
return code + '\n';
|
||||||
|
};
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ Blockly['Arduino']['controls_repeat_ext'] = function (Block) {
|
|||||||
let branch = Blockly['Arduino'].statementToCode(Block, 'DO');
|
let branch = Blockly['Arduino'].statementToCode(Block, 'DO');
|
||||||
branch = Blockly['Arduino'].addLoopTrap(branch, Block.id);
|
branch = Blockly['Arduino'].addLoopTrap(branch, Block.id);
|
||||||
let code = '';
|
let code = '';
|
||||||
const loopVar = 'simple_loop_variable';
|
const loopVar = 'i';
|
||||||
code +=
|
code +=
|
||||||
'for (' +
|
'for (int ' +
|
||||||
loopVar +
|
loopVar +
|
||||||
' = 1; ' +
|
' = 1; ' +
|
||||||
loopVar +
|
loopVar +
|
||||||
@ -36,6 +36,8 @@ Blockly['Arduino']['controls_for'] = function (Block) {
|
|||||||
Block.getFieldValue('VAR')
|
Block.getFieldValue('VAR')
|
||||||
).name;
|
).name;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const branch = Blockly['Arduino'].statementToCode(Block, 'DO');
|
const branch = Blockly['Arduino'].statementToCode(Block, 'DO');
|
||||||
|
|
||||||
const startNumber =
|
const startNumber =
|
||||||
|
@ -19,9 +19,9 @@ Blockly.Arduino['arduino_functions'] = function (block) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var setupBranch = Blockly.Arduino.statementToCode(block, 'SETUP_FUNC');
|
var setupBranch = Blockly.Arduino.statementToCode(block, 'SETUP_FUNC');
|
||||||
//var setupCode = Blockly.Arduino.scrub_(block, setupBranch); No comment block
|
// //var setupCode = Blockly.Arduino.scrub_(block, setupBranch); No comment block
|
||||||
if (setupBranch) {
|
if (setupBranch) {
|
||||||
Blockly.Arduino.setupCode_('userSetupCode', setupBranch, true);
|
Blockly.Arduino.setupCode_['mainsetup'] = setupBranch;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loopBranch = statementToCodeNoTab(block, 'LOOP_FUNC');
|
var loopBranch = statementToCodeNoTab(block, 'LOOP_FUNC');
|
||||||
|
54
src/components/Blockly/generator/sensebox-sd.js
Normal file
54
src/components/Blockly/generator/sensebox-sd.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import Blockly from 'blockly';
|
||||||
|
|
||||||
|
|
||||||
|
/* SD-Card Blocks using the Standard SD Library*/
|
||||||
|
/**
|
||||||
|
* Code generator for variable (X) getter.
|
||||||
|
* Arduino code: loop { X }
|
||||||
|
* @param {Blockly.Block} block Block to generate the code from.
|
||||||
|
* @return {array} Completed code with order of operation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_sd_create_file = function (block) {
|
||||||
|
var filename = this.getFieldValue('Filename');
|
||||||
|
var res = filename.slice(0, 4);
|
||||||
|
Blockly.Arduino.libraries_['library_spi'] = '#include <SPI.h>';
|
||||||
|
Blockly.Arduino.libraries_['library_sd'] = '#include <SD.h>';
|
||||||
|
Blockly.Arduino.definitions_['define_' + res] = 'File dataFile' + res + ';';
|
||||||
|
Blockly.Arduino.setupCode_['sensebox_sd'] = 'SD.begin(28);';
|
||||||
|
Blockly.Arduino.setupCode_['sensebox_sd' + filename] = 'dataFile' + res + ' = SD.open("' + filename + '", FILE_WRITE);\ndataFile' + res + '.close();\n';
|
||||||
|
var code = '';
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_sd_open_file = function (block) {
|
||||||
|
var filename = this.getFieldValue('Filename');
|
||||||
|
var res = filename.slice(0, 4);
|
||||||
|
var branch = Blockly.Arduino.statementToCode(block, 'SD');
|
||||||
|
var code = 'dataFile' + res + ' = SD.open("' + filename + '", FILE_WRITE);\n'
|
||||||
|
code += branch;
|
||||||
|
code += 'dataFile' + res + '.close();\n'
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_sd_write_file = function (block) {
|
||||||
|
if (this.parentBlock_ != null) {
|
||||||
|
var filename = this.getSurroundParent().getFieldValue('Filename');
|
||||||
|
}
|
||||||
|
var res = filename.slice(0, 4);
|
||||||
|
var text = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || '"Keine Eingabe"';
|
||||||
|
var linebreak = this.getFieldValue('linebreak');
|
||||||
|
if (linebreak === "TRUE") {
|
||||||
|
linebreak = "ln";
|
||||||
|
} else {
|
||||||
|
linebreak = "";
|
||||||
|
}
|
||||||
|
var code = '';
|
||||||
|
if (text === "gps.getLongitude()" || text === "gps.getLatitude()") {
|
||||||
|
code = 'dataFile' + res + '.print' + linebreak + '(' + text + ',5);\n'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
code = 'dataFile' + res + '.print' + linebreak + '(' + text + ');\n'
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
};
|
@ -13,7 +13,7 @@ Blockly.Arduino.sensebox_telegram = function (Block) {
|
|||||||
|
|
||||||
UniversalTelegramBot bot(BOTtoken, client);`
|
UniversalTelegramBot bot(BOTtoken, client);`
|
||||||
|
|
||||||
let code = 'testcode';
|
let code = '';
|
||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
85
src/components/Blockly/generator/text.js
Normal file
85
src/components/Blockly/generator/text.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import * as Blockly from 'blockly/core';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code generator for a literal String (X).
|
||||||
|
* Arduino code: loop { "X" }
|
||||||
|
* @param {!Blockly.Block} block Block to generate the code from.
|
||||||
|
* @return {array} Completed code with order of operation.
|
||||||
|
*/
|
||||||
|
Blockly.Arduino['text'] = function (block) {
|
||||||
|
var code = Blockly.Arduino.quote_(block.getFieldValue('TEXT'));
|
||||||
|
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code generator for a String concatenation (X...Y). This string can be made
|
||||||
|
* up of any number of elements of any type.
|
||||||
|
* This block uses a mutator.
|
||||||
|
* String construction info: http://arduino.cc/en/Reference/StringConstructor
|
||||||
|
* Arduino code: loop { "String(X)" + ... + "String(Y)" }
|
||||||
|
* @param {!Blockly.Block} block Block to generate the code from.
|
||||||
|
* @return {array} Completed code with order of operation.
|
||||||
|
*/
|
||||||
|
Blockly.Arduino['text_join'] = function (block) {
|
||||||
|
var code;
|
||||||
|
if (block.itemCount_ === 0) {
|
||||||
|
return ['""', Blockly.Arduino.ORDER_ATOMIC];
|
||||||
|
} else if (block.itemCount_ === 1) {
|
||||||
|
var argument0 = Blockly.Arduino.valueToCode(block, 'ADD0',
|
||||||
|
Blockly.Arduino.ORDER_UNARY_POSTFIX) || '""';
|
||||||
|
code = 'String(' + argument0 + ')';
|
||||||
|
return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||||
|
} else {
|
||||||
|
var argument;
|
||||||
|
code = [];
|
||||||
|
for (var n = 0; n < block.itemCount_; n++) {
|
||||||
|
argument = Blockly.Arduino.valueToCode(
|
||||||
|
block, 'ADD' + n, Blockly.Arduino.ORDER_NONE);
|
||||||
|
if (argument === '') {
|
||||||
|
code[n] = '""';
|
||||||
|
} else {
|
||||||
|
code[n] = 'String(' + argument + ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = code.join(' + ');
|
||||||
|
return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code generator for appending text (Y) to a variable in place (X).
|
||||||
|
* String constructor info: http://arduino.cc/en/Reference/StringConstructor
|
||||||
|
* Arduino code: loop { X += String(Y) }
|
||||||
|
* @param {!Blockly.Block} block Block to generate the code from.
|
||||||
|
* @return {string} Completed code.
|
||||||
|
*/
|
||||||
|
Blockly.Arduino['text_append'] = function (block) {
|
||||||
|
// Append to a variable in place.
|
||||||
|
var varName = Blockly.Arduino.variableDB_.getName(
|
||||||
|
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||||
|
var argument0 = Blockly.Arduino.valueToCode(block, 'TEXT',
|
||||||
|
Blockly.Arduino.ORDER_UNARY_POSTFIX);
|
||||||
|
if (argument0 === '') {
|
||||||
|
argument0 = '""';
|
||||||
|
} else {
|
||||||
|
argument0 = 'String(' + argument0 + ')';
|
||||||
|
}
|
||||||
|
return varName + ' += ' + argument0 + ';\n';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code generator to get the length of a string (X).
|
||||||
|
* String length info: http://arduino.cc/en/Reference/StringLength
|
||||||
|
* Arduino code: loop { String(X).length() }
|
||||||
|
* @param {!Blockly.Block} block Block to generate the code from.
|
||||||
|
* @return {array} Completed code with order of operation.
|
||||||
|
*/
|
||||||
|
Blockly.Arduino['text_length'] = function (block) {
|
||||||
|
var argument0 = Blockly.Arduino.valueToCode(block, 'VALUE',
|
||||||
|
Blockly.Arduino.ORDER_UNARY_POSTFIX) || '""';
|
||||||
|
var code = 'String(' + argument0 + ').length()';
|
||||||
|
return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||||
|
};
|
||||||
|
|
33
src/components/Blockly/generator/variables.js
Normal file
33
src/components/Blockly/generator/variables.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import Blockly from 'blockly';
|
||||||
|
|
||||||
|
const setVariableFunction = function (defaultValue) {
|
||||||
|
return function (block) {
|
||||||
|
const variableName = Blockly['Arduino'].variableDB_.getName(
|
||||||
|
block.getFieldValue('VAR'),
|
||||||
|
Blockly.Variables.NAME_TYPE
|
||||||
|
);
|
||||||
|
const variableValue = Blockly['Arduino'].valueToCode(
|
||||||
|
block,
|
||||||
|
'VALUE',
|
||||||
|
Blockly['Arduino'].ORDER_ATOMIC
|
||||||
|
);
|
||||||
|
|
||||||
|
const allVars = Blockly.getMainWorkspace().getVariableMap().getAllVariables();
|
||||||
|
const myVar = allVars.filter(v => v.name === variableName)[0]
|
||||||
|
|
||||||
|
Blockly.Arduino.variables_[myVar + myVar.type] = myVar.type + " " + myVar.name + ';\n';
|
||||||
|
return variableName + ' = ' + (variableValue || defaultValue) + ';\n';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getVariableFunction = function (block) {
|
||||||
|
const variableName = Blockly['Arduino'].variableDB_.getName(
|
||||||
|
block.getFieldValue('VAR'),
|
||||||
|
Blockly.Variables.NAME_TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
return [variableName, Blockly['Arduino'].ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly['Arduino']['variables_set_dynamic'] = setVariableFunction()
|
||||||
|
Blockly['Arduino']['variables_get_dynamic'] = getVariableFunction;
|
@ -7,6 +7,9 @@ const colours = {
|
|||||||
io: 60,
|
io: 60,
|
||||||
procedures: 290,
|
procedures: 290,
|
||||||
time: 140,
|
time: 140,
|
||||||
|
text: 160,
|
||||||
|
variables: 330,
|
||||||
|
audio: 250,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,57 +12,54 @@
|
|||||||
/** Single character. */
|
/** Single character. */
|
||||||
export const CHARACTER = {
|
export const CHARACTER = {
|
||||||
typeId: 'Character',
|
typeId: 'Character',
|
||||||
|
typeName: 'char',
|
||||||
typeMsgName: 'ARD_TYPE_CHAR',
|
typeMsgName: 'ARD_TYPE_CHAR',
|
||||||
compatibleTypes: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BOOLEAN = {
|
export const BOOLEAN = {
|
||||||
typeId: 'Boolean',
|
typeId: 'Boolean',
|
||||||
typeMsgName: 'ARD_TYPE_BOOL',
|
typeMsgName: 'ARD_TYPE_BOOL',
|
||||||
compatibleTypes: ['Boolean']
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Text string. */
|
/** Text string. */
|
||||||
export const TEXT = {
|
export const TEXT = {
|
||||||
typeId: 'Text',
|
typeId: 'Text',
|
||||||
|
typeName: 'String',
|
||||||
typeMsgName: 'ARD_TYPE_TEXT',
|
typeMsgName: 'ARD_TYPE_TEXT',
|
||||||
compatibleTypes: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Short integer number. */
|
/** Short integer number. */
|
||||||
export const SHORT_NUMBER = {
|
export const SHORT_NUMBER = {
|
||||||
typeId: 'Short Number',
|
typeId: 'Short_Number',
|
||||||
|
typeName: 'int',
|
||||||
typeMsgName: 'ARD_TYPE_SHORT',
|
typeMsgName: 'ARD_TYPE_SHORT',
|
||||||
compatibleTypes: [] // Circular dependencies, add after all declarations
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Integer number. */
|
/** Integer number. */
|
||||||
export const NUMBER = {
|
export const NUMBER = {
|
||||||
typeId: 'Number',
|
typeId: 'Number',
|
||||||
|
typeName: 'int',
|
||||||
typeMsgName: 'ARD_TYPE_NUMBER',
|
typeMsgName: 'ARD_TYPE_NUMBER',
|
||||||
compatibleTypes: ['Number'] // Circular dependencies, add after all declarations
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Large integer number. */
|
/** Large integer number. */
|
||||||
export const LARGE_NUMBER = {
|
export const LARGE_NUMBER = {
|
||||||
typeId: 'Large Number',
|
typeId: 'Large Number',
|
||||||
|
typeName: 'long',
|
||||||
typeMsgName: 'ARD_TYPE_LONG',
|
typeMsgName: 'ARD_TYPE_LONG',
|
||||||
compatibleTypes: [] // Circular dependencies, add after all declarations
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decimal/floating point number. */
|
/** Decimal/floating point number. */
|
||||||
export const DECIMAL = {
|
export const DECIMAL = {
|
||||||
typeId: 'Decimal',
|
typeId: 'Decimal',
|
||||||
|
typeName: 'float',
|
||||||
typeMsgName: 'ARD_TYPE_DECIMAL',
|
typeMsgName: 'ARD_TYPE_DECIMAL',
|
||||||
compatibleTypes: [BOOLEAN.typeId,
|
|
||||||
NUMBER,
|
|
||||||
SHORT_NUMBER,
|
|
||||||
LARGE_NUMBER]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Array/List of items. */
|
/** Array/List of items. */
|
||||||
export const ARRAY = {
|
export const ARRAY = {
|
||||||
typeId: 'Array',
|
typeId: 'Array',
|
||||||
|
typeName: 'array',
|
||||||
typeMsgName: 'ARD_TYPE_ARRAY',
|
typeMsgName: 'ARD_TYPE_ARRAY',
|
||||||
compatibleTypes: []
|
compatibleTypes: []
|
||||||
}
|
}
|
||||||
@ -70,15 +67,15 @@ export const ARRAY = {
|
|||||||
/** Null indicate there is no type. */
|
/** Null indicate there is no type. */
|
||||||
export const NULL = {
|
export const NULL = {
|
||||||
typeId: 'Null',
|
typeId: 'Null',
|
||||||
|
typeName: 'void',
|
||||||
typeMsgName: 'ARD_TYPE_NULL',
|
typeMsgName: 'ARD_TYPE_NULL',
|
||||||
compatibleTypes: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Type not defined, or not yet defined. */
|
/** Type not defined, or not yet defined. */
|
||||||
export const UNDEF = {
|
export const UNDEF = {
|
||||||
typeId: 'Undefined',
|
typeId: 'Undefined',
|
||||||
|
typeName: 'undef',
|
||||||
typeMsgName: 'ARD_TYPE_UNDEF',
|
typeMsgName: 'ARD_TYPE_UNDEF',
|
||||||
compatibleTypes: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set when no child block (meant to define the variable type) is connected. */
|
/** Set when no child block (meant to define the variable type) is connected. */
|
||||||
@ -88,6 +85,24 @@ export const CHILD_BLOCK_MISSING = {
|
|||||||
compatibleTypes: []
|
compatibleTypes: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const compatibleTypes = {
|
||||||
|
boolean: ['boolean'],
|
||||||
|
int: ['int'],
|
||||||
|
char: ['char'],
|
||||||
|
string: ['String'],
|
||||||
|
void: ['void'],
|
||||||
|
long: ['int', 'long'],
|
||||||
|
double: ['int', 'long', 'double'],
|
||||||
|
float: ['int', 'long', 'double', 'float']
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getCompatibleTypes = (type) => {
|
||||||
|
return compatibleTypes[type];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const VARIABLE_TYPES = [['SHORT_NUMBER', 'char'], ['NUMBER', 'int'], ['DECIMAL', 'long'], ['TEXT', 'String'], ['CHARACTER', 'char'], ['BOOLEAN', 'boolean'], ['NULL', 'void'], ['UNDEF', 'undefined']];
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Some Types have circular dependencies on their compatibilities, so add them
|
// * Some Types have circular dependencies on their compatibilities, so add them
|
||||||
// * after declaration.
|
// * after declaration.
|
||||||
|
@ -3,13 +3,41 @@ import { Block, Value, Field, Shadow, Category } from '../';
|
|||||||
import { getColour } from '../helpers/colour'
|
import { getColour } from '../helpers/colour'
|
||||||
import '@blockly/block-plus-minus';
|
import '@blockly/block-plus-minus';
|
||||||
|
|
||||||
|
import { TypedVariableModal } from '@blockly/plugin-typed-variable-modal';
|
||||||
|
import * as Blockly from 'blockly/core';
|
||||||
|
import BlocklyComponent from '../BlocklyComponent';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Toolbox extends React.Component {
|
class Toolbox extends React.Component {
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
this.props.workspace.registerToolboxCategoryCallback('CREATE_TYPED_VARIABLE', this.createFlyout);
|
||||||
|
|
||||||
|
const typedVarModal = new TypedVariableModal(this.props.workspace, 'callbackName', [['SHORT_NUMBER', 'char'], ['NUMBER', 'int'], ['DECIMAL', 'float'], ['TEXT', 'String'], ['CHARACTER', 'char'], ['BOOLEAN', 'boolean'], ['NULL', 'void'], ['UNDEF', 'undefined']]);
|
||||||
|
typedVarModal.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
createFlyout(workspace) {
|
||||||
|
let xmlList = [];
|
||||||
|
// Add your button and give it a callback name.
|
||||||
|
const button = document.createElement('button');
|
||||||
|
button.setAttribute('text', 'Create Typed Variable');
|
||||||
|
button.setAttribute('callbackKey', 'callbackName');
|
||||||
|
|
||||||
|
xmlList.push(button);
|
||||||
|
|
||||||
|
// This gets all the variables that the user creates and adds them to the
|
||||||
|
// flyout.
|
||||||
|
const blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(workspace);
|
||||||
|
xmlList = xmlList.concat(blockList);
|
||||||
|
return xmlList;
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<xml xmlns="https://developers.google.com/blockly/xml" id="blockly" style={{ display: 'none' }} ref={this.props.toolbox}>
|
<xml xmlns="https://developers.google.com/blockly/xml" id="blockly" style={{ display: 'none' }} ref={this.props.toolbox}>
|
||||||
<Category name="senseBox" colour={getColour().sensebox}>
|
|
||||||
<Category name="Sensoren" colour={getColour().sensebox}>
|
<Category name="Sensoren" colour={getColour().sensebox}>
|
||||||
<Block type="sensebox_sensor_temp_hum" />
|
<Block type="sensebox_sensor_temp_hum" />
|
||||||
<Block type="sensebox_sensor_uv_light" />
|
<Block type="sensebox_sensor_uv_light" />
|
||||||
@ -24,6 +52,11 @@ class Toolbox extends React.Component {
|
|||||||
<Block type="sensebox_wifi" />
|
<Block type="sensebox_wifi" />
|
||||||
<Block type="sensebox_startap" />
|
<Block type="sensebox_startap" />
|
||||||
</Category>
|
</Category>
|
||||||
|
<Category name="SD" colour={getColour().sensebox}>
|
||||||
|
<Block type="sensebox_sd_create_file" />
|
||||||
|
<Block type="sensebox_sd_open_file" />
|
||||||
|
<Block type="sensebox_sd_write_file" />
|
||||||
|
</Category>
|
||||||
<Category name="LED" colour={getColour().sensebox}>
|
<Category name="LED" colour={getColour().sensebox}>
|
||||||
<Block type="sensebox_rgb_led" />
|
<Block type="sensebox_rgb_led" />
|
||||||
<Block type="sensebox_led" />
|
<Block type="sensebox_led" />
|
||||||
@ -144,8 +177,9 @@ class Toolbox extends React.Component {
|
|||||||
<Block type="sensebox_telegram_do_on_message" />
|
<Block type="sensebox_telegram_do_on_message" />
|
||||||
<Block type="sensebox_telegram_send" />
|
<Block type="sensebox_telegram_send" />
|
||||||
</Category>
|
</Category>
|
||||||
<Category name="osem" colour={getColour().sensebox}>
|
<Category name="openSenseMap" colour={getColour().sensebox}>
|
||||||
<Block type="sensebox_osem_connection" />
|
<Block type="sensebox_osem_connection" />
|
||||||
|
<Block type="sensebox_send_to_osem" />
|
||||||
</Category>
|
</Category>
|
||||||
<Category id="catSenseBoxOutput_LoRa" name=" LoRa" colour={getColour().sensebox}>
|
<Category id="catSenseBoxOutput_LoRa" name=" LoRa" colour={getColour().sensebox}>
|
||||||
<Category id="catSenseBoxOutput_LoRa_activation" name=" Activation" colour={getColour().sensebox}>
|
<Category id="catSenseBoxOutput_LoRa_activation" name=" Activation" colour={getColour().sensebox}>
|
||||||
@ -167,7 +201,6 @@ class Toolbox extends React.Component {
|
|||||||
<Block type="sensebox_lora_cayenne_gps" />
|
<Block type="sensebox_lora_cayenne_gps" />
|
||||||
</Category>
|
</Category>
|
||||||
</Category>
|
</Category>
|
||||||
</Category>
|
|
||||||
<Category name="Logic" colour={getColour().logic}>
|
<Category name="Logic" colour={getColour().logic}>
|
||||||
<Block type="controls_if" />
|
<Block type="controls_if" />
|
||||||
<Block type="controls_ifelse" />
|
<Block type="controls_ifelse" />
|
||||||
@ -175,6 +208,7 @@ class Toolbox extends React.Component {
|
|||||||
<Block type="logic_operation" />
|
<Block type="logic_operation" />
|
||||||
<Block type="logic_negate" />
|
<Block type="logic_negate" />
|
||||||
<Block type="logic_boolean" />
|
<Block type="logic_boolean" />
|
||||||
|
<Block type="switch_case" />
|
||||||
</Category>
|
</Category>
|
||||||
<Category id="loops" name="Loops" colour={getColour().loops}>
|
<Category id="loops" name="Loops" colour={getColour().loops}>
|
||||||
<Block type="controls_repeat_ext">
|
<Block type="controls_repeat_ext">
|
||||||
@ -204,6 +238,17 @@ class Toolbox extends React.Component {
|
|||||||
</Block>
|
</Block>
|
||||||
<Block type="controls_flow_statements" />
|
<Block type="controls_flow_statements" />
|
||||||
</Category>
|
</Category>
|
||||||
|
<Category id="text" name="Text" colour={getColour().text}>
|
||||||
|
<Block type="text" />
|
||||||
|
<Block type="text_join" />
|
||||||
|
<Block type="text_append">
|
||||||
|
<Value name="TEXT">
|
||||||
|
<Block type="text" />
|
||||||
|
</Value>
|
||||||
|
</Block>
|
||||||
|
<Block type="text_length" />
|
||||||
|
<Block type="text_isEmpty" />
|
||||||
|
</Category>
|
||||||
<Category id="time" name="Time" colour={getColour().time}>
|
<Category id="time" name="Time" colour={getColour().time}>
|
||||||
<Block type="time_delay">
|
<Block type="time_delay">
|
||||||
<Value name="DELAY_TIME_MILI">
|
<Value name="DELAY_TIME_MILI">
|
||||||
@ -267,6 +312,17 @@ class Toolbox extends React.Component {
|
|||||||
<Block type="math_random_float"></Block>
|
<Block type="math_random_float"></Block>
|
||||||
<Block type="base_map"></Block>
|
<Block type="base_map"></Block>
|
||||||
</Category>
|
</Category>
|
||||||
|
<Category id="audio" name="Audio" colour={getColour().audio}>
|
||||||
|
<Block type="io_tone">
|
||||||
|
<Value name="FREQUENCY">
|
||||||
|
<Shadow type="math_number">
|
||||||
|
<Field name="NUM">220</Field>
|
||||||
|
</Shadow>
|
||||||
|
</Value>
|
||||||
|
</Block>
|
||||||
|
<Block type="io_notone"></Block>
|
||||||
|
</Category>
|
||||||
|
<Category name="Variablen" colour={getColour().variables} custom="CREATE_TYPED_VARIABLE"></Category>;
|
||||||
<sep></sep>
|
<sep></sep>
|
||||||
<Category name="Input/Output" colour={getColour().io}>
|
<Category name="Input/Output" colour={getColour().io}>
|
||||||
<Block type="io_digitalwrite"></Block>
|
<Block type="io_digitalwrite"></Block>
|
||||||
|
@ -158,4 +158,5 @@ const mapStateToProps = state => ({
|
|||||||
name: state.workspace.name
|
name: state.workspace.name
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, { workspaceName })(withStyles(styles, {withTheme: true})(Compile));
|
export default connect(mapStateToProps, { workspaceName })(withStyles(styles, {withTheme: true})(Compile));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user