commit
67cc477d28
41
package-lock.json
generated
41
package-lock.json
generated
@ -1097,14 +1097,27 @@
|
||||
}
|
||||
},
|
||||
"@blockly/block-plus-minus": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/block-plus-minus/-/block-plus-minus-2.0.8.tgz",
|
||||
"integrity": "sha512-LRn+Js2rZ14XyrSoEf7wTz6/ESNW2MI5TkXJ2wWFJVA+/E4lTfBwXeZpRFYRP9DZwNEv9alZETyEcBbK+FCZKw=="
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/block-plus-minus/-/block-plus-minus-2.0.10.tgz",
|
||||
"integrity": "sha512-YWEQd9xHAAn1aJgIuZsAdx2t9ZSjinaSEzbN1c43iU584TvaiPsGq5JcnLpoDIyGgJI90Nk+o4erWyQR+kqLyQ=="
|
||||
},
|
||||
"@blockly/field-slider": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-2.0.7.tgz",
|
||||
"integrity": "sha512-kSFeeyfJboj2zOz55hgunFzRHQZUTWmKgw695GOwOGvt4wTG5SQ2/pNnd+C41vdjaOdjaI8tlwiyWg4oJ/MPeA=="
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-2.1.1.tgz",
|
||||
"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": {
|
||||
"version": "1.0.4",
|
||||
@ -3065,9 +3078,9 @@
|
||||
}
|
||||
},
|
||||
"blockly": {
|
||||
"version": "3.20200625.2",
|
||||
"resolved": "https://registry.npmjs.org/blockly/-/blockly-3.20200625.2.tgz",
|
||||
"integrity": "sha512-+0aUynP4kAFjg+m9uSyctWB+KwT3/BDmqy4Fm7vwWq7cuMtgIsqqA8VGb6INVpFx9WZUXSZ5enFAco6CM85bpA==",
|
||||
"version": "3.20200924.0",
|
||||
"resolved": "https://registry.npmjs.org/blockly/-/blockly-3.20200924.0.tgz",
|
||||
"integrity": "sha512-mOZiXi908oNFAcVb8Q5LKJNRZ5jtBJtgNilddqTYMAXEdqSY/BhcnU2rgytWARDnu2iSQlI374kEafCNuUEWKQ==",
|
||||
"requires": {
|
||||
"jsdom": "^15.2.1"
|
||||
},
|
||||
@ -5947,6 +5960,11 @@
|
||||
"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": {
|
||||
"version": "1.0.0",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
|
||||
"integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA=="
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
|
@ -3,8 +3,9 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@blockly/block-plus-minus": "^2.0.8",
|
||||
"@blockly/field-slider": "^2.0.7",
|
||||
"@blockly/block-plus-minus": "^2.0.10",
|
||||
"@blockly/field-slider": "^2.1.1",
|
||||
"@blockly/plugin-typed-variable-modal": "^3.1.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.14.0",
|
||||
"@fortawesome/react-fontawesome": "^0.1.11",
|
||||
@ -12,7 +13,7 @@
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.5.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"blockly": "^3.20200625.2",
|
||||
"blockly": "^3.20200924.0",
|
||||
"file-saver": "^2.0.2",
|
||||
"moment": "^2.28.0",
|
||||
"prismjs": "^1.20.0",
|
||||
|
@ -34,10 +34,12 @@ import { Card } from '@material-ui/core';
|
||||
Blockly.setLocale(locale);
|
||||
|
||||
class BlocklyComponent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.blocklyDiv = React.createRef();
|
||||
this.toolbox = React.createRef();
|
||||
this.state = {workspace: undefined};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -49,6 +51,7 @@ class BlocklyComponent extends React.Component {
|
||||
...rest
|
||||
},
|
||||
);
|
||||
this.setState({workspace: this.primaryWorkspace})
|
||||
|
||||
if (initialXml) {
|
||||
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(initialXml), this.primaryWorkspace);
|
||||
@ -64,11 +67,9 @@ class BlocklyComponent extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
return <React.Fragment>
|
||||
<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>;
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class BlocklyWindow extends Component {
|
||||
this.props.onChangeWorkspace(event);
|
||||
// switch on that a block is displayed disabled or not depending on whether it is correctly connected
|
||||
// for SVG display, a deactivated block in the display is undesirable
|
||||
if(this.props.blockDisabled){
|
||||
if (this.props.blockDisabled) {
|
||||
Blockly.Events.disableOrphans(event);
|
||||
}
|
||||
});
|
||||
@ -39,10 +39,10 @@ class BlocklyWindow extends Component {
|
||||
const workspace = Blockly.getMainWorkspace();
|
||||
var xml = this.props.initialXml;
|
||||
// if svg is true, then the update process is done in the BlocklySvg component
|
||||
if(props.initialXml !== xml && !this.props.svg){
|
||||
if (props.initialXml !== xml && !this.props.svg) {
|
||||
// guarantees that the current xml-code (this.props.initialXml) is rendered
|
||||
workspace.clear();
|
||||
if(!xml) xml = initialXml;
|
||||
if (!xml) xml = initialXml;
|
||||
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
|
||||
}
|
||||
Blockly.svgResize(workspace);
|
||||
@ -52,7 +52,7 @@ class BlocklyWindow extends Component {
|
||||
return (
|
||||
<div>
|
||||
<BlocklyComponent ref={this.simpleWorkspace}
|
||||
style={this.props.svg ? {height: 0} : this.props.blocklyCSS}
|
||||
style={this.props.svg ? { height: 0 } : this.props.blocklyCSS}
|
||||
readOnly={this.props.readOnly !== undefined ? this.props.readOnly : false}
|
||||
trashcan={this.props.trashcan !== undefined ? this.props.trashcan : true}
|
||||
renderer='zelos'
|
||||
@ -70,18 +70,18 @@ class BlocklyWindow extends Component {
|
||||
length: 1,
|
||||
colour: '#4EAF47', // senseBox-green
|
||||
snap: false
|
||||
}}
|
||||
}}
|
||||
media={'/media/blockly/'}
|
||||
move={this.props.move !== undefined && !this.props.move ? {} :
|
||||
{ // https://developers.google.com/blockly/guides/configure/web/move
|
||||
scrollbars: true,
|
||||
drag: true,
|
||||
wheel: false
|
||||
}}
|
||||
}}
|
||||
initialXml={this.props.initialXml ? this.props.initialXml : initialXml}
|
||||
>
|
||||
</BlocklyComponent >
|
||||
{this.props.svg && this.props.initialXml ? <BlocklySvg initialXml={this.props.initialXml}/> : null}
|
||||
{this.props.svg && this.props.initialXml ? <BlocklySvg initialXml={this.props.initialXml} /> : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
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-lora';
|
||||
import './sensebox-led';
|
||||
import './sensebox-sd';
|
||||
import './text';
|
||||
import './io';
|
||||
import './audio';
|
||||
import './math';
|
||||
import './map';
|
||||
import './procedures';
|
||||
import './time';
|
||||
|
||||
import './variables';
|
||||
|
||||
import '../helpers/types'
|
@ -56,7 +56,7 @@ Blockly.Blocks['io_digitalread'] = {
|
||||
.appendField(Blockly.Msg.ARD_DIGITALREAD)
|
||||
.appendField(new Blockly.FieldDropdown(
|
||||
selectedBoard().digitalPins), 'PIN');
|
||||
this.setOutput(true, Types.BOOLEAN);
|
||||
this.setOutput(true, 'boolean');
|
||||
this.setTooltip(Blockly.Msg.ARD_DIGITALREAD_TIP);
|
||||
},
|
||||
/** @return {!string} The type of return value for the block, an integer. */
|
||||
|
@ -1,6 +1,5 @@
|
||||
import Blockly from 'blockly/core';
|
||||
|
||||
|
||||
import { getColour } from '../helpers/colour';
|
||||
|
||||
|
||||
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);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
let variableName = this.getField('COLOR');
|
||||
console.log(variableName.getValue());
|
||||
this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip);
|
||||
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)
|
||||
.appendField(Blockly.Msg.senseBox_value)
|
||||
.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.setTooltip(Blockly.Msg.senseBox_temp_hum_tip);
|
||||
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)
|
||||
.appendField(Blockly.Msg.senseBox_value)
|
||||
.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.setTooltip(Blockly.Msg.senseBox_uv_light_tip);
|
||||
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)
|
||||
.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");
|
||||
this.setOutput(true, Types.NUMBER.typeId);
|
||||
this.setOutput(true, Types.DECIMAL.typeName);
|
||||
this.setColour(getColour().sensebox);
|
||||
this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tip);
|
||||
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(Blockly.Msg.senseBox_sds011_dimension)
|
||||
.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.setTooltip(Blockly.Msg.senseBox_sds011_tip);
|
||||
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(dropdown, "NAME");
|
||||
this.setColour(getColour().sensebox);
|
||||
this.setOutput(true, Types.NUMBER.typeId);
|
||||
this.setOutput(true, Types.DECIMAL.typeName);
|
||||
this.setTooltip(Blockly.Msg.senseBox_pressure_tip);
|
||||
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) {
|
||||
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)
|
||||
.appendField(Blockly.Msg.senseBox_value)
|
||||
.appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown")
|
||||
this.setOutput(true, Types.NUMBER.typeId);
|
||||
this.setOutput(true, Types.DECIMAL.typeName);
|
||||
this.setColour(getColour().sensebox);
|
||||
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(new Blockly.FieldDropdown(
|
||||
selectedBoard().digitalPins), 'ultrasonic_echo');
|
||||
this.setOutput(true, Types.NUMBER.typeId);
|
||||
this.setOutput(true, Types.NUMBER.typeName);
|
||||
this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tip);
|
||||
this.setHelpUrl('https://sensebox.de/books');
|
||||
},
|
||||
@ -280,10 +257,6 @@ Blockly.Blocks['sensebox_sensor_ultrasonic_ranger'] = {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
getBlockType: function () {
|
||||
return Blockly.Types.NUMBER;
|
||||
}
|
||||
};
|
||||
|
||||
@ -300,13 +273,10 @@ Blockly.Blocks['sensebox_sensor_sound'] = {
|
||||
.appendField(Blockly.Msg.senseBox_sound)
|
||||
.appendField("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.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-lora';
|
||||
import './sensebox-led';
|
||||
import './sensebox-sd';
|
||||
import './logic';
|
||||
import './text';
|
||||
import './math';
|
||||
import './map';
|
||||
import './io';
|
||||
import './audio';
|
||||
import './procedures';
|
||||
import './time';
|
||||
import './variables';
|
||||
|
||||
|
||||
|
@ -86,7 +86,37 @@ Blockly.Arduino['controls_if'] = function (Block) {
|
||||
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) {
|
||||
// Negation.
|
||||
@ -95,3 +125,30 @@ Blockly.Arduino['logic_negate'] = function (Block) {
|
||||
const code = '!' + argument0;
|
||||
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');
|
||||
branch = Blockly['Arduino'].addLoopTrap(branch, Block.id);
|
||||
let code = '';
|
||||
const loopVar = 'simple_loop_variable';
|
||||
const loopVar = 'i';
|
||||
code +=
|
||||
'for (' +
|
||||
'for (int ' +
|
||||
loopVar +
|
||||
' = 1; ' +
|
||||
loopVar +
|
||||
@ -36,6 +36,8 @@ Blockly['Arduino']['controls_for'] = function (Block) {
|
||||
Block.getFieldValue('VAR')
|
||||
).name;
|
||||
|
||||
|
||||
|
||||
const branch = Blockly['Arduino'].statementToCode(Block, 'DO');
|
||||
|
||||
const startNumber =
|
||||
|
@ -19,9 +19,9 @@ Blockly.Arduino['arduino_functions'] = function (block) {
|
||||
}
|
||||
|
||||
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) {
|
||||
Blockly.Arduino.setupCode_('userSetupCode', setupBranch, true);
|
||||
Blockly.Arduino.setupCode_['mainsetup'] = setupBranch;
|
||||
}
|
||||
|
||||
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);`
|
||||
|
||||
let code = 'testcode';
|
||||
let 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,
|
||||
procedures: 290,
|
||||
time: 140,
|
||||
text: 160,
|
||||
variables: 330,
|
||||
audio: 250,
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,57 +12,54 @@
|
||||
/** Single character. */
|
||||
export const CHARACTER = {
|
||||
typeId: 'Character',
|
||||
typeName: 'char',
|
||||
typeMsgName: 'ARD_TYPE_CHAR',
|
||||
compatibleTypes: []
|
||||
}
|
||||
|
||||
export const BOOLEAN = {
|
||||
typeId: 'Boolean',
|
||||
typeMsgName: 'ARD_TYPE_BOOL',
|
||||
compatibleTypes: ['Boolean']
|
||||
}
|
||||
|
||||
/** Text string. */
|
||||
export const TEXT = {
|
||||
typeId: 'Text',
|
||||
typeName: 'String',
|
||||
typeMsgName: 'ARD_TYPE_TEXT',
|
||||
compatibleTypes: []
|
||||
}
|
||||
|
||||
/** Short integer number. */
|
||||
export const SHORT_NUMBER = {
|
||||
typeId: 'Short Number',
|
||||
typeId: 'Short_Number',
|
||||
typeName: 'int',
|
||||
typeMsgName: 'ARD_TYPE_SHORT',
|
||||
compatibleTypes: [] // Circular dependencies, add after all declarations
|
||||
}
|
||||
|
||||
/** Integer number. */
|
||||
export const NUMBER = {
|
||||
typeId: 'Number',
|
||||
typeName: 'int',
|
||||
typeMsgName: 'ARD_TYPE_NUMBER',
|
||||
compatibleTypes: ['Number'] // Circular dependencies, add after all declarations
|
||||
}
|
||||
|
||||
/** Large integer number. */
|
||||
export const LARGE_NUMBER = {
|
||||
typeId: 'Large Number',
|
||||
typeName: 'long',
|
||||
typeMsgName: 'ARD_TYPE_LONG',
|
||||
compatibleTypes: [] // Circular dependencies, add after all declarations
|
||||
}
|
||||
|
||||
/** Decimal/floating point number. */
|
||||
export const DECIMAL = {
|
||||
typeId: 'Decimal',
|
||||
typeName: 'float',
|
||||
typeMsgName: 'ARD_TYPE_DECIMAL',
|
||||
compatibleTypes: [BOOLEAN.typeId,
|
||||
NUMBER,
|
||||
SHORT_NUMBER,
|
||||
LARGE_NUMBER]
|
||||
}
|
||||
|
||||
/** Array/List of items. */
|
||||
export const ARRAY = {
|
||||
typeId: 'Array',
|
||||
typeName: 'array',
|
||||
typeMsgName: 'ARD_TYPE_ARRAY',
|
||||
compatibleTypes: []
|
||||
}
|
||||
@ -70,15 +67,15 @@ export const ARRAY = {
|
||||
/** Null indicate there is no type. */
|
||||
export const NULL = {
|
||||
typeId: 'Null',
|
||||
typeName: 'void',
|
||||
typeMsgName: 'ARD_TYPE_NULL',
|
||||
compatibleTypes: []
|
||||
}
|
||||
|
||||
/** Type not defined, or not yet defined. */
|
||||
export const UNDEF = {
|
||||
typeId: 'Undefined',
|
||||
typeName: 'undef',
|
||||
typeMsgName: 'ARD_TYPE_UNDEF',
|
||||
compatibleTypes: []
|
||||
}
|
||||
|
||||
/** Set when no child block (meant to define the variable type) is connected. */
|
||||
@ -88,6 +85,24 @@ export const CHILD_BLOCK_MISSING = {
|
||||
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
|
||||
// * after declaration.
|
||||
|
@ -3,169 +3,202 @@ import { Block, Value, Field, Shadow, Category } from '../';
|
||||
import { getColour } from '../helpers/colour'
|
||||
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 {
|
||||
|
||||
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() {
|
||||
return (
|
||||
<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}>
|
||||
<Block type="sensebox_sensor_temp_hum" />
|
||||
<Block type="sensebox_sensor_uv_light" />
|
||||
<Block type="sensebox_sensor_bmx055_accelerometer" />
|
||||
<Block type="sensebox_sensor_sds011" />
|
||||
<Block type="sensebox_sensor_pressure" />
|
||||
<Block type="sensebox_sensor_bme680_bsec" />
|
||||
<Block type="sensebox_sensor_ultrasonic_ranger" />
|
||||
<Block type="sensebox_sensor_sound" />
|
||||
</Category >
|
||||
<Category name="WIFI" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_wifi" />
|
||||
<Block type="sensebox_startap" />
|
||||
<Category name="Sensoren" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_sensor_temp_hum" />
|
||||
<Block type="sensebox_sensor_uv_light" />
|
||||
<Block type="sensebox_sensor_bmx055_accelerometer" />
|
||||
<Block type="sensebox_sensor_sds011" />
|
||||
<Block type="sensebox_sensor_pressure" />
|
||||
<Block type="sensebox_sensor_bme680_bsec" />
|
||||
<Block type="sensebox_sensor_ultrasonic_ranger" />
|
||||
<Block type="sensebox_sensor_sound" />
|
||||
</Category >
|
||||
<Category name="WIFI" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_wifi" />
|
||||
<Block type="sensebox_startap" />
|
||||
</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}>
|
||||
<Block type="sensebox_rgb_led" />
|
||||
<Block type="sensebox_led" />
|
||||
</Category>
|
||||
<Category name="Display" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_display_beginDisplay" />
|
||||
<Block type="sensebox_display_show" />
|
||||
<Block type="sensebox_display_clearDisplay" />
|
||||
<Block type="sensebox_display_printDisplay">
|
||||
<Value name="SIZE">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">1</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="X">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="Y">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="sensebox_display_plotDisplay">
|
||||
<Value name="Title">
|
||||
<Block type="text">
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="YLabel">
|
||||
<Block type="text">
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="XLabel">
|
||||
<Block type="text">
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="XRange1">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="XRange2">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">15</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="YRange1">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="YRange2">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">50</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="XTick">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">5</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="YTick">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="TimeFrame">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">15</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="sensebox_display_fillCircle">
|
||||
<Value name="X">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="Y">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="Radius">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="sensebox_display_drawRectangle">
|
||||
<Value name="X">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="Y">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="height">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="width">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
</Category>
|
||||
<Category name="Telegram" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_telegram" />
|
||||
<Block type="sensebox_telegram_do" />
|
||||
<Block type="sensebox_telegram_do_on_message" />
|
||||
<Block type="sensebox_telegram_send" />
|
||||
</Category>
|
||||
<Category name="openSenseMap" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_osem_connection" />
|
||||
<Block type="sensebox_send_to_osem" />
|
||||
</Category>
|
||||
<Category id="catSenseBoxOutput_LoRa" name=" LoRa" colour={getColour().sensebox}>
|
||||
<Category id="catSenseBoxOutput_LoRa_activation" name=" Activation" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_lora_initialize_otaa" />
|
||||
<Block type="sensebox_lora_initialize_abp" />
|
||||
</Category>
|
||||
<Category name="LED" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_rgb_led" />
|
||||
<Block type="sensebox_led" />
|
||||
<Category id="catSenseBoxOutput_LoRa_loramessage" name=" Lora Message" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_lora_message_send" />
|
||||
<Block type="sensebox_send_lora_sensor_value" />
|
||||
</Category>
|
||||
<Category name="Display" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_display_beginDisplay" />
|
||||
<Block type="sensebox_display_show" />
|
||||
<Block type="sensebox_display_clearDisplay" />
|
||||
<Block type="sensebox_display_printDisplay">
|
||||
<Value name="SIZE">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">1</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="X">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="Y">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="sensebox_display_plotDisplay">
|
||||
<Value name="Title">
|
||||
<Block type="text">
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="YLabel">
|
||||
<Block type="text">
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="XLabel">
|
||||
<Block type="text">
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="XRange1">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="XRange2">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">15</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="YRange1">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="YRange2">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">50</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="XTick">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">5</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="YTick">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="TimeFrame">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">15</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="sensebox_display_fillCircle">
|
||||
<Value name="X">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="Y">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="Radius">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="sensebox_display_drawRectangle">
|
||||
<Value name="X">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="Y">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="height">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="width">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">0</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
</Category>
|
||||
<Category name="Telegram" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_telegram" />
|
||||
<Block type="sensebox_telegram_do" />
|
||||
<Block type="sensebox_telegram_do_on_message" />
|
||||
<Block type="sensebox_telegram_send" />
|
||||
</Category>
|
||||
<Category name="osem" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_osem_connection" />
|
||||
</Category>
|
||||
<Category id="catSenseBoxOutput_LoRa" name=" LoRa" colour={getColour().sensebox}>
|
||||
<Category id="catSenseBoxOutput_LoRa_activation" name=" Activation" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_lora_initialize_otaa" />
|
||||
<Block type="sensebox_lora_initialize_abp" />
|
||||
</Category>
|
||||
<Category id="catSenseBoxOutput_LoRa_loramessage" name=" Lora Message" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_lora_message_send" />
|
||||
<Block type="sensebox_send_lora_sensor_value" />
|
||||
</Category>
|
||||
<Category id="catSenseBoxOutput_LoRa_cayenne" name=" Cayenne LPP" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_lora_cayenne_send" />
|
||||
<Block type="sensebox_lora_cayenne_temperature" />
|
||||
<Block type="sensebox_lora_cayenne_humidity" />
|
||||
<Block type="sensebox_lora_cayenne_pressure" />
|
||||
<Block type="sensebox_lora_cayenne_luminosity" />
|
||||
<Block type="sensebox_lora_cayenne_sensor" />
|
||||
<Block type="sensebox_lora_cayenne_accelerometer" />
|
||||
<Block type="sensebox_lora_cayenne_gps" />
|
||||
</Category>
|
||||
<Category id="catSenseBoxOutput_LoRa_cayenne" name=" Cayenne LPP" colour={getColour().sensebox}>
|
||||
<Block type="sensebox_lora_cayenne_send" />
|
||||
<Block type="sensebox_lora_cayenne_temperature" />
|
||||
<Block type="sensebox_lora_cayenne_humidity" />
|
||||
<Block type="sensebox_lora_cayenne_pressure" />
|
||||
<Block type="sensebox_lora_cayenne_luminosity" />
|
||||
<Block type="sensebox_lora_cayenne_sensor" />
|
||||
<Block type="sensebox_lora_cayenne_accelerometer" />
|
||||
<Block type="sensebox_lora_cayenne_gps" />
|
||||
</Category>
|
||||
</Category>
|
||||
<Category name="Logic" colour={getColour().logic}>
|
||||
@ -175,6 +208,7 @@ class Toolbox extends React.Component {
|
||||
<Block type="logic_operation" />
|
||||
<Block type="logic_negate" />
|
||||
<Block type="logic_boolean" />
|
||||
<Block type="switch_case" />
|
||||
</Category>
|
||||
<Category id="loops" name="Loops" colour={getColour().loops}>
|
||||
<Block type="controls_repeat_ext">
|
||||
@ -204,6 +238,17 @@ class Toolbox extends React.Component {
|
||||
</Block>
|
||||
<Block type="controls_flow_statements" />
|
||||
</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}>
|
||||
<Block type="time_delay">
|
||||
<Value name="DELAY_TIME_MILI">
|
||||
@ -267,6 +312,17 @@ class Toolbox extends React.Component {
|
||||
<Block type="math_random_float"></Block>
|
||||
<Block type="base_map"></Block>
|
||||
</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>
|
||||
<Category name="Input/Output" colour={getColour().io}>
|
||||
<Block type="io_digitalwrite"></Block>
|
||||
|
@ -65,7 +65,7 @@ class Compile extends Component {
|
||||
};
|
||||
fetch(`${process.env.REACT_APP_COMPILER_URL}/compile`, {
|
||||
method: "POST",
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(response => response.json())
|
||||
@ -158,4 +158,5 @@ const mapStateToProps = state => ({
|
||||
name: state.workspace.name
|
||||
});
|
||||
|
||||
|
||||
export default connect(mapStateToProps, { workspaceName })(withStyles(styles, {withTheme: true})(Compile));
|
||||
|
Loading…
x
Reference in New Issue
Block a user