From c2405de04af76af110f98a76c47fa4e8783084f6 Mon Sep 17 00:00:00 2001 From: Delucse <46593742+Delucse@users.noreply.github.com> Date: Thu, 23 Jul 2020 15:42:01 +0200 Subject: [PATCH] adaptation of the functionalities to Blockly package --- src/actions/types.js | 3 + src/actions/workspaceActions.js | 51 +++++++++++++--- src/components/Blockly/BlocklyComponent.css | 4 +- src/components/BlocklyView.js | 68 +++++++++++++++++++++ src/components/ClearWorkspace.js | 22 ++++--- src/components/CodeViewer.js | 28 +++++++++ src/components/Home.js | 48 ++++++++++----- src/components/MaxBlocks.js | 27 ++++---- src/components/WorkspaceFunc.js | 18 +++--- src/components/WorkspaceStats.js | 31 +++++++--- src/reducers/workspaceReducer.js | 27 +++++--- 11 files changed, 254 insertions(+), 73 deletions(-) create mode 100644 src/components/BlocklyView.js create mode 100644 src/components/CodeViewer.js diff --git a/src/actions/types.js b/src/actions/types.js index 0c9a0a7..26cd445 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -1,5 +1,8 @@ +export const NEW_CODE = 'NEW_CODE'; +export const CHANGE_WORKSPACE = 'CHANGE_WORKSPACE'; export const NEW_WORKSPACE = 'NEW_WORKSPACE'; export const CREATE_BLOCK = 'CREATE_BLOCK'; +export const MOVE_BLOCK = 'MOVE_BLOCK'; export const CHANGE_BLOCK = 'CHANGE_BLOCK'; export const DELETE_BLOCK = 'DELETE_BLOCK'; export const CLEAR_STATS = 'CLEAR_STATS'; diff --git a/src/actions/workspaceActions.js b/src/actions/workspaceActions.js index 905a699..f692563 100644 --- a/src/actions/workspaceActions.js +++ b/src/actions/workspaceActions.js @@ -1,28 +1,61 @@ -import { NEW_WORKSPACE, CREATE_BLOCK, CHANGE_BLOCK, DELETE_BLOCK, CLEAR_STATS } from './types'; +import { NEW_CODE, CHANGE_WORKSPACE, NEW_WORKSPACE, CREATE_BLOCK, MOVE_BLOCK, CHANGE_BLOCK, DELETE_BLOCK, CLEAR_STATS } from './types'; + +import * as Blockly from 'blockly/core'; + +export const workspaceChange = () => (dispatch) => { + dispatch({ + type: CHANGE_WORKSPACE + }) +} + +export const initWorkspace = (workspace) => (dispatch) => { + dispatch({ + type: NEW_WORKSPACE, + payload: workspace + }); +} export const onChangeWorkspace = (event) => (dispatch, getState) => { - var oldWorkspace = getState().workspace.new; // stored 'new workspace' is from now on old - var newWorkspace = window.Ardublockly.workspace; + const workspace = Blockly.getMainWorkspace(); dispatch({ type: NEW_WORKSPACE, - payload: {new: newWorkspace, old: oldWorkspace} + payload: workspace }); + dispatch({ + type: CHANGE_WORKSPACE, + }) + var code = getState().workspace.code; + code.arduino = Blockly.Arduino.workspaceToCode(workspace); + var xmlDom = Blockly.Xml.workspaceToDom(workspace); + code.xml = Blockly.Xml.domToPrettyText(xmlDom); + dispatch({ + type: NEW_CODE, + payload: code + }); + console.log(event.type); var stats = getState().workspace.stats; - if (event.type === window.Blockly.Events.CREATE){ + if (event.type === Blockly.Events.BLOCK_CREATE){ stats.create += event.ids.length; dispatch({ type: CREATE_BLOCK, payload: stats }); } - else if (event.type === window.Blockly.Events.CHANGE){ + else if (event.type === Blockly.Events.BLOCK_MOVE){ + stats.move += 1; + dispatch({ + type: MOVE_BLOCK, + payload: stats + }); + } + else if (event.type === Blockly.Events.BLOCK_CHANGE){ stats.change += 1; dispatch({ type: CHANGE_BLOCK, payload: stats }); } - else if (event.type === window.Blockly.Events.DELETE){ + else if (event.type === Blockly.Events.BLOCK_DELETE){ if(stats.create > 0){ stats.delete += event.ids.length; dispatch({ @@ -37,7 +70,8 @@ export const clearStats = () => (dispatch) => { var stats = { create: 0, change: 0, - delete: 0 + delete: 0, + move: 0 }; dispatch({ type: CLEAR_STATS, @@ -45,6 +79,7 @@ export const clearStats = () => (dispatch) => { }); }; + export const setWorkspace = (workspace) => (dispatch, getState) => { dispatch({ type: NEW_WORKSPACE, diff --git a/src/components/Blockly/BlocklyComponent.css b/src/components/Blockly/BlocklyComponent.css index 6f8e099..d1ac2b4 100644 --- a/src/components/Blockly/BlocklyComponent.css +++ b/src/components/Blockly/BlocklyComponent.css @@ -1,6 +1,4 @@ #blocklyDiv { - height: 90vH; + height: 60vH; width: 50%; - position: absolute; - bottom: 0; } diff --git a/src/components/BlocklyView.js b/src/components/BlocklyView.js new file mode 100644 index 0000000..77060c2 --- /dev/null +++ b/src/components/BlocklyView.js @@ -0,0 +1,68 @@ +import React, { Component } from 'react'; + +import BlocklyComponent, { Block, Value, Field, Shadow, Category } from './Blockly'; +import * as Blockly from 'blockly/core'; +import * as De from './Blockly/msg/de'; // de locale files +//import * as En from './Blockly/msg/en'; // de locale files +import './Blockly/blocks/index'; +import './Blockly/generator/index'; + + +class BlocklyView extends Component { + constructor(props) { + super(props); + this.simpleWorkspace = React.createRef(); + this.state = { + generatedCode: 'Click text' + } + } + + componentDidMount() { + let workspace = Blockly.getMainWorkspace(); + workspace.addChangeListener(this.generateCode); + } + + generateCode = () => { + var code = Blockly.Arduino.workspaceToCode(this.workspace); + console.log(code); + this.setState({ generatedCode: code }) + } + + render() { + return ( + + + + + + + + + + + + + + + + + + + + + + ); + }; +} + +export default BlocklyView; diff --git a/src/components/ClearWorkspace.js b/src/components/ClearWorkspace.js index 9ab4c57..c22672e 100644 --- a/src/components/ClearWorkspace.js +++ b/src/components/ClearWorkspace.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { clearStats } from '../actions/workspaceActions'; +import { clearStats, workspaceChange } from '../actions/workspaceActions'; import ListItem from '@material-ui/core/ListItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; @@ -13,8 +13,15 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; class ClearWorkspace extends Component { clearWorkspace = () => { - this.props.newWorkspace.clear(); - this.props.clearStats(); + if(this.props.workspace){ + this.props.workspace.clear(); + this.props.workspace.options.maxBlocks = Infinity; + this.props.workspaceChange(); + this.props.clearStats(); + } + else { + alert() + } } render() { @@ -28,12 +35,13 @@ class ClearWorkspace extends Component { } ClearWorkspace.propTypes = { - newWorkspace: PropTypes.object.isRequired, - clearStats: PropTypes.func.isRequired + workspace: PropTypes.object.isRequired, + clearStats: PropTypes.func.isRequired, + workspaceChange: PropTypes.func.isRequired }; const mapStateToProps = state => ({ - newWorkspace: state.workspace.new + workspace: state.workspace.workspace }); -export default connect(mapStateToProps, { clearStats })(ClearWorkspace); +export default connect(mapStateToProps, { clearStats, workspaceChange })(ClearWorkspace); diff --git a/src/components/CodeViewer.js b/src/components/CodeViewer.js new file mode 100644 index 0000000..caa920b --- /dev/null +++ b/src/components/CodeViewer.js @@ -0,0 +1,28 @@ +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; + + +class CodeViewer extends Component { + + render() { + return ( +
+ {this.props.arduino} +

{this.props.xml}

+
+ ); + }; +} + +CodeViewer.propTypes = { + arduino: PropTypes.string.isRequired, + xml: PropTypes.string.isRequired +}; + +const mapStateToProps = state => ({ + arduino: state.workspace.code.arduino, + xml: state.workspace.code.xml +}); + +export default connect(mapStateToProps, null)(CodeViewer); diff --git a/src/components/Home.js b/src/components/Home.js index 289b155..1082845 100644 --- a/src/components/Home.js +++ b/src/components/Home.js @@ -1,7 +1,12 @@ import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { onChangeWorkspace, initWorkspace } from '../actions/workspaceActions'; + import WorkspaceStats from './WorkspaceStats'; import WorkspaceFunc from './WorkspaceFunc'; +import CodeViewer from './CodeViewer'; import BlocklyComponent, { Block, Value, Field, Shadow, Category } from './Blockly'; import * as Blockly from 'blockly/core'; @@ -11,25 +16,19 @@ import './Blockly/blocks/index'; import './Blockly/generator/index'; - class Home extends React.Component { constructor(props) { super(props); this.simpleWorkspace = React.createRef(); - this.state = { generatedCode: 'Click text' } } componentDidMount() { - let workspace = Blockly.getMainWorkspace(); - workspace.addChangeListener(this.generateCode); - } - - generateCode = () => { - var code = Blockly.Arduino.workspaceToCode(this.workspace); - console.log(code); - this.setState({ generatedCode: code }) + this.props.initWorkspace(workspace); + workspace.addChangeListener((event) => { + this.props.onChangeWorkspace(event); + }); } render() { @@ -37,13 +36,16 @@ class Home extends React.Component {
+ initialXml={''} + > @@ -64,10 +66,28 @@ class Home extends React.Component { - +
); }; } -export default Home; +WorkspaceStats.propTypes = { + workspace: PropTypes.object.isRequired, + create: PropTypes.number.isRequired, + change: PropTypes.number.isRequired, + delete: PropTypes.number.isRequired, + move: PropTypes.number.isRequired, + worskpaceChange: PropTypes.number.isRequired +}; + +const mapStateToProps = state => ({ + workspace: state.workspace.workspace, + create: state.workspace.stats.create, + change: state.workspace.stats.change, + delete: state.workspace.stats.delete, + move: state.workspace.stats.move, + worskpaceChange: state.workspace.change +}); + +export default connect(null, { onChangeWorkspace, initWorkspace })(Home); diff --git a/src/components/MaxBlocks.js b/src/components/MaxBlocks.js index 014fe2e..01e8caa 100644 --- a/src/components/MaxBlocks.js +++ b/src/components/MaxBlocks.js @@ -1,7 +1,9 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { setWorkspace } from '../actions/workspaceActions'; +import { workspaceChange } from '../actions/workspaceActions'; + +import * as Blockly from 'blockly/core'; import TextField from '@material-ui/core/TextField'; import Button from '@material-ui/core/Button'; @@ -16,9 +18,13 @@ class MaxBlocks extends Component { this.setState({ [e.target.name]: e.target.value}); } + setMaxBlocks = () => { + const workspace = Blockly.getMainWorkspace(); + workspace.options.maxBlocks = this.state.max; + this.props.workspaceChange(); + } + render() { - // var blockLeft = Object.keys(this.props.newWorkspace).length > 0 ?

{this.props.newWorkspace.remainingCapacity()} verbleibende Blöcke möglich

: null - // var error = this.state.error ?
{this.state.error}
: null; return (
-
@@ -37,13 +43,4 @@ class MaxBlocks extends Component { }; } -MaxBlocks.propTypes = { - newWorkspace: PropTypes.object.isRequired, - setWorkspace: PropTypes.func.isRequired -}; - -const mapStateToProps = state => ({ - newWorkspace: state.workspace.new -}); - -export default connect(mapStateToProps, { setWorkspace })(MaxBlocks); +export default connect(null, { workspaceChange })(MaxBlocks); diff --git a/src/components/WorkspaceFunc.js b/src/components/WorkspaceFunc.js index 110324e..07de091 100644 --- a/src/components/WorkspaceFunc.js +++ b/src/components/WorkspaceFunc.js @@ -18,11 +18,12 @@ class WorkspaceFunc extends Component { open: false } - + getArduinoCode = () => { + this.setState({ title: 'Adurino Code', content: this.props.arduino, open: true }); + } getXMLCode = () => { - var code = window.Ardublockly.generateXml(); - this.setState({ title: 'XML Code', content: code, open: true }); + this.setState({ title: 'XML Code', content: this.props.xml, open: true }); } toggleDialog = () => { @@ -43,15 +44,12 @@ class WorkspaceFunc extends Component { - - ); @@ -59,11 +57,13 @@ class WorkspaceFunc extends Component { } WorkspaceFunc.propTypes = { - newWorkspace: PropTypes.object.isRequired + arduino: PropTypes.string.isRequired, + xml: PropTypes.string.isRequired }; const mapStateToProps = state => ({ - newWorkspace: state.workspace.new + arduino: state.workspace.code.arduino, + xml: state.workspace.code.xml }); export default connect(mapStateToProps, null)(WorkspaceFunc); diff --git a/src/components/WorkspaceStats.js b/src/components/WorkspaceStats.js index 7eadd99..baddbcd 100644 --- a/src/components/WorkspaceStats.js +++ b/src/components/WorkspaceStats.js @@ -2,11 +2,13 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; +import * as Blockly from 'blockly/core'; + import { withStyles } from '@material-ui/core/styles'; import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; -import { faPuzzlePiece, faTrash, faPlus, faPen } from "@fortawesome/free-solid-svg-icons"; +import { faPuzzlePiece, faTrash, faPlus, faPen, faArrowsAlt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; const styles = (theme) => ({ @@ -22,13 +24,13 @@ const styles = (theme) => ({ class WorkspaceStats extends Component { render() { - // var check = Object.keys(this.props.newWorkspace).length > 0 && this.props.create - this.props.delete !== this.props.newWorkspace.getAllBlocks().length ?

FEHLER!

: null; + const remainingBlocksInfinity = this.props.workspace ? this.props.workspace.remainingCapacity() !== Infinity : null; return (
- {Object.keys(this.props.newWorkspace).length > 0 ? this.props.newWorkspace.getAllBlocks().length : 0} + {this.props.workspace ? this.props.workspace.getAllBlocks().length : 0}
@@ -45,6 +47,13 @@ class WorkspaceStats extends Component { {this.props.change}
+ +
+ + + {this.props.move} +
+
@@ -52,29 +61,31 @@ class WorkspaceStats extends Component { {this.props.delete}
- {Object.keys(this.props.newWorkspace).length > 0 ? this.props.newWorkspace.remainingCapacity() !== Infinity ? + {remainingBlocksInfinity ? - {this.props.delete} verbleibende Blöcke - : null : null} + {this.props.workspace.remainingCapacity()} verbleibende Blöcke + : null} ); }; } WorkspaceStats.propTypes = { - newWorkspace: PropTypes.object.isRequired, + workspace: PropTypes.object.isRequired, create: PropTypes.number.isRequired, change: PropTypes.number.isRequired, delete: PropTypes.number.isRequired, - test: PropTypes.number.isRequired + move: PropTypes.number.isRequired, + worskpaceChange: PropTypes.number.isRequired }; const mapStateToProps = state => ({ - newWorkspace: state.workspace.new, + workspace: state.workspace.workspace, create: state.workspace.stats.create, change: state.workspace.stats.change, delete: state.workspace.stats.delete, - test: state.workspace.test + move: state.workspace.stats.move, + worskpaceChange: state.workspace.change }); export default connect(mapStateToProps, null)(withStyles(styles, {withTheme: true})(WorkspaceStats)); diff --git a/src/reducers/workspaceReducer.js b/src/reducers/workspaceReducer.js index df9e4bb..22b9082 100644 --- a/src/reducers/workspaceReducer.js +++ b/src/reducers/workspaceReducer.js @@ -1,27 +1,40 @@ -import { NEW_WORKSPACE, CREATE_BLOCK, CHANGE_BLOCK, DELETE_BLOCK, CLEAR_STATS } from '../actions/types'; +import { CHANGE_WORKSPACE, NEW_CODE, NEW_WORKSPACE, CREATE_BLOCK, MOVE_BLOCK, CHANGE_BLOCK, DELETE_BLOCK, CLEAR_STATS } from '../actions/types'; const initialState = { - old: {}, - new: {}, + code: { + arduino: '', + xml: '' + }, + workspace: null, stats: { create: 0, change: 0, delete: 0, + move: 0 }, - test: 0 + change: 0 }; export default function(state = initialState, action){ switch(action.type){ + case NEW_CODE: + return { + ...state, + code: action.payload + }; + case CHANGE_WORKSPACE: + return { + ...state, + change: state.change += 1 + }; case NEW_WORKSPACE: return { ...state, - old: action.payload.old, - new: action.payload.new, - test: state.test += 1 + workspace: action.payload }; case CREATE_BLOCK: + case MOVE_BLOCK: case CHANGE_BLOCK: case DELETE_BLOCK: case CLEAR_STATS: