mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-22 21:42:30 -05:00
commit
c49a469eda
19 changed files with 728 additions and 4 deletions
19
src/components/oval-mode.jsx
Normal file
19
src/components/oval-mode.jsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
|
const OvalModeComponent = props => (
|
||||||
|
<button onClick={props.onMouseDown}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Circle"
|
||||||
|
description="Label for the oval-drawing tool"
|
||||||
|
id="paint.ovalMode.oval"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
OvalModeComponent.propTypes = {
|
||||||
|
onMouseDown: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OvalModeComponent;
|
|
@ -1,12 +1,19 @@
|
||||||
import bindAll from 'lodash.bindall';
|
import bindAll from 'lodash.bindall';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import PaperCanvas from '../containers/paper-canvas.jsx';
|
import PaperCanvas from '../containers/paper-canvas.jsx';
|
||||||
|
|
||||||
import BrushMode from '../containers/brush-mode.jsx';
|
import BrushMode from '../containers/brush-mode.jsx';
|
||||||
import EraserMode from '../containers/eraser-mode.jsx';
|
import EraserMode from '../containers/eraser-mode.jsx';
|
||||||
import ReshapeMode from '../containers/reshape-mode.jsx';
|
import ReshapeMode from '../containers/reshape-mode.jsx';
|
||||||
import SelectMode from '../containers/select-mode.jsx';
|
import SelectMode from '../containers/select-mode.jsx';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import LineMode from '../containers/line-mode.jsx';
|
import LineMode from '../containers/line-mode.jsx';
|
||||||
|
import PenMode from '../containers/pen-mode.jsx';
|
||||||
|
import RectMode from '../containers/rect-mode.jsx';
|
||||||
|
import RoundedRectMode from '../containers/rounded-rect-mode.jsx';
|
||||||
|
import OvalMode from '../containers/oval-mode.jsx';
|
||||||
|
|
||||||
import FillColorIndicatorComponent from '../containers/fill-color-indicator.jsx';
|
import FillColorIndicatorComponent from '../containers/fill-color-indicator.jsx';
|
||||||
import StrokeColorIndicatorComponent from '../containers/stroke-color-indicator.jsx';
|
import StrokeColorIndicatorComponent from '../containers/stroke-color-indicator.jsx';
|
||||||
import StrokeWidthIndicatorComponent from '../containers/stroke-width-indicator.jsx';
|
import StrokeWidthIndicatorComponent from '../containers/stroke-width-indicator.jsx';
|
||||||
|
@ -132,6 +139,10 @@ class PaintEditorComponent extends React.Component {
|
||||||
canvas={this.state.canvas}
|
canvas={this.state.canvas}
|
||||||
onUpdateSvg={this.props.onUpdateSvg}
|
onUpdateSvg={this.props.onUpdateSvg}
|
||||||
/>
|
/>
|
||||||
|
<PenMode
|
||||||
|
canvas={this.state.canvas}
|
||||||
|
onUpdateSvg={this.props.onUpdateSvg}
|
||||||
|
/>
|
||||||
<LineMode
|
<LineMode
|
||||||
canvas={this.state.canvas}
|
canvas={this.state.canvas}
|
||||||
onUpdateSvg={this.props.onUpdateSvg}
|
onUpdateSvg={this.props.onUpdateSvg}
|
||||||
|
@ -142,6 +153,15 @@ class PaintEditorComponent extends React.Component {
|
||||||
<ReshapeMode
|
<ReshapeMode
|
||||||
onUpdateSvg={this.props.onUpdateSvg}
|
onUpdateSvg={this.props.onUpdateSvg}
|
||||||
/>
|
/>
|
||||||
|
<OvalMode
|
||||||
|
onUpdateSvg={this.props.onUpdateSvg}
|
||||||
|
/>
|
||||||
|
<RectMode
|
||||||
|
onUpdateSvg={this.props.onUpdateSvg}
|
||||||
|
/>
|
||||||
|
<RoundedRectMode
|
||||||
|
onUpdateSvg={this.props.onUpdateSvg}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|
19
src/components/pen-mode.jsx
Normal file
19
src/components/pen-mode.jsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
|
const PenModeComponent = props => (
|
||||||
|
<button onClick={props.onMouseDown}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Pen"
|
||||||
|
description="Label for the pen tool, which draws outlines"
|
||||||
|
id="paint.penMode.pen"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
PenModeComponent.propTypes = {
|
||||||
|
onMouseDown: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PenModeComponent;
|
19
src/components/rect-mode.jsx
Normal file
19
src/components/rect-mode.jsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
|
const RectModeComponent = props => (
|
||||||
|
<button onClick={props.onMouseDown}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Rectangle"
|
||||||
|
description="Label for the rectangle tool"
|
||||||
|
id="paint.rectMode.rect"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
RectModeComponent.propTypes = {
|
||||||
|
onMouseDown: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RectModeComponent;
|
19
src/components/rounded-rect-mode.jsx
Normal file
19
src/components/rounded-rect-mode.jsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
|
const RoundedRectModeComponent = props => (
|
||||||
|
<button onClick={props.onMouseDown}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Rounded Rectangle"
|
||||||
|
description="Label for the rounded rectangle tool"
|
||||||
|
id="paint.roundedRectMode.roundedRect"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
RoundedRectModeComponent.propTypes = {
|
||||||
|
onMouseDown: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RoundedRectModeComponent;
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import bindAll from 'lodash.bindall';
|
import bindAll from 'lodash.bindall';
|
||||||
import Modes from '../modes/modes';
|
import Modes from '../modes/modes';
|
||||||
import Blobbiness from './blob/blob';
|
import Blobbiness from '../helper/blob-tools/blob';
|
||||||
|
|
||||||
import {changeBrushSize} from '../reducers/brush-mode';
|
import {changeBrushSize} from '../reducers/brush-mode';
|
||||||
import {changeMode} from '../reducers/modes';
|
import {changeMode} from '../reducers/modes';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import bindAll from 'lodash.bindall';
|
import bindAll from 'lodash.bindall';
|
||||||
import Modes from '../modes/modes';
|
import Modes from '../modes/modes';
|
||||||
import Blobbiness from './blob/blob';
|
import Blobbiness from '../helper/blob-tools/blob';
|
||||||
import {changeBrushSize} from '../reducers/eraser-mode';
|
import {changeBrushSize} from '../reducers/eraser-mode';
|
||||||
import {clearSelectedItems} from '../reducers/selected-items';
|
import {clearSelectedItems} from '../reducers/selected-items';
|
||||||
import EraserModeComponent from '../components/eraser-mode.jsx';
|
import EraserModeComponent from '../components/eraser-mode.jsx';
|
||||||
|
|
102
src/containers/oval-mode.jsx
Normal file
102
src/containers/oval-mode.jsx
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import bindAll from 'lodash.bindall';
|
||||||
|
import Modes from '../modes/modes';
|
||||||
|
|
||||||
|
import {changeMode} from '../reducers/modes';
|
||||||
|
import {clearHoveredItem, setHoveredItem} from '../reducers/hover';
|
||||||
|
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
|
||||||
|
|
||||||
|
import {getSelectedLeafItems} from '../helper/selection';
|
||||||
|
import OvalTool from '../helper/tools/oval-tool';
|
||||||
|
import OvalModeComponent from '../components/oval-mode.jsx';
|
||||||
|
|
||||||
|
class OvalMode extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
bindAll(this, [
|
||||||
|
'activateTool',
|
||||||
|
'deactivateTool'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
if (this.props.isOvalModeActive) {
|
||||||
|
this.activateTool(this.props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (this.tool && nextProps.hoveredItemId !== this.props.hoveredItemId) {
|
||||||
|
this.tool.setPrevHoveredItemId(nextProps.hoveredItemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextProps.isOvalModeActive && !this.props.isOvalModeActive) {
|
||||||
|
this.activateTool();
|
||||||
|
} else if (!nextProps.isOvalModeActive && this.props.isOvalModeActive) {
|
||||||
|
this.deactivateTool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shouldComponentUpdate () {
|
||||||
|
return false; // Static component, for now
|
||||||
|
}
|
||||||
|
activateTool () {
|
||||||
|
this.tool = new OvalTool(
|
||||||
|
this.props.setHoveredItem,
|
||||||
|
this.props.clearHoveredItem,
|
||||||
|
this.props.setSelectedItems,
|
||||||
|
this.props.clearSelectedItems,
|
||||||
|
this.props.onUpdateSvg
|
||||||
|
);
|
||||||
|
this.tool.activate();
|
||||||
|
}
|
||||||
|
deactivateTool () {
|
||||||
|
this.tool.deactivateTool();
|
||||||
|
this.tool.remove();
|
||||||
|
this.tool = null;
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<OvalModeComponent onMouseDown={this.props.handleMouseDown} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OvalMode.propTypes = {
|
||||||
|
clearHoveredItem: PropTypes.func.isRequired,
|
||||||
|
clearSelectedItems: PropTypes.func.isRequired,
|
||||||
|
handleMouseDown: PropTypes.func.isRequired,
|
||||||
|
hoveredItemId: PropTypes.number,
|
||||||
|
isOvalModeActive: PropTypes.bool.isRequired,
|
||||||
|
onUpdateSvg: PropTypes.func.isRequired,
|
||||||
|
setHoveredItem: PropTypes.func.isRequired,
|
||||||
|
setSelectedItems: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
isOvalModeActive: state.scratchPaint.mode === Modes.OVAL,
|
||||||
|
hoveredItemId: state.scratchPaint.hoveredItemId
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
setHoveredItem: hoveredItemId => {
|
||||||
|
dispatch(setHoveredItem(hoveredItemId));
|
||||||
|
},
|
||||||
|
clearHoveredItem: () => {
|
||||||
|
dispatch(clearHoveredItem());
|
||||||
|
},
|
||||||
|
clearSelectedItems: () => {
|
||||||
|
dispatch(clearSelectedItems());
|
||||||
|
},
|
||||||
|
setSelectedItems: () => {
|
||||||
|
dispatch(setSelectedItems(getSelectedLeafItems()));
|
||||||
|
},
|
||||||
|
handleMouseDown: () => {
|
||||||
|
dispatch(changeMode(Modes.OVAL));
|
||||||
|
},
|
||||||
|
deactivateTool () {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(OvalMode);
|
102
src/containers/pen-mode.jsx
Normal file
102
src/containers/pen-mode.jsx
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import bindAll from 'lodash.bindall';
|
||||||
|
import Modes from '../modes/modes';
|
||||||
|
|
||||||
|
import {changeMode} from '../reducers/modes';
|
||||||
|
import {clearHoveredItem, setHoveredItem} from '../reducers/hover';
|
||||||
|
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
|
||||||
|
|
||||||
|
import {getSelectedLeafItems} from '../helper/selection';
|
||||||
|
import PenTool from '../helper/tools/pen-tool';
|
||||||
|
import PenModeComponent from '../components/pen-mode.jsx';
|
||||||
|
|
||||||
|
class PenMode extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
bindAll(this, [
|
||||||
|
'activateTool',
|
||||||
|
'deactivateTool'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
if (this.props.isPenModeActive) {
|
||||||
|
this.activateTool(this.props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (this.tool && nextProps.hoveredItemId !== this.props.hoveredItemId) {
|
||||||
|
this.tool.setPrevHoveredItemId(nextProps.hoveredItemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextProps.isPenModeActive && !this.props.isPenModeActive) {
|
||||||
|
this.activateTool();
|
||||||
|
} else if (!nextProps.isPenModeActive && this.props.isPenModeActive) {
|
||||||
|
this.deactivateTool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shouldComponentUpdate () {
|
||||||
|
return false; // Static component, for now
|
||||||
|
}
|
||||||
|
activateTool () {
|
||||||
|
this.tool = new PenTool(
|
||||||
|
this.props.setHoveredItem,
|
||||||
|
this.props.clearHoveredItem,
|
||||||
|
this.props.setSelectedItems,
|
||||||
|
this.props.clearSelectedItems,
|
||||||
|
this.props.onUpdateSvg
|
||||||
|
);
|
||||||
|
this.tool.activate();
|
||||||
|
}
|
||||||
|
deactivateTool () {
|
||||||
|
this.tool.deactivateTool();
|
||||||
|
this.tool.remove();
|
||||||
|
this.tool = null;
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<PenModeComponent onMouseDown={this.props.handleMouseDown} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PenMode.propTypes = {
|
||||||
|
clearHoveredItem: PropTypes.func.isRequired,
|
||||||
|
clearSelectedItems: PropTypes.func.isRequired,
|
||||||
|
handleMouseDown: PropTypes.func.isRequired,
|
||||||
|
hoveredItemId: PropTypes.number,
|
||||||
|
isPenModeActive: PropTypes.bool.isRequired,
|
||||||
|
onUpdateSvg: PropTypes.func.isRequired,
|
||||||
|
setHoveredItem: PropTypes.func.isRequired,
|
||||||
|
setSelectedItems: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
isPenModeActive: state.scratchPaint.mode === Modes.PEN,
|
||||||
|
hoveredItemId: state.scratchPaint.hoveredItemId
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
setHoveredItem: hoveredItemId => {
|
||||||
|
dispatch(setHoveredItem(hoveredItemId));
|
||||||
|
},
|
||||||
|
clearHoveredItem: () => {
|
||||||
|
dispatch(clearHoveredItem());
|
||||||
|
},
|
||||||
|
clearSelectedItems: () => {
|
||||||
|
dispatch(clearSelectedItems());
|
||||||
|
},
|
||||||
|
setSelectedItems: () => {
|
||||||
|
dispatch(setSelectedItems(getSelectedLeafItems()));
|
||||||
|
},
|
||||||
|
handleMouseDown: () => {
|
||||||
|
dispatch(changeMode(Modes.PEN));
|
||||||
|
},
|
||||||
|
deactivateTool () {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(PenMode);
|
102
src/containers/rect-mode.jsx
Normal file
102
src/containers/rect-mode.jsx
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import bindAll from 'lodash.bindall';
|
||||||
|
import Modes from '../modes/modes';
|
||||||
|
|
||||||
|
import {changeMode} from '../reducers/modes';
|
||||||
|
import {clearHoveredItem, setHoveredItem} from '../reducers/hover';
|
||||||
|
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
|
||||||
|
|
||||||
|
import {getSelectedLeafItems} from '../helper/selection';
|
||||||
|
import RectTool from '../helper/tools/rect-tool';
|
||||||
|
import RectModeComponent from '../components/rect-mode.jsx';
|
||||||
|
|
||||||
|
class RectMode extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
bindAll(this, [
|
||||||
|
'activateTool',
|
||||||
|
'deactivateTool'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
if (this.props.isRectModeActive) {
|
||||||
|
this.activateTool(this.props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (this.tool && nextProps.hoveredItemId !== this.props.hoveredItemId) {
|
||||||
|
this.tool.setPrevHoveredItemId(nextProps.hoveredItemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextProps.isRectModeActive && !this.props.isRectModeActive) {
|
||||||
|
this.activateTool();
|
||||||
|
} else if (!nextProps.isRectModeActive && this.props.isRectModeActive) {
|
||||||
|
this.deactivateTool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shouldComponentUpdate () {
|
||||||
|
return false; // Static component, for now
|
||||||
|
}
|
||||||
|
activateTool () {
|
||||||
|
this.tool = new RectTool(
|
||||||
|
this.props.setHoveredItem,
|
||||||
|
this.props.clearHoveredItem,
|
||||||
|
this.props.setSelectedItems,
|
||||||
|
this.props.clearSelectedItems,
|
||||||
|
this.props.onUpdateSvg
|
||||||
|
);
|
||||||
|
this.tool.activate();
|
||||||
|
}
|
||||||
|
deactivateTool () {
|
||||||
|
this.tool.deactivateTool();
|
||||||
|
this.tool.remove();
|
||||||
|
this.tool = null;
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<RectModeComponent onMouseDown={this.props.handleMouseDown} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RectMode.propTypes = {
|
||||||
|
clearHoveredItem: PropTypes.func.isRequired,
|
||||||
|
clearSelectedItems: PropTypes.func.isRequired,
|
||||||
|
handleMouseDown: PropTypes.func.isRequired,
|
||||||
|
hoveredItemId: PropTypes.number,
|
||||||
|
isRectModeActive: PropTypes.bool.isRequired,
|
||||||
|
onUpdateSvg: PropTypes.func.isRequired,
|
||||||
|
setHoveredItem: PropTypes.func.isRequired,
|
||||||
|
setSelectedItems: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
isRectModeActive: state.scratchPaint.mode === Modes.RECT,
|
||||||
|
hoveredItemId: state.scratchPaint.hoveredItemId
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
setHoveredItem: hoveredItemId => {
|
||||||
|
dispatch(setHoveredItem(hoveredItemId));
|
||||||
|
},
|
||||||
|
clearHoveredItem: () => {
|
||||||
|
dispatch(clearHoveredItem());
|
||||||
|
},
|
||||||
|
clearSelectedItems: () => {
|
||||||
|
dispatch(clearSelectedItems());
|
||||||
|
},
|
||||||
|
setSelectedItems: () => {
|
||||||
|
dispatch(setSelectedItems(getSelectedLeafItems()));
|
||||||
|
},
|
||||||
|
handleMouseDown: () => {
|
||||||
|
dispatch(changeMode(Modes.RECT));
|
||||||
|
},
|
||||||
|
deactivateTool () {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(RectMode);
|
102
src/containers/rounded-rect-mode.jsx
Normal file
102
src/containers/rounded-rect-mode.jsx
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import bindAll from 'lodash.bindall';
|
||||||
|
import Modes from '../modes/modes';
|
||||||
|
|
||||||
|
import {changeMode} from '../reducers/modes';
|
||||||
|
import {clearHoveredItem, setHoveredItem} from '../reducers/hover';
|
||||||
|
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
|
||||||
|
|
||||||
|
import {getSelectedLeafItems} from '../helper/selection';
|
||||||
|
import RoundedRectTool from '../helper/tools/rounded-rect-tool';
|
||||||
|
import RoundedRectModeComponent from '../components/rounded-rect-mode.jsx';
|
||||||
|
|
||||||
|
class RoundedRectMode extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
bindAll(this, [
|
||||||
|
'activateTool',
|
||||||
|
'deactivateTool'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
if (this.props.isRoundedRectModeActive) {
|
||||||
|
this.activateTool(this.props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (this.tool && nextProps.hoveredItemId !== this.props.hoveredItemId) {
|
||||||
|
this.tool.setPrevHoveredItemId(nextProps.hoveredItemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextProps.isRoundedRectModeActive && !this.props.isRoundedRectModeActive) {
|
||||||
|
this.activateTool();
|
||||||
|
} else if (!nextProps.isRoundedRectModeActive && this.props.isRoundedRectModeActive) {
|
||||||
|
this.deactivateTool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shouldComponentUpdate () {
|
||||||
|
return false; // Static component, for now
|
||||||
|
}
|
||||||
|
activateTool () {
|
||||||
|
this.tool = new RoundedRectTool(
|
||||||
|
this.props.setHoveredItem,
|
||||||
|
this.props.clearHoveredItem,
|
||||||
|
this.props.setSelectedItems,
|
||||||
|
this.props.clearSelectedItems,
|
||||||
|
this.props.onUpdateSvg
|
||||||
|
);
|
||||||
|
this.tool.activate();
|
||||||
|
}
|
||||||
|
deactivateTool () {
|
||||||
|
this.tool.deactivateTool();
|
||||||
|
this.tool.remove();
|
||||||
|
this.tool = null;
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<RoundedRectModeComponent onMouseDown={this.props.handleMouseDown} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RoundedRectMode.propTypes = {
|
||||||
|
clearHoveredItem: PropTypes.func.isRequired,
|
||||||
|
clearSelectedItems: PropTypes.func.isRequired,
|
||||||
|
handleMouseDown: PropTypes.func.isRequired,
|
||||||
|
hoveredItemId: PropTypes.number,
|
||||||
|
isRoundedRectModeActive: PropTypes.bool.isRequired,
|
||||||
|
onUpdateSvg: PropTypes.func.isRequired,
|
||||||
|
setHoveredItem: PropTypes.func.isRequired,
|
||||||
|
setSelectedItems: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
isRoundedRectModeActive: state.scratchPaint.mode === Modes.ROUNDED_RECT,
|
||||||
|
hoveredItemId: state.scratchPaint.hoveredItemId
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
setHoveredItem: hoveredItemId => {
|
||||||
|
dispatch(setHoveredItem(hoveredItemId));
|
||||||
|
},
|
||||||
|
clearHoveredItem: () => {
|
||||||
|
dispatch(clearHoveredItem());
|
||||||
|
},
|
||||||
|
clearSelectedItems: () => {
|
||||||
|
dispatch(clearSelectedItems());
|
||||||
|
},
|
||||||
|
setSelectedItems: () => {
|
||||||
|
dispatch(setSelectedItems(getSelectedLeafItems()));
|
||||||
|
},
|
||||||
|
handleMouseDown: () => {
|
||||||
|
dispatch(changeMode(Modes.ROUNDED_RECT));
|
||||||
|
},
|
||||||
|
deactivateTool () {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(RoundedRectMode);
|
54
src/helper/tools/oval-tool.js
Normal file
54
src/helper/tools/oval-tool.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import paper from '@scratch/paper';
|
||||||
|
import log from '../../log/log';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tool for drawing ovals.
|
||||||
|
*/
|
||||||
|
class OvalTool extends paper.Tool {
|
||||||
|
/**
|
||||||
|
* @param {function} setHoveredItem Callback to set the hovered item
|
||||||
|
* @param {function} clearHoveredItem Callback to clear the hovered item
|
||||||
|
* @param {function} setSelectedItems Callback to set the set of selected items in the Redux state
|
||||||
|
* @param {function} clearSelectedItems Callback to clear the set of selected items in the Redux state
|
||||||
|
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
|
||||||
|
*/
|
||||||
|
constructor (setHoveredItem, clearHoveredItem, setSelectedItems, clearSelectedItems, onUpdateSvg) {
|
||||||
|
super();
|
||||||
|
this.setHoveredItem = setHoveredItem;
|
||||||
|
this.clearHoveredItem = clearHoveredItem;
|
||||||
|
this.setSelectedItems = setSelectedItems;
|
||||||
|
this.clearSelectedItems = clearSelectedItems;
|
||||||
|
this.onUpdateSvg = onUpdateSvg;
|
||||||
|
this.prevHoveredItemId = null;
|
||||||
|
|
||||||
|
// We have to set these functions instead of just declaring them because
|
||||||
|
// paper.js tools hook up the listeners in the setter functions.
|
||||||
|
this.onMouseDown = this.handleMouseDown;
|
||||||
|
this.onMouseMove = this.handleMouseMove;
|
||||||
|
this.onMouseDrag = this.handleMouseDrag;
|
||||||
|
this.onMouseUp = this.handleMouseUp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be called when the hovered item changes. When the select tool hovers over a
|
||||||
|
* new item, it compares against this to see if a hover item change event needs to
|
||||||
|
* be fired.
|
||||||
|
* @param {paper.Item} prevHoveredItemId ID of the highlight item that indicates the mouse is
|
||||||
|
* over a given item currently
|
||||||
|
*/
|
||||||
|
setPrevHoveredItemId (prevHoveredItemId) {
|
||||||
|
this.prevHoveredItemId = prevHoveredItemId;
|
||||||
|
}
|
||||||
|
handleMouseDown () {
|
||||||
|
log.warn('Circle tool not yet implemented');
|
||||||
|
}
|
||||||
|
handleMouseMove () {
|
||||||
|
}
|
||||||
|
handleMouseDrag () {
|
||||||
|
}
|
||||||
|
handleMouseUp () {
|
||||||
|
}
|
||||||
|
deactivateTool () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OvalTool;
|
54
src/helper/tools/pen-tool.js
Normal file
54
src/helper/tools/pen-tool.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import paper from '@scratch/paper';
|
||||||
|
import log from '../../log/log';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tool to handle freehand drawing of lines.
|
||||||
|
*/
|
||||||
|
class PenTool extends paper.Tool {
|
||||||
|
/**
|
||||||
|
* @param {function} setHoveredItem Callback to set the hovered item
|
||||||
|
* @param {function} clearHoveredItem Callback to clear the hovered item
|
||||||
|
* @param {function} setSelectedItems Callback to set the set of selected items in the Redux state
|
||||||
|
* @param {function} clearSelectedItems Callback to clear the set of selected items in the Redux state
|
||||||
|
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
|
||||||
|
*/
|
||||||
|
constructor (setHoveredItem, clearHoveredItem, setSelectedItems, clearSelectedItems, onUpdateSvg) {
|
||||||
|
super();
|
||||||
|
this.setHoveredItem = setHoveredItem;
|
||||||
|
this.clearHoveredItem = clearHoveredItem;
|
||||||
|
this.setSelectedItems = setSelectedItems;
|
||||||
|
this.clearSelectedItems = clearSelectedItems;
|
||||||
|
this.onUpdateSvg = onUpdateSvg;
|
||||||
|
this.prevHoveredItemId = null;
|
||||||
|
|
||||||
|
// We have to set these functions instead of just declaring them because
|
||||||
|
// paper.js tools hook up the listeners in the setter functions.
|
||||||
|
this.onMouseDown = this.handleMouseDown;
|
||||||
|
this.onMouseMove = this.handleMouseMove;
|
||||||
|
this.onMouseDrag = this.handleMouseDrag;
|
||||||
|
this.onMouseUp = this.handleMouseUp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be called when the hovered item changes. When the select tool hovers over a
|
||||||
|
* new item, it compares against this to see if a hover item change event needs to
|
||||||
|
* be fired.
|
||||||
|
* @param {paper.Item} prevHoveredItemId ID of the highlight item that indicates the mouse is
|
||||||
|
* over a given item currently
|
||||||
|
*/
|
||||||
|
setPrevHoveredItemId (prevHoveredItemId) {
|
||||||
|
this.prevHoveredItemId = prevHoveredItemId;
|
||||||
|
}
|
||||||
|
handleMouseDown () {
|
||||||
|
log.warn('Pen not yet implemented');
|
||||||
|
}
|
||||||
|
handleMouseMove () {
|
||||||
|
}
|
||||||
|
handleMouseDrag () {
|
||||||
|
}
|
||||||
|
handleMouseUp () {
|
||||||
|
}
|
||||||
|
deactivateTool () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PenTool;
|
54
src/helper/tools/rect-tool.js
Normal file
54
src/helper/tools/rect-tool.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import paper from '@scratch/paper';
|
||||||
|
import log from '../../log/log';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tool for drawing rectangles.
|
||||||
|
*/
|
||||||
|
class RectTool extends paper.Tool {
|
||||||
|
/**
|
||||||
|
* @param {function} setHoveredItem Callback to set the hovered item
|
||||||
|
* @param {function} clearHoveredItem Callback to clear the hovered item
|
||||||
|
* @param {function} setSelectedItems Callback to set the set of selected items in the Redux state
|
||||||
|
* @param {function} clearSelectedItems Callback to clear the set of selected items in the Redux state
|
||||||
|
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
|
||||||
|
*/
|
||||||
|
constructor (setHoveredItem, clearHoveredItem, setSelectedItems, clearSelectedItems, onUpdateSvg) {
|
||||||
|
super();
|
||||||
|
this.setHoveredItem = setHoveredItem;
|
||||||
|
this.clearHoveredItem = clearHoveredItem;
|
||||||
|
this.setSelectedItems = setSelectedItems;
|
||||||
|
this.clearSelectedItems = clearSelectedItems;
|
||||||
|
this.onUpdateSvg = onUpdateSvg;
|
||||||
|
this.prevHoveredItemId = null;
|
||||||
|
|
||||||
|
// We have to set these functions instead of just declaring them because
|
||||||
|
// paper.js tools hook up the listeners in the setter functions.
|
||||||
|
this.onMouseDown = this.handleMouseDown;
|
||||||
|
this.onMouseMove = this.handleMouseMove;
|
||||||
|
this.onMouseDrag = this.handleMouseDrag;
|
||||||
|
this.onMouseUp = this.handleMouseUp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be called when the hovered item changes. When the select tool hovers over a
|
||||||
|
* new item, it compares against this to see if a hover item change event needs to
|
||||||
|
* be fired.
|
||||||
|
* @param {paper.Item} prevHoveredItemId ID of the highlight item that indicates the mouse is
|
||||||
|
* over a given item currently
|
||||||
|
*/
|
||||||
|
setPrevHoveredItemId (prevHoveredItemId) {
|
||||||
|
this.prevHoveredItemId = prevHoveredItemId;
|
||||||
|
}
|
||||||
|
handleMouseDown () {
|
||||||
|
log.warn('Rectangle tool not yet implemented');
|
||||||
|
}
|
||||||
|
handleMouseMove () {
|
||||||
|
}
|
||||||
|
handleMouseDrag () {
|
||||||
|
}
|
||||||
|
handleMouseUp () {
|
||||||
|
}
|
||||||
|
deactivateTool () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RectTool;
|
54
src/helper/tools/rounded-rect-tool.js
Normal file
54
src/helper/tools/rounded-rect-tool.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import paper from '@scratch/paper';
|
||||||
|
import log from '../../log/log';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tool for drawing rounded rectangles
|
||||||
|
*/
|
||||||
|
class RoundedRectTool extends paper.Tool {
|
||||||
|
/**
|
||||||
|
* @param {function} setHoveredItem Callback to set the hovered item
|
||||||
|
* @param {function} clearHoveredItem Callback to clear the hovered item
|
||||||
|
* @param {function} setSelectedItems Callback to set the set of selected items in the Redux state
|
||||||
|
* @param {function} clearSelectedItems Callback to clear the set of selected items in the Redux state
|
||||||
|
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
|
||||||
|
*/
|
||||||
|
constructor (setHoveredItem, clearHoveredItem, setSelectedItems, clearSelectedItems, onUpdateSvg) {
|
||||||
|
super();
|
||||||
|
this.setHoveredItem = setHoveredItem;
|
||||||
|
this.clearHoveredItem = clearHoveredItem;
|
||||||
|
this.setSelectedItems = setSelectedItems;
|
||||||
|
this.clearSelectedItems = clearSelectedItems;
|
||||||
|
this.onUpdateSvg = onUpdateSvg;
|
||||||
|
this.prevHoveredItemId = null;
|
||||||
|
|
||||||
|
// We have to set these functions instead of just declaring them because
|
||||||
|
// paper.js tools hook up the listeners in the setter functions.
|
||||||
|
this.onMouseDown = this.handleMouseDown;
|
||||||
|
this.onMouseMove = this.handleMouseMove;
|
||||||
|
this.onMouseDrag = this.handleMouseDrag;
|
||||||
|
this.onMouseUp = this.handleMouseUp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be called when the hovered item changes. When the select tool hovers over a
|
||||||
|
* new item, it compares against this to see if a hover item change event needs to
|
||||||
|
* be fired.
|
||||||
|
* @param {paper.Item} prevHoveredItemId ID of the highlight item that indicates the mouse is
|
||||||
|
* over a given item currently
|
||||||
|
*/
|
||||||
|
setPrevHoveredItemId (prevHoveredItemId) {
|
||||||
|
this.prevHoveredItemId = prevHoveredItemId;
|
||||||
|
}
|
||||||
|
handleMouseDown () {
|
||||||
|
log.warn('Rounded Rectangle tool not yet implemented');
|
||||||
|
}
|
||||||
|
handleMouseMove () {
|
||||||
|
}
|
||||||
|
handleMouseDrag () {
|
||||||
|
}
|
||||||
|
handleMouseUp () {
|
||||||
|
}
|
||||||
|
deactivateTool () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RoundedRectTool;
|
|
@ -5,7 +5,11 @@ const Modes = keyMirror({
|
||||||
ERASER: null,
|
ERASER: null,
|
||||||
LINE: null,
|
LINE: null,
|
||||||
SELECT: null,
|
SELECT: null,
|
||||||
RESHAPE: null
|
RESHAPE: null,
|
||||||
|
PEN: null,
|
||||||
|
OVAL: null,
|
||||||
|
RECT: null,
|
||||||
|
ROUNDED_RECT: null
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Modes;
|
export default Modes;
|
||||||
|
|
Loading…
Reference in a new issue