Merge branch 'master' into add-new-blocks
This commit is contained in:
+1
-1
@@ -3,5 +3,5 @@
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
position: relative;
|
||||
padding-bottom: 60px; /* height of your footer + 30px*/y
|
||||
/* padding-bottom: 60px; /* height of your footer + 30px*/
|
||||
}
|
||||
|
||||
+6
-3
@@ -5,6 +5,8 @@ import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import store from './store';
|
||||
|
||||
import './App.css';
|
||||
|
||||
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
|
||||
|
||||
import Navbar from './components/Navbar';
|
||||
@@ -15,6 +17,9 @@ const theme = createMuiTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#4EAF47',
|
||||
},
|
||||
secondary: {
|
||||
main: '#DDDDDD'
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -27,9 +32,7 @@ function App() {
|
||||
<Router>
|
||||
<div className="wrapper">
|
||||
<Navbar />
|
||||
<div style={{ margin: '0 22px' }}>
|
||||
<Routes />
|
||||
</div>
|
||||
<Routes />
|
||||
<Footer />
|
||||
</div>
|
||||
</Router>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export const NEW_WORKSPACE = 'NEW_WORKSPACE';
|
||||
export const NEW_CODE = 'NEW_CODE';
|
||||
export const CHANGE_WORKSPACE = 'CHANGE_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';
|
||||
|
||||
@@ -1,28 +1,50 @@
|
||||
import { NEW_WORKSPACE, CREATE_BLOCK, CHANGE_BLOCK, DELETE_BLOCK, CLEAR_STATS } from './types';
|
||||
import { NEW_CODE, CHANGE_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 onChangeWorkspace = (event) => (dispatch, getState) => {
|
||||
var oldWorkspace = getState().workspace.new; // stored 'new workspace' is from now on old
|
||||
var newWorkspace = window.Ardublockly.workspace;
|
||||
dispatch({
|
||||
type: NEW_WORKSPACE,
|
||||
payload: {new: newWorkspace, old: oldWorkspace}
|
||||
type: CHANGE_WORKSPACE,
|
||||
})
|
||||
const workspace = Blockly.getMainWorkspace();
|
||||
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
|
||||
});
|
||||
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,17 +59,11 @@ export const clearStats = () => (dispatch) => {
|
||||
var stats = {
|
||||
create: 0,
|
||||
change: 0,
|
||||
delete: 0
|
||||
delete: 0,
|
||||
move: 0
|
||||
};
|
||||
dispatch({
|
||||
type: CLEAR_STATS,
|
||||
payload: stats
|
||||
});
|
||||
};
|
||||
|
||||
export const setWorkspace = (workspace) => (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: NEW_WORKSPACE,
|
||||
payload: {new: workspace, old: getState().workspace.new}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#blocklyDiv {
|
||||
height: 90vH;
|
||||
width: 50%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
min-height: 500px;
|
||||
width: 100%;
|
||||
border: 1px solid #4EAF47;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { onChangeWorkspace } from '../../actions/workspaceActions';
|
||||
|
||||
import BlocklyComponent, { Block, Value, Field, Shadow, Category } from './';
|
||||
import * as Blockly from 'blockly/core';
|
||||
import * as De from './msg/de'; // de locale files
|
||||
//import * as En from './Blockly/msg/en'; // de locale files
|
||||
import './blocks/index';
|
||||
import './generator/index';
|
||||
|
||||
|
||||
class BlocklyWindow extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.simpleWorkspace = React.createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const workspace = Blockly.getMainWorkspace();
|
||||
this.props.onChangeWorkspace({});
|
||||
workspace.addChangeListener((event) => {
|
||||
this.props.onChangeWorkspace(event);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<BlocklyComponent ref={this.simpleWorkspace}
|
||||
readOnly={false}
|
||||
trashcan={true}
|
||||
zoom={{ // https://developers.google.com/blockly/guides/configure/web/zoom
|
||||
controls: true,
|
||||
wheel: true,
|
||||
startScale: 1.0,
|
||||
maxScale: 3,
|
||||
minScale: 0.3,
|
||||
scaleSpeed: 1.2
|
||||
}}
|
||||
grid={{ // https://developers.google.com/blockly/guides/configure/web/grid
|
||||
spacing: 20,
|
||||
length: 1,
|
||||
colour: '#4EAF47', // senseBox-green
|
||||
snap: false
|
||||
}}
|
||||
media={'media/'}
|
||||
move={{ // https://developers.google.com/blockly/guides/configure/web/move
|
||||
scrollbars: true,
|
||||
drag: true,
|
||||
wheel: false
|
||||
}}
|
||||
initialXml={''}
|
||||
>
|
||||
<Category name="loops" >
|
||||
<Block type="controls_for" />
|
||||
<Block type="controls_repeat_ext" />
|
||||
<Block type="controls_whileUntil" />
|
||||
</Category>
|
||||
<Category name="senseBox" colour="120" >
|
||||
<Category name="Sensoren" colour="120" >
|
||||
<Block type="sensebox_sensor_temp_hum"></Block>
|
||||
</Category>
|
||||
<Block type="sensebox_telegram" />
|
||||
</Category>
|
||||
<Category name="Logic" colour="#b063c5">
|
||||
<Block type="control_if"></Block>
|
||||
<Block type="controls_ifelse"></Block>
|
||||
<Block type="logic_compare"></Block>
|
||||
<Block type="logic_operation"></Block>
|
||||
<Block type="logic_negate"></Block>
|
||||
<Block type="logic_boolean"></Block>
|
||||
</Category>
|
||||
</BlocklyComponent>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
BlocklyWindow.propTypes = {
|
||||
onChangeWorkspace: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
export default connect(null, { onChangeWorkspace })(BlocklyWindow);
|
||||
@@ -1,7 +1,9 @@
|
||||
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 * as Blockly from 'blockly/core';
|
||||
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
@@ -13,7 +15,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
class ClearWorkspace extends Component {
|
||||
|
||||
clearWorkspace = () => {
|
||||
this.props.newWorkspace.clear();
|
||||
const workspace = Blockly.getMainWorkspace();
|
||||
workspace.clear();
|
||||
workspace.options.maxBlocks = Infinity;
|
||||
this.props.workspaceChange();
|
||||
this.props.clearStats();
|
||||
}
|
||||
|
||||
@@ -28,12 +33,9 @@ class ClearWorkspace extends Component {
|
||||
}
|
||||
|
||||
ClearWorkspace.propTypes = {
|
||||
newWorkspace: PropTypes.object.isRequired,
|
||||
clearStats: PropTypes.func.isRequired
|
||||
clearStats: PropTypes.func.isRequired,
|
||||
workspaceChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
newWorkspace: state.workspace.new
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { clearStats })(ClearWorkspace);
|
||||
export default connect(null, { clearStats, workspaceChange })(ClearWorkspace);
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import Prism from "prismjs";
|
||||
import "prismjs/themes/prism.css";
|
||||
import "prismjs/plugins/line-numbers/prism-line-numbers";
|
||||
import "prismjs/plugins/line-numbers/prism-line-numbers.css";
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import MuiAccordion from '@material-ui/core/Accordion';
|
||||
import MuiAccordionSummary from '@material-ui/core/AccordionSummary';
|
||||
import MuiAccordionDetails from '@material-ui/core/AccordionDetails';
|
||||
|
||||
const Accordion = withStyles((theme) => ({
|
||||
root: {
|
||||
border: `1px solid ${theme.palette.secondary.main}`,
|
||||
boxShadow: 'none',
|
||||
'&:before': {
|
||||
display: 'none',
|
||||
},
|
||||
'&$expanded': {
|
||||
margin: 'auto',
|
||||
},
|
||||
},
|
||||
expanded: {},
|
||||
}))(MuiAccordion);
|
||||
|
||||
const AccordionSummary = withStyles((theme) => ({
|
||||
root: {
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
borderBottom: `1px solid white`,
|
||||
marginBottom: -1,
|
||||
minHeight: 50,
|
||||
'&$expanded': {
|
||||
minHeight: 50,
|
||||
},
|
||||
},
|
||||
content: {
|
||||
'&$expanded': {
|
||||
margin: '12px 0',
|
||||
},
|
||||
},
|
||||
expanded: {},
|
||||
}))(MuiAccordionSummary);
|
||||
|
||||
const AccordionDetails = withStyles((theme) => ({
|
||||
root: {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
}))(MuiAccordionDetails);
|
||||
|
||||
|
||||
class CodeViewer extends Component {
|
||||
|
||||
state = {
|
||||
expanded: true
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
Prism.highlightAll();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
Prism.highlightAll();
|
||||
}
|
||||
|
||||
onChange = () => {
|
||||
this.setState({ expanded: !this.state.expanded });
|
||||
}
|
||||
|
||||
render() {
|
||||
var curlyBrackets = '{ }';
|
||||
var unequal = '<>';
|
||||
return (
|
||||
<div style={{height: '500px'}}>
|
||||
<Accordion
|
||||
square={true}
|
||||
style={{margin: 0}}
|
||||
expanded={this.state.expanded}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<AccordionSummary>
|
||||
<b style={{fontSize: '20px', marginRight: '5px', width: '35px'}}>{curlyBrackets}</b>
|
||||
<div style={{margin: 'auto 5px 2px 0px'}}>Arduino Quellcode</div>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails style={{padding: 0, height: 'calc(500px - 50px - 50px)', backgroundColor: 'white'}}>
|
||||
<pre className="line-numbers" style={{paddingBottom: 0, width: '100%', overflow: 'auto', scrollbarWidth: 'thin', height: 'calc(100% - 30px)', margin: '15px 0', paddingTop: 0, whiteSpace: 'pre-wrap', backgroundColor: 'white'}}>
|
||||
<code className="language-clike">
|
||||
{this.props.arduino}
|
||||
</code>
|
||||
</pre>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
square={true}
|
||||
style={{margin: 0}}
|
||||
expanded={!this.state.expanded}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<AccordionSummary>
|
||||
<b style={{fontSize: '20px', marginRight: '5px', width: '35px'}}>{unequal}</b>
|
||||
<div style={{margin: 'auto 5px 2px 0px'}}>XML Blöcke</div>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails style={{padding: 0, height: 'calc(500px - 50px - 50px)', backgroundColor: 'white'}}>
|
||||
<pre className="line-numbers" style={{paddingBottom: 0, width: '100%', overflow: 'auto', scrollbarWidth: 'thin', height: 'calc(100% - 30px)', margin: '15px 0', paddingTop: 0, whiteSpace: 'pre-wrap', backgroundColor: 'white'}}>
|
||||
<code className="language-xml">
|
||||
{`${this.props.xml}`}
|
||||
</code>
|
||||
</pre>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -8,7 +8,7 @@ class Footer extends Component {
|
||||
render() {
|
||||
return (
|
||||
<footer style={{position:'absolute', bottom: '0', width: '100%'}}>
|
||||
<div style={{minHeight:'30px', backgroundColor:'lightgrey', textAlign: 'center', paddingTop: '2px'}}>
|
||||
<div style={{minHeight:'30px', backgroundColor:'#DDDDDD', textAlign: 'center', paddingTop: '2px'}}>
|
||||
<div style={{color: 'grey', height: '100%'}}>
|
||||
<Link to={"/impressum"} style={{textDecoration: 'none', color: 'inherit'}}>Impressum</Link>
|
||||
<Typography style={{margin: '0px 10px 0px 10px', display: 'initial', fontSize: '1rem'}}>|</Typography>
|
||||
|
||||
+35
-31
@@ -1,51 +1,55 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import * as Blockly from 'blockly/core';
|
||||
|
||||
import WorkspaceStats from './WorkspaceStats';
|
||||
import WorkspaceFunc from './WorkspaceFunc';
|
||||
import BlocklyWindow from './Blockly/BlocklyWindow';
|
||||
import CodeViewer from './CodeViewer';
|
||||
|
||||
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/';
|
||||
import './Blockly/generator/';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import Switch from '@material-ui/core/Switch';
|
||||
|
||||
class Home extends Component {
|
||||
|
||||
|
||||
|
||||
class Home extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.simpleWorkspace = React.createRef();
|
||||
this.state = { generatedCode: 'Click text' }
|
||||
state = {
|
||||
codeOn: false
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
let workspace = Blockly.getMainWorkspace();
|
||||
workspace.addChangeListener(this.generateCode);
|
||||
componentDidUpdate() {
|
||||
/* Resize and reposition all of the workspace chrome (toolbox, trash,
|
||||
scrollbars etc.) This should be called when something changes that requires
|
||||
recalculating dimensions and positions of the trash, zoom, toolbox, etc.
|
||||
(e.g. window resize). */
|
||||
const workspace = Blockly.getMainWorkspace();
|
||||
Blockly.svgResize(workspace);
|
||||
}
|
||||
|
||||
generateCode = () => {
|
||||
var code = Blockly.Arduino.workspaceToCode(this.workspace);
|
||||
console.log(code);
|
||||
this.setState({ generatedCode: code })
|
||||
onChange = () => {
|
||||
this.setState({ codeOn: !this.state.codeOn });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<WorkspaceStats />
|
||||
<BlocklyComponent ref={this.simpleWorkspace}
|
||||
readOnly={false} trashcan={true} media={'media/'}
|
||||
move={{
|
||||
scrollbars: true,
|
||||
drag: true,
|
||||
wheel: true
|
||||
}}
|
||||
initialXml={''} />
|
||||
<WorkspaceFunc generateCode={this.generateCode} />
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={this.state.codeOn ? 6 : 12} style={{ position: 'relative' }}>
|
||||
<FormControlLabel
|
||||
style={{ margin: '5px 10px 0 0', position: 'absolute', top: 0, right: 0, zIndex: 1 }}
|
||||
control={<Switch checked={this.state.codeOn} onChange={this.onChange} color='primary' />}
|
||||
label="Code"
|
||||
/>
|
||||
<BlocklyWindow />
|
||||
</Grid>
|
||||
{this.state.codeOn ?
|
||||
<Grid item xs={12} md={6}>
|
||||
<CodeViewer />
|
||||
</Grid>
|
||||
: null}
|
||||
</Grid>
|
||||
<WorkspaceFunc />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+13
-13
@@ -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,20 +18,23 @@ 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 ? <p>{this.props.newWorkspace.remainingCapacity()} verbleibende Blöcke möglich</p> : null
|
||||
// var error = this.state.error ? <div>{this.state.error}</div> : null;
|
||||
return (
|
||||
<div style={{display: 'inline', marginLeft: '10px'}}>
|
||||
<TextField
|
||||
style={{width: '50px'}}
|
||||
style={{width: '50px', marginRight: '5px'}}
|
||||
name="max"
|
||||
type="number"
|
||||
onChange={this.onChange}
|
||||
value={this.state.max}
|
||||
variant='filled'
|
||||
/>
|
||||
<Button style={{marginRight: '10px'}} variant="contained" color="primary" onClick={() => {this.props.newWorkspace.options.maxBlocks = this.state.max; this.props.setWorkspace(this.props.newWorkspace)}}>
|
||||
<Button style={{marginRight: '10px', color: 'white'}} variant="contained" color="primary" onClick={this.setMaxBlocks}>
|
||||
Maximale Blöcke
|
||||
</Button>
|
||||
</div>
|
||||
@@ -38,12 +43,7 @@ class MaxBlocks extends Component {
|
||||
}
|
||||
|
||||
MaxBlocks.propTypes = {
|
||||
newWorkspace: PropTypes.object.isRequired,
|
||||
setWorkspace: PropTypes.func.isRequired
|
||||
workspaceChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
newWorkspace: state.workspace.new
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { setWorkspace })(MaxBlocks);
|
||||
export default connect(null, { workspaceChange })(MaxBlocks);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import ClearWorkspace from './ClearWorkspace';
|
||||
import senseboxLogo from './sensebox_logo.svg';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Drawer from '@material-ui/core/Drawer';
|
||||
@@ -51,7 +52,7 @@ class Navbar extends Component {
|
||||
style={{height: '50px', marginBottom: '30px'}}
|
||||
classes={{root: this.props.classes.appBarColor}}
|
||||
>
|
||||
<Toolbar style={{height: '50px', minHeight: '50px', padding: 0}}>
|
||||
<Toolbar style={{height: '50px', minHeight: '50px', padding: 0, color: 'white'}}>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
onClick={this.toggleDrawer}
|
||||
@@ -64,6 +65,9 @@ class Navbar extends Component {
|
||||
senseBox Blockly
|
||||
</Typography>
|
||||
</Link>
|
||||
<Link to={"/"} style={{marginLeft: '10px'}}>
|
||||
<img src={senseboxLogo} alt="senseBox-Logo" width="30"/>
|
||||
</Link>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<Drawer
|
||||
|
||||
@@ -9,10 +9,12 @@ class Routes extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Switch>
|
||||
<Route path="/" exact component={Home} />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
<div style={{ margin: '0 22px' }}>
|
||||
<Switch>
|
||||
<Route path="/" exact component={Home} />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
<Button style={{ marginRight: '10px' }} variant="contained" color="primary" onClick={() => this.props.generateCode()}>
|
||||
<Button style={{ marginRight: '10px', color: 'white' }} variant="contained" color="primary" onClick={() => this.getArduinoCode()}>
|
||||
Get Adurino Code
|
||||
</Button>
|
||||
<Button style={{ marginRight: '10px' }} variant="contained" color="primary" onClick={() => this.getXMLCode()}>
|
||||
<Button style={{ marginRight: '10px', color: 'white' }} variant="contained" color="primary" onClick={() => this.getXMLCode()}>
|
||||
Get XML Code
|
||||
</Button>
|
||||
<Button variant="contained" color="primary" onClick={() => { var blocks = this.props.newWorkspace; console.log(blocks); }}>
|
||||
Get workspace
|
||||
</Button>
|
||||
<MaxBlocks />
|
||||
</div>
|
||||
);
|
||||
@@ -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);
|
||||
|
||||
@@ -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,14 @@ 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 ? <h1>FEHLER!</h1> : null;
|
||||
const workspace = Blockly.getMainWorkspace();
|
||||
const remainingBlocksInfinity = workspace ? workspace.remainingCapacity() !== Infinity : null;
|
||||
return (
|
||||
<div style={{marginBottom: '20px'}}>
|
||||
<div style={{marginBottom: '20px', color: 'white'}}>
|
||||
<Tooltip title="Anzahl aktueller Blöcke" style={{marginLeft: 0}} className={this.props.classes.stats}>
|
||||
<div>
|
||||
<FontAwesomeIcon icon={faPuzzlePiece} />
|
||||
<Typography style={{display: 'inline'}}> {Object.keys(this.props.newWorkspace).length > 0 ? this.props.newWorkspace.getAllBlocks().length : 0}</Typography>
|
||||
<Typography style={{display: 'inline'}}> {workspace ? workspace.getAllBlocks().length : 0}</Typography>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Anzahl neuer Blöcke" className={this.props.classes.stats}>
|
||||
@@ -45,6 +48,13 @@ class WorkspaceStats extends Component {
|
||||
<Typography style={{display: 'inline'}}> {this.props.change}</Typography>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Anzahl bewegter Blöcke" className={this.props.classes.stats}>
|
||||
<div>
|
||||
<FontAwesomeIcon icon={faArrowsAlt} style={{marginRight: '5px'}}/>
|
||||
<FontAwesomeIcon icon={faPuzzlePiece} />
|
||||
<Typography style={{display: 'inline'}}> {this.props.move}</Typography>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="Anzahl gelöschter Blöcke" className={this.props.classes.stats}>
|
||||
<div>
|
||||
<FontAwesomeIcon icon={faTrash} style={{marginRight: '5px'}}/>
|
||||
@@ -52,29 +62,29 @@ class WorkspaceStats extends Component {
|
||||
<Typography style={{display: 'inline'}}> {this.props.delete}</Typography>
|
||||
</div>
|
||||
</Tooltip>
|
||||
{Object.keys(this.props.newWorkspace).length > 0 ? this.props.newWorkspace.remainingCapacity() !== Infinity ?
|
||||
{remainingBlocksInfinity ?
|
||||
<Tooltip title="verbleibende Blöcke" className={this.props.classes.stats}>
|
||||
<Typography style={{display: 'inline'}}>{this.props.delete} verbleibende Blöcke</Typography>
|
||||
</Tooltip> : null : null}
|
||||
<Typography style={{display: 'inline'}}>{workspace.remainingCapacity()} verbleibende Blöcke</Typography>
|
||||
</Tooltip> : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
WorkspaceStats.propTypes = {
|
||||
newWorkspace: 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,
|
||||
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));
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 7.1 KiB |
@@ -1,27 +1,34 @@
|
||||
import { NEW_WORKSPACE, CREATE_BLOCK, CHANGE_BLOCK, DELETE_BLOCK, CLEAR_STATS } from '../actions/types';
|
||||
import { CHANGE_WORKSPACE, NEW_CODE, CREATE_BLOCK, MOVE_BLOCK, CHANGE_BLOCK, DELETE_BLOCK, CLEAR_STATS } from '../actions/types';
|
||||
|
||||
|
||||
const initialState = {
|
||||
old: {},
|
||||
new: {},
|
||||
code: {
|
||||
arduino: '',
|
||||
xml: ''
|
||||
},
|
||||
stats: {
|
||||
create: 0,
|
||||
change: 0,
|
||||
delete: 0,
|
||||
move: 0
|
||||
},
|
||||
test: 0
|
||||
change: 0
|
||||
};
|
||||
|
||||
export default function(state = initialState, action){
|
||||
switch(action.type){
|
||||
case NEW_WORKSPACE:
|
||||
case NEW_CODE:
|
||||
return {
|
||||
...state,
|
||||
old: action.payload.old,
|
||||
new: action.payload.new,
|
||||
test: state.test += 1
|
||||
code: action.payload
|
||||
};
|
||||
case CHANGE_WORKSPACE:
|
||||
return {
|
||||
...state,
|
||||
change: state.change += 1
|
||||
};
|
||||
case CREATE_BLOCK:
|
||||
case MOVE_BLOCK:
|
||||
case CHANGE_BLOCK:
|
||||
case DELETE_BLOCK:
|
||||
case CLEAR_STATS:
|
||||
|
||||
Reference in New Issue
Block a user