add new blocks
This commit is contained in:
parent
25134d4d86
commit
bbd14c58b5
65
src/components/Blockly/blocks/audio.js
Normal file
65
src/components/Blockly/blocks/audio.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
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.NUMBER.checkList)
|
||||||
|
.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');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** @return {!string} The type of input value for the block, an integer. */
|
||||||
|
getBlockType: function () {
|
||||||
|
return Blockly.Types.NUMBER;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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'
|
@ -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 '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 '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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -2,7 +2,6 @@ import * as Blockly from 'blockly/core';
|
|||||||
import { getColour } from '../helpers/colour';
|
import { getColour } from '../helpers/colour';
|
||||||
import * as Types from '../helpers/types'
|
import * as Types from '../helpers/types'
|
||||||
import { FieldSlider } from '@blockly/field-slider';
|
import { FieldSlider } from '@blockly/field-slider';
|
||||||
import { Field } from '..';
|
|
||||||
|
|
||||||
|
|
||||||
Blockly.Blocks['sensebox_display_beginDisplay'] = {
|
Blockly.Blocks['sensebox_display_beginDisplay'] = {
|
||||||
|
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'],
|
||||||
|
};
|
1
src/components/Blockly/blocks/text.js
Normal file
1
src/components/Blockly/blocks/text.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
167
src/components/Blockly/blocks/variables.js
Normal file
167
src/components/Blockly/blocks/variables.js
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
import Blockly from 'blockly/core';
|
||||||
|
import { getColour } from '../helpers/colour';
|
||||||
|
|
||||||
|
Blockly.defineBlocksWithJsonArray([
|
||||||
|
// BEGIN JSON EXTRACT
|
||||||
|
{
|
||||||
|
type: 'variables_get_number',
|
||||||
|
message0: '= number variable %1',
|
||||||
|
args0: [
|
||||||
|
{
|
||||||
|
type: 'field_variable',
|
||||||
|
name: 'VAR',
|
||||||
|
variable: null,
|
||||||
|
variableTypes: ['Number'],
|
||||||
|
defaultType: 'Number',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
output: 'Number',
|
||||||
|
colour: getColour().variables,
|
||||||
|
tooltip: '',
|
||||||
|
helpUrl: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'variables_set_number',
|
||||||
|
message0: 'Number variable %1 = %2',
|
||||||
|
args0: [
|
||||||
|
{
|
||||||
|
type: 'field_variable',
|
||||||
|
name: 'VAR',
|
||||||
|
variable: null,
|
||||||
|
variableTypes: ['Number'],
|
||||||
|
defaultType: 'Number',
|
||||||
|
createNewVariable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input_value',
|
||||||
|
name: 'VALUE',
|
||||||
|
check: 'Number',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
previousStatement: null,
|
||||||
|
nextStatement: null,
|
||||||
|
colour: getColour().variables,
|
||||||
|
tooltip: '',
|
||||||
|
helpUrl: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'variables_get_colour',
|
||||||
|
message0: '= color variable %1',
|
||||||
|
args0: [
|
||||||
|
{
|
||||||
|
type: 'field_variable',
|
||||||
|
name: 'VAR',
|
||||||
|
variable: null,
|
||||||
|
variableTypes: ['Colour'],
|
||||||
|
defaultType: 'Colour',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
output: 'Colour',
|
||||||
|
colour: getColour().variables,
|
||||||
|
tooltip: '',
|
||||||
|
helpUrl: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'variables_set_colour',
|
||||||
|
message0: 'Color variable %1 = %2',
|
||||||
|
args0: [
|
||||||
|
{
|
||||||
|
type: 'field_variable',
|
||||||
|
name: 'VAR',
|
||||||
|
variable: null,
|
||||||
|
variableTypes: ['Colour'],
|
||||||
|
defaultType: 'Colour',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input_value',
|
||||||
|
name: 'VALUE',
|
||||||
|
check: 'Colour',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
previousStatement: null,
|
||||||
|
nextStatement: null,
|
||||||
|
colour: getColour().variables,
|
||||||
|
tooltip: '',
|
||||||
|
helpUrl: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'variables_get_string',
|
||||||
|
message0: '= text variable %1',
|
||||||
|
args0: [
|
||||||
|
{
|
||||||
|
type: 'field_variable',
|
||||||
|
name: 'VAR',
|
||||||
|
variable: null,
|
||||||
|
variableTypes: ['String'],
|
||||||
|
defaultType: 'String',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
output: 'String',
|
||||||
|
colour: getColour().variables,
|
||||||
|
tooltip: '',
|
||||||
|
helpUrl: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'variables_set_string',
|
||||||
|
message0: 'Text variable %1 = %2',
|
||||||
|
args0: [
|
||||||
|
{
|
||||||
|
type: 'field_variable',
|
||||||
|
name: 'VAR',
|
||||||
|
variable: null,
|
||||||
|
variableTypes: ['String'],
|
||||||
|
defaultType: 'String',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input_value',
|
||||||
|
name: 'VALUE',
|
||||||
|
check: 'String',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
previousStatement: null,
|
||||||
|
nextStatement: null,
|
||||||
|
colour: getColour().variables,
|
||||||
|
tooltip: '',
|
||||||
|
helpUrl: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'variables_get_boolean',
|
||||||
|
message0: '= boolean variable %1',
|
||||||
|
args0: [
|
||||||
|
{
|
||||||
|
type: 'field_variable',
|
||||||
|
name: 'VAR',
|
||||||
|
variable: null,
|
||||||
|
variableTypes: ['Boolean'],
|
||||||
|
defaultType: 'Boolean',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
output: 'Boolean',
|
||||||
|
colour: getColour().variables,
|
||||||
|
tooltip: '',
|
||||||
|
helpUrl: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'variables_set_boolean',
|
||||||
|
message0: 'Boolean variable %1 = %2',
|
||||||
|
args0: [
|
||||||
|
{
|
||||||
|
type: 'field_variable',
|
||||||
|
name: 'VAR',
|
||||||
|
variable: null,
|
||||||
|
variableTypes: ['Boolean'],
|
||||||
|
defaultType: 'Boolean',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input_value',
|
||||||
|
name: 'VALUE',
|
||||||
|
check: 'Boolean',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
previousStatement: null,
|
||||||
|
nextStatement: null,
|
||||||
|
colour: getColour().variables,
|
||||||
|
tooltip: '',
|
||||||
|
helpUrl: '',
|
||||||
|
},
|
||||||
|
]); // END JSON EXTRACT (Do not delete this comment.)
|
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++) {
|
||||||
|
var DO = Blockly.Arduino.statementToCode(block, ('CASE' + n));
|
||||||
|
var branch = Blockly.Arduino.valueToCode(block, ('CASECONDITION' + n), Blockly.Arduino.ORDER_NONE) || '0';
|
||||||
|
cases += 'case ' + branch + ':\n';
|
||||||
|
cases += DO + '\nbreak;\n';
|
||||||
|
}
|
||||||
|
if (block.defaultCount_) {
|
||||||
|
var 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';
|
||||||
|
};
|
||||||
|
|
||||||
|
53
src/components/Blockly/generator/sensebox-sd.js
Normal file
53
src/components/Blockly/generator/sensebox-sd.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
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_' + filename] = '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) {
|
||||||
|
var res = filename.slice(0, 4);
|
||||||
|
if (this.parentBlock_ != null) {
|
||||||
|
var filename = this.getSurroundParent().getFieldValue('Filename');
|
||||||
|
}
|
||||||
|
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 = "";
|
||||||
|
}
|
||||||
|
if (text == "gps.getLongitude()" || text == "gps.getLatitude()") {
|
||||||
|
var code = 'dataFile' + res + '.print' + linebreak + '(' + text + ',5);\n'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var code = 'dataFile' + res + '.print' + linebreak + '(' + text + ');\n'
|
||||||
|
}
|
||||||
|
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];
|
||||||
|
};
|
||||||
|
|
38
src/components/Blockly/generator/variables.js
Normal file
38
src/components/Blockly/generator/variables.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
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_number'] = setVariableFunction(10);
|
||||||
|
Blockly['Arduino']['variables_set_boolean'] = setVariableFunction('true');
|
||||||
|
Blockly['Arduino']['variables_set_string'] = setVariableFunction('" "');
|
||||||
|
Blockly['Arduino']['variables_set_colour'] = setVariableFunction(
|
||||||
|
`{ 22, 0, 22}`
|
||||||
|
);
|
||||||
|
|
||||||
|
Blockly['Arduino']['variables_get_number'] = getVariableFunction;
|
||||||
|
Blockly['Arduino']['variables_get_boolean'] = getVariableFunction;
|
||||||
|
Blockly['Arduino']['variables_get_string'] = getVariableFunction;
|
||||||
|
Blockly['Arduino']['variables_get_colour'] = 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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,6 +88,9 @@ export const CHILD_BLOCK_MISSING = {
|
|||||||
compatibleTypes: []
|
compatibleTypes: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const VARIABLE_TYPES = ['Number', 'String', 'Boolean', 'Colour'];
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * 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.
|
||||||
|
@ -24,6 +24,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" />
|
||||||
@ -175,6 +180,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 +210,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 +284,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="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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user