diff --git a/package.json b/package.json
index c8d81796..a3c0209c 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
"react": "15.5.4",
"react-dom": "15.5.4",
"react-intl": "2.3.0",
+ "react-redux": "5.0.5",
"redux": "3.6.0",
"redux-throttle": "0.1.1",
"rimraf": "^2.6.1",
diff --git a/src/components/paint-editor.jsx b/src/components/paint-editor.jsx
index 16a9c877..db93953f 100644
--- a/src/components/paint-editor.jsx
+++ b/src/components/paint-editor.jsx
@@ -1,13 +1,18 @@
+import PropTypes from 'prop-types';
import React from 'react';
-import PaperCanvas from './paper-canvas.jsx';
+import PaperCanvas from '../containers/paper-canvas.jsx';
-export default class PaintEditorComponent extends React.Component {
- render () {
- return (
-
- );
- }
-}
+const PaintEditorComponent = props => (
+
+);
-PaintEditorComponent.defaultProps = {
+PaintEditorComponent.propTypes = {
+ tool: PropTypes.shape({
+ name: PropTypes.string.isRequired
+ })
};
+
+
+module.exports = PaintEditorComponent;
diff --git a/src/containers/paint-editor.jsx b/src/containers/paint-editor.jsx
new file mode 100644
index 00000000..efe05522
--- /dev/null
+++ b/src/containers/paint-editor.jsx
@@ -0,0 +1,48 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import PaintEditorComponent from '../components/paint-editor.jsx';
+import tools from '../reducers/tools';
+import ToolTypes from '../tools/tool-types.js';
+import {connect} from 'react-redux';
+
+class PaintEditor extends React.Component {
+ componentDidMount () {
+ const onKeyPress = this.props.onKeyPress;
+ document.onkeydown = function (e) {
+ e = e || window.event;
+ onKeyPress(e);
+ };
+ }
+ render () {
+ return (
+
+ );
+ }
+}
+
+PaintEditor.propTypes = {
+ onKeyPress: PropTypes.func.isRequired,
+ tool: PropTypes.shape({
+ name: PropTypes.string.isRequired
+ })
+};
+
+const mapStateToProps = state => ({
+ tool: state.tool
+});
+const mapDispatchToProps = dispatch => ({
+ onKeyPress: e => {
+ if (e.key === 'e') {
+ dispatch(tools.changeTool(ToolTypes.ERASER));
+ } else if (e.key === 'b') {
+ dispatch(tools.changeTool(ToolTypes.BRUSH));
+ }
+ }
+});
+
+module.exports = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(PaintEditor);
diff --git a/src/components/paper-canvas.jsx b/src/containers/paper-canvas.jsx
similarity index 72%
rename from src/components/paper-canvas.jsx
rename to src/containers/paper-canvas.jsx
index e4df4b14..5d813a0f 100644
--- a/src/components/paper-canvas.jsx
+++ b/src/containers/paper-canvas.jsx
@@ -1,5 +1,7 @@
+import PropTypes from 'prop-types';
import React from 'react';
import paper from 'paper';
+import ToolTypes from '../tools/tool-types.js';
class PaperCanvas extends React.Component {
constructor (props) {
@@ -22,6 +24,11 @@ class PaperCanvas extends React.Component {
// Draw the view now:
paper.view.draw();
}
+ componentWillReceiveProps (nextProps) {
+ if (nextProps.tool !== this.props.tool && nextProps.tool instanceof ToolTypes) {
+ // TODO switch tool
+ }
+ }
componentWillUnmount () {
}
render () {
@@ -31,6 +38,10 @@ class PaperCanvas extends React.Component {
}
}
-PaperCanvas.propTypes = {};
+PaperCanvas.propTypes = {
+ tool: PropTypes.shape({
+ name: PropTypes.string.isRequired
+ })
+};
module.exports = PaperCanvas;
diff --git a/src/index.js b/src/index.js
index 5df3df46..699887c5 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,3 +1,3 @@
-import PaintEditorComponent from './components/paint-editor.jsx';
+import PaintEditor from './containers/paint-editor.jsx';
-export {PaintEditorComponent as default};
+export {PaintEditor as default};
diff --git a/src/playground/playground.jsx b/src/playground/playground.jsx
index 6efcd1cd..31ad10cf 100644
--- a/src/playground/playground.jsx
+++ b/src/playground/playground.jsx
@@ -1,9 +1,21 @@
import React from 'react';
import ReactDOM from 'react-dom';
import PaintEditor from '..';
+import {Provider} from 'react-redux';
+import {createStore, applyMiddleware} from 'redux';
+import throttle from 'redux-throttle';
+import reducer from '../reducers/combine-reducers';
const appTarget = document.createElement('div');
document.body.appendChild(appTarget);
-ReactDOM.render(
- ,
- appTarget);
+const store = applyMiddleware(
+ throttle(300, {leading: true, trailing: true})
+)(createStore)(
+ reducer,
+ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
+);
+ReactDOM.render((
+
+
+
+), appTarget);
diff --git a/src/reducers/combine-reducers.js b/src/reducers/combine-reducers.js
new file mode 100644
index 00000000..a533b763
--- /dev/null
+++ b/src/reducers/combine-reducers.js
@@ -0,0 +1,5 @@
+import {combineReducers} from 'redux';
+
+module.exports = combineReducers({
+ tool: require('./tools')
+});
diff --git a/src/reducers/tools.js b/src/reducers/tools.js
new file mode 100644
index 00000000..5a09586e
--- /dev/null
+++ b/src/reducers/tools.js
@@ -0,0 +1,32 @@
+import ToolTypes from '../tools/tool-types.js';
+
+const CHANGE_TOOL = 'scratch-paint/tools/CHANGE_TOOL';
+const initialState = ToolTypes.BRUSH;
+
+const reducer = function (state, action) {
+ if (typeof state === 'undefined') state = initialState;
+ switch (action.type) {
+ case CHANGE_TOOL:
+ if (action.tool instanceof ToolTypes) {
+ return action.tool;
+ }
+ // TODO switch to minilog
+ console.warn('Warning: Tool type does not exist: ${action.tool}');
+ /* falls through */
+ default:
+ return state;
+ }
+};
+
+// Action creators ==================================
+reducer.changeTool = function (tool) {
+ return {
+ type: CHANGE_TOOL,
+ tool: tool,
+ meta: {
+ throttle: 30
+ }
+ };
+};
+
+module.exports = reducer;
diff --git a/src/tools/tool-types.js b/src/tools/tool-types.js
new file mode 100644
index 00000000..12c8b0f4
--- /dev/null
+++ b/src/tools/tool-types.js
@@ -0,0 +1,12 @@
+class ToolTypes {
+ constructor (name) {
+ this.name = name;
+ }
+ toString () {
+ return `ToolTypes.${this.name}`;
+ }
+}
+ToolTypes.BRUSH = new ToolTypes('BRUSH');
+ToolTypes.ERASER = new ToolTypes('ERASER');
+
+module.exports = ToolTypes;