diff --git a/src/components/Blockly/BlocklyComponent.jsx b/src/components/Blockly/BlocklyComponent.jsx index b025821..9e68f5a 100644 --- a/src/components/Blockly/BlocklyComponent.jsx +++ b/src/components/Blockly/BlocklyComponent.jsx @@ -24,22 +24,20 @@ import React from 'react'; import Blockly from 'blockly/core'; -import locale from 'blockly/msg/en'; import 'blockly/blocks'; import Toolbox from './toolbox/Toolbox'; 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}; + this.state = { workspace: undefined }; } componentDidMount() { @@ -51,7 +49,7 @@ class BlocklyComponent extends React.Component { ...rest }, ); - this.setState({workspace: this.primaryWorkspace}) + this.setState({ workspace: this.primaryWorkspace }) if (initialXml) { Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(initialXml), this.primaryWorkspace); @@ -68,7 +66,7 @@ class BlocklyComponent extends React.Component { render() { return - + ; } diff --git a/src/components/Blockly/BlocklyWindow.js b/src/components/Blockly/BlocklyWindow.js index 15ec6d1..f3c680d 100644 --- a/src/components/Blockly/BlocklyWindow.js +++ b/src/components/Blockly/BlocklyWindow.js @@ -2,7 +2,8 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { onChangeWorkspace, clearStats } from '../../actions/workspaceActions'; -import * as De from './msg/de'; +import { De } from './msg/de'; +import { En } from './msg/en'; import BlocklyComponent from './BlocklyComponent'; import BlocklySvg from './BlocklySvg'; import * as Blockly from 'blockly/core'; @@ -17,10 +18,26 @@ class BlocklyWindow extends Component { constructor(props) { super(props); this.simpleWorkspace = React.createRef(); - Blockly.setLocale(De); + var locale = window.localStorage.getItem('locale'); + this.state = { + renderer: window.localStorage.getItem('renderer'), + }; + if (locale === null) { + if (navigator.language === 'de-DE') { + locale = 'de'; + } else { + locale = 'en'; + } + } + if (locale === 'de') { + Blockly.setLocale(De); + } else if (locale === 'en') { + Blockly.setLocale(En); + } } componentDidMount() { + const workspace = Blockly.getMainWorkspace(); this.props.onChangeWorkspace({}); this.props.clearStats(); @@ -55,7 +72,7 @@ class BlocklyWindow extends Component { 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='geras' + renderer={this.state.renderer} zoom={{ // https://developers.google.com/blockly/guides/configure/web/zoom controls: this.props.zoomControls !== undefined ? this.props.zoomControls : true, wheel: false, diff --git a/src/components/Blockly/blocks/index.js b/src/components/Blockly/blocks/index.js index 5ba7a02..7eeae60 100644 --- a/src/components/Blockly/blocks/index.js +++ b/src/components/Blockly/blocks/index.js @@ -17,5 +17,6 @@ import './map'; import './procedures'; import './time'; import './variables'; +import './lists'; import '../helpers/types' \ No newline at end of file diff --git a/src/components/Blockly/blocks/lists.js b/src/components/Blockly/blocks/lists.js new file mode 100644 index 0000000..2d33472 --- /dev/null +++ b/src/components/Blockly/blocks/lists.js @@ -0,0 +1,60 @@ +import Blockly, { FieldDropdown } from 'blockly/core'; +import { selectedBoard } from '../helpers/board' +import * as Types from '../helpers/types' +import { getColour } from '../helpers/colour'; + +Blockly.Blocks['lists_create_empty'] = { + /** + * Elapsed time in milliseconds block definition + * @this Blockly.Block + */ + init: function () { + this.setHelpUrl('http://arduino.cc/en/Reference/Millis'); + this.setColour(getColour().arrays); + this.appendDummyInput() + .appendField("create List with") + this.appendValueInput('NUMBER'); + this.appendDummyInput() + .appendField("Items of Type") + .appendField(new FieldDropdown(Types.VARIABLE_TYPES), 'type'); + this.setOutput(true, Types.ARRAY.typeId); + this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); + }, +}; + + +Blockly.Blocks['array_getIndex'] = { + /** + * Elapsed time in milliseconds block definition + * @this Blockly.Block + */ + init: function () { + this.setHelpUrl('http://arduino.cc/en/Reference/Millis'); + this.setColour(getColour().arrays); + this.appendDummyInput() + .appendField(new Blockly.FieldVariable( + 'X', + null, + ['Array'], + 'Array' + ), 'FIELDNAME'); + this.setOutput(true, Types.ARRAY.typeId); + this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); + }, +}; + +Blockly.Blocks['lists_length'] = { + /** + * Elapsed time in milliseconds block definition + * @this Blockly.Block + */ + init: function () { + this.setHelpUrl('http://arduino.cc/en/Reference/Millis'); + this.setColour(getColour().arrays); + this.appendValueInput('ARRAY') + .appendField('length of') + .setCheck(Types.ARRAY.compatibleTypes); + this.setOutput(true, Types.NUMBER.typeName); + this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); + }, +}; \ No newline at end of file diff --git a/src/components/Blockly/blocks/sensebox-display.js b/src/components/Blockly/blocks/sensebox-display.js index d9824d9..8092bff 100644 --- a/src/components/Blockly/blocks/sensebox-display.js +++ b/src/components/Blockly/blocks/sensebox-display.js @@ -81,6 +81,54 @@ Blockly.Blocks['sensebox_display_printDisplay'] = { LOOP_TYPES: ['sensebox_display_show'], }; +Blockly.Blocks['sensebox_display_fastPrint'] = { + init: function (block) { + this.setColour(getColour().sensebox); + this.appendDummyInput() + .appendField(Blockly.Msg.senseBox_display_fastPrint_show); + this.appendValueInput("Title1", 'Title1') + .appendField(Blockly.Msg.senseBox_display_fastPrint_title); + this.appendValueInput("Value1", 'Value1') + .appendField(Blockly.Msg.senseBox_display_fastPrint_value); + this.appendValueInput("Dimension1", 'Dimension1') + .appendField(Blockly.Msg.senseBox_display_fastPrint_dimension); + this.appendValueInput("Title2", 'Title2') + .appendField(Blockly.Msg.senseBox_display_fastPrint_title); + this.appendValueInput("Value2", 'Value2') + .appendField(Blockly.Msg.senseBox_display_fastPrint_value); + this.appendValueInput("Dimension2", 'Dimension2') + .appendField(Blockly.Msg.senseBox_display_fastPrint_dimension); + this.setPreviousStatement(true, null); + this.setNextStatement(true, null); + this.setTooltip(Blockly.Msg.sensebox_display_fastPrint_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_display_show'], +}; + Blockly.Blocks['sensebox_display_plotDisplay'] = { init: function () { diff --git a/src/components/Blockly/generator/index.js b/src/components/Blockly/generator/index.js index fd2c108..afe28a7 100644 --- a/src/components/Blockly/generator/index.js +++ b/src/components/Blockly/generator/index.js @@ -17,5 +17,6 @@ import './audio'; import './procedures'; import './time'; import './variables'; +import './lists'; diff --git a/src/components/Blockly/generator/lists.js b/src/components/Blockly/generator/lists.js new file mode 100644 index 0000000..7902920 --- /dev/null +++ b/src/components/Blockly/generator/lists.js @@ -0,0 +1,19 @@ +import * as Blockly from 'blockly/core'; + + +Blockly.Arduino['lists_create_empty'] = function () { + var code = ''; + return [code, Blockly.Arduino.ORDER_ATOMIC]; +} + +Blockly.Arduino['array_getIndex'] = function () { + var code = ''; + return [code, Blockly.Arduino.ORDER_ATOMIC]; +} + + +Blockly.Arduino['lists_length'] = function () { + var array = Blockly.Arduino.valueToCode(this, 'ARRAY', Blockly.Arduino.ORDER_ATOMIC); + var code = `${array}.length`; + return [code, Blockly.Arduino.ORDER_ATOMIC]; +} \ No newline at end of file diff --git a/src/components/Blockly/generator/sensebox-display.js b/src/components/Blockly/generator/sensebox-display.js index 17f8542..5fbc114 100644 --- a/src/components/Blockly/generator/sensebox-display.js +++ b/src/components/Blockly/generator/sensebox-display.js @@ -31,6 +31,42 @@ Blockly.Arduino.sensebox_display_printDisplay = function () { return code; }; + +Blockly.Arduino.sensebox_display_fastPrint = function () { + var title1 = Blockly.Arduino.valueToCode(this, 'Title1', Blockly.Arduino.ORDER_ATOMIC) || '0' + var value1 = Blockly.Arduino.valueToCode(this, 'Value1', Blockly.Arduino.ORDER_ATOMIC); + var dimension1 = Blockly.Arduino.valueToCode(this, 'Dimension1', Blockly.Arduino.ORDER_ATOMIC) || '0' + var title2 = Blockly.Arduino.valueToCode(this, 'Title2', Blockly.Arduino.ORDER_ATOMIC) || '0' + var value2 = Blockly.Arduino.valueToCode(this, 'Value2', Blockly.Arduino.ORDER_ATOMIC); + var dimension2 = Blockly.Arduino.valueToCode(this, 'Dimension2', Blockly.Arduino.ORDER_ATOMIC) || '0' + Blockly.Arduino.codeFunctions_['sensebox_fastPrint'] = ` + void printOnDisplay(String title1, String measurement1, String unit1, String title2, String measurement2, String unit2) { + + display.setCursor(0, 0); + display.setTextSize(1); + display.setTextColor(WHITE, BLACK); + display.println(title1); + display.setCursor(0, 10); + display.setTextSize(2); + display.print(measurement1); + display.print(" "); + display.setTextSize(1); + display.println(unit1); + display.setCursor(0, 30); + display.setTextSize(1); + display.println(title2); + display.setCursor(0, 40); + display.setTextSize(2); + display.print(measurement2); + display.print(" "); + display.setTextSize(1); + display.println(unit2); + } + ` + var code = ` printOnDisplay(${title1}, String(${value1}), ${dimension1}, ${title2}, String(${value2}), ${dimension2});\n`; + return code; +}; + Blockly.Arduino.sensebox_display_show = function (block) { var show = Blockly.Arduino.statementToCode(block, 'SHOW'); var code = ''; diff --git a/src/components/Blockly/generator/variables.js b/src/components/Blockly/generator/variables.js index c0733d5..8ef80ae 100644 --- a/src/components/Blockly/generator/variables.js +++ b/src/components/Blockly/generator/variables.js @@ -14,9 +14,28 @@ const setVariableFunction = function (defaultValue) { const allVars = Blockly.getMainWorkspace().getVariableMap().getAllVariables(); const myVar = allVars.filter(v => v.name === variableName)[0] + var code = '' - Blockly.Arduino.variables_[myVar + myVar.type] = myVar.type + " " + myVar.name + ';\n'; - return variableName + ' = ' + (variableValue || defaultValue) + ';\n'; + switch (myVar.type) { + default: + Blockly.Arduino.variables_[myVar + myVar.type] = myVar.type + " " + myVar.name + ';\n'; + code = variableName + ' = ' + (variableValue || defaultValue) + ';\n'; + break; + case 'Array': + var arrayType; + var number; + + if (this.getChildren().length > 0) { + if (this.getChildren()[0].type === 'lists_create_empty') { + + arrayType = this.getChildren()[0].getFieldValue('type'); + number = Blockly.Arduino.valueToCode(this.getChildren()[0], 'NUMBER', Blockly['Arduino'].ORDER_ATOMIC); + Blockly.Arduino.variables_[myVar + myVar.type] = `${arrayType} ${myVar.name} [${number}];\n`; + } + } + break; + } + return code; }; }; @@ -25,8 +44,8 @@ const getVariableFunction = function (block) { block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE ); - - return [variableName, Blockly['Arduino'].ORDER_ATOMIC]; + var code = variableName; + return [code, Blockly['Arduino'].ORDER_ATOMIC]; }; Blockly['Arduino']['variables_set_dynamic'] = setVariableFunction() diff --git a/src/components/Blockly/helpers/colour.js b/src/components/Blockly/helpers/colour.js index 7aea8df..e807695 100644 --- a/src/components/Blockly/helpers/colour.js +++ b/src/components/Blockly/helpers/colour.js @@ -10,6 +10,7 @@ const colours = { text: 160, variables: 330, audio: 250, + arrays: 33 } diff --git a/src/components/Blockly/helpers/types.js b/src/components/Blockly/helpers/types.js index 9abdd85..f7cacc7 100644 --- a/src/components/Blockly/helpers/types.js +++ b/src/components/Blockly/helpers/types.js @@ -60,7 +60,7 @@ export const DECIMAL = { /** Array/List of items. */ export const ARRAY = { typeId: 'Array', - typeName: 'array', + typeName: 'Array', typeMsgName: 'ARD_TYPE_ARRAY', compatibleTypes: [] } @@ -87,6 +87,7 @@ export const CHILD_BLOCK_MISSING = { } const compatibleTypes = { + Array: ['Array'], boolean: ['boolean'], int: ['int'], char: ['char'], diff --git a/src/components/Blockly/msg/de.js b/src/components/Blockly/msg/de.js index cf6db85..9d019c9 100644 --- a/src/components/Blockly/msg/de.js +++ b/src/components/Blockly/msg/de.js @@ -1,5 +1,5 @@ - -import * as Blockly from 'blockly/core'; +const Blockly = {}; +Blockly.Msg = {}; Blockly.Msg.ADD_COMMENT = "Kommentar hinzufügen"; Blockly.Msg.AUTH = "Bitte autorisiere diese App zum Aktivieren der Speicherung deiner Arbeit und zum Teilen."; @@ -646,7 +646,11 @@ Blockly.Msg.sensebox_display_fillCircle_radius = "Radius"; Blockly.Msg.sensebox_display_drawRectangle = "Zeichne Rechteck"; Blockly.Msg.sensebox_display_drawRectangle_width = "Breite"; Blockly.Msg.sensebox_display_drawRectangle_height = "Höhe"; -Blockly.Msg.senseBox_display_filled = "Ausgefüllt" +Blockly.Msg.senseBox_display_filled = "Ausgefüllt"; +Blockly.Msg.senseBox_display_fastPrint_show = "Zeige Messwerte"; +Blockly.Msg.senseBox_display_fastPrint_title = "Titel"; +Blockly.Msg.senseBox_display_fastPrint_value = "Messwert"; +Blockly.Msg.senseBox_display_fastPrint_dimension = "Einheit"; // GPS Blockly.Msg.senseBox_gps_getValues = "GPS Modul"; Blockly.Msg.senseBox_gps_getValues_tip = "ruft das GPS Signal ab"; @@ -770,3 +774,6 @@ Blockly.Msg.senseBox_telegram_send = "Sende Nachricht" Blockly.Msg.senseBox_scd30 = "CO2 Sensor (Sensirion SCD30)"; + + +export const De = Blockly.Msg; \ No newline at end of file diff --git a/src/components/Blockly/msg/en.js b/src/components/Blockly/msg/en.js index e32e321..7474b93 100644 --- a/src/components/Blockly/msg/en.js +++ b/src/components/Blockly/msg/en.js @@ -1,5 +1,5 @@ - -import * as Blockly from 'blockly/core'; +const Blockly = {}; +Blockly.Msg = {}; Blockly.Msg.ADD_COMMENT = "Add Comment"; Blockly.Msg.AUTH = "Please authorize this app to enable your work to be saved and to allow it to be shared by you."; @@ -609,6 +609,11 @@ Blockly.Msg.senseBox_display_printDisplay_y = "y-coordinates"; Blockly.Msg.senseBox_display_setSize = "set font size to"; Blockly.Msg.senseBox_display_setSize_tip = "Change the font size. Set a Value between 1-10."; Blockly.Msg.senseBox_display_white = "White"; +Blockly.Msg.senseBox_display_fastPrint_dimension = "Unit"; +Blockly.Msg.senseBox_display_fastPrint_show = "Show Measurements"; +Blockly.Msg.senseBox_display_fastPrint_tip = "Show two measurements with title and dimension on the display"; +Blockly.Msg.senseBox_display_fastPrint_title = "Title"; +Blockly.Msg.senseBox_display_fastPrint_value = "Measurement"; Blockly.Msg.senseBox_foto = "Light Dependent Resistor"; Blockly.Msg.senseBox_foto_tip = "simple light depending resistor, gives values between 0 and 1023"; Blockly.Msg.senseBox_gas = "Gas (VOC)"; @@ -750,4 +755,6 @@ Blockly.Msg.sensebox_sd_filename = "data"; Blockly.Msg.sensebox_soil_smt50 = "Soil Moisture and Temperature (SMT50)"; Blockly.Msg.sensebox_web_readHTML_filename = "File:"; -Blockly.Msg.senseBox_scd30 = "CO2 Sensor (Sensirion SCD30)"; \ No newline at end of file +Blockly.Msg.senseBox_scd30 = "CO2 Sensor (Sensirion SCD30)"; + +export const En = Blockly.Msg; \ No newline at end of file diff --git a/src/components/Blockly/toolbox/Toolbox.js b/src/components/Blockly/toolbox/Toolbox.js index 3cfae6e..fa9a822 100644 --- a/src/components/Blockly/toolbox/Toolbox.js +++ b/src/components/Blockly/toolbox/Toolbox.js @@ -2,7 +2,6 @@ import React from 'react'; 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'; @@ -14,12 +13,14 @@ 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']]); + const typedVarModal = new TypedVariableModal(this.props.workspace, 'callbackName', [['SHORT_NUMBER', 'char'], ['NUMBER', 'int'], ['DECIMAL', 'float'], ['TEXT', 'String'], ['ARRAY', 'Array'], ['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'); @@ -83,6 +84,28 @@ class Toolbox extends React.Component { + + + + Title + + + + + Unit + + + + + Title + + + + + Unit + + + @@ -323,7 +346,12 @@ class Toolbox extends React.Component { - ; + + + + + + diff --git a/src/components/Gallery/GalleryHome.js b/src/components/Gallery/GalleryHome.js index 4a1a83c..6b55c1a 100644 --- a/src/components/Gallery/GalleryHome.js +++ b/src/components/Gallery/GalleryHome.js @@ -81,14 +81,20 @@ class GalleryHome extends Component {

{gallery.title}

- + + + + +

{gallery.text}

-

{gallery.name}

diff --git a/src/components/Routes.js b/src/components/Routes.js index a12ef2b..35e868a 100644 --- a/src/components/Routes.js +++ b/src/components/Routes.js @@ -11,11 +11,12 @@ import TutorialHome from './Tutorial/TutorialHome'; import Builder from './Tutorial/Builder/Builder'; import NotFound from './NotFound'; import GalleryHome from './Gallery/GalleryHome'; +import Settings from './Settings/Settings'; class Routes extends Component { - componentDidUpdate(){ + componentDidUpdate() { this.props.visitPage(); } @@ -25,6 +26,7 @@ class Routes extends Component { + diff --git a/src/components/Settings/LanguageSelector.js b/src/components/Settings/LanguageSelector.js new file mode 100644 index 0000000..dea7465 --- /dev/null +++ b/src/components/Settings/LanguageSelector.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import InputLabel from '@material-ui/core/InputLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; + +const useStyles = makeStyles((theme) => ({ + formControl: { + margin: theme.spacing(1), + minWidth: 120, + }, + selectEmpty: { + marginTop: theme.spacing(2), + }, +})); + +export default function LanguageSelector() { + const classes = useStyles(); + const [lang, setLang] = React.useState(window.localStorage.getItem('locale')); + + const handleChange = (event) => { + setLang(event.target.value); + window.localStorage.setItem('locale', event.target.value); + }; + + return ( +
+ + Sprache + + +
+ ); +} diff --git a/src/components/Settings/RenderSelector.js b/src/components/Settings/RenderSelector.js new file mode 100644 index 0000000..46ad84e --- /dev/null +++ b/src/components/Settings/RenderSelector.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import InputLabel from '@material-ui/core/InputLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; + +const useStyles = makeStyles((theme) => ({ + formControl: { + margin: theme.spacing(1), + minWidth: 400, + }, + selectEmpty: { + marginTop: theme.spacing(2), + }, +})); + +export default function LanguageSelector() { + const classes = useStyles(); + const [renderer, setRenderer] = React.useState(window.localStorage.getItem('renderer')); + + const handleChange = (event) => { + setRenderer(event.target.value); + window.localStorage.setItem('renderer', event.target.value); + }; + + return ( +
+ + Renderer + + +

Der Renderer bestimmt das aussehen der Blöcke

+
+ ); +} diff --git a/src/components/Settings/Settings.js b/src/components/Settings/Settings.js new file mode 100644 index 0000000..95b33dc --- /dev/null +++ b/src/components/Settings/Settings.js @@ -0,0 +1,30 @@ +import React, { Component } from 'react'; +import { withRouter } from 'react-router-dom'; + +import Button from '@material-ui/core/Button'; +import Typography from '@material-ui/core/Typography'; +import LanguageSelector from './LanguageSelector'; +import RenderSelector from './RenderSelector'; + + +class Settings extends Component { + render() { + return ( +
+ Einstellungen + + + +
+ ); + }; +} + +export default withRouter(Settings);