scratch-paint/src/containers/select-mode.jsx

154 lines
4.7 KiB
React
Raw Normal View History

2017-09-11 10:52:00 -04:00
import PropTypes from 'prop-types';
import React from 'react';
import {connect} from 'react-redux';
import bindAll from 'lodash.bindall';
import Modes from '../modes/modes';
2017-09-11 14:23:30 -04:00
2017-09-11 10:52:00 -04:00
import {changeMode} from '../reducers/modes';
2017-09-11 14:23:30 -04:00
import {setHoveredItem, clearHoveredItem} from '../reducers/hover';
import {getHoveredItem} from '../helper/hover';
import {rectSelect} from '../helper/guides';
import {clearSelection, selectRootItem, processRectangularSelection} from '../helper/selection';
2017-09-11 10:52:00 -04:00
import SelectModeComponent from '../components/select-mode.jsx';
2017-09-11 14:23:30 -04:00
import BoundingBoxTool from '../helper/bounding-box/bounding-box-tool';
2017-09-11 10:52:00 -04:00
import paper from 'paper';
class SelectMode extends React.Component {
static get TOLERANCE () {
return 6;
}
constructor (props) {
super(props);
bindAll(this, [
'activateTool',
'deactivateTool',
'getHitOptions',
'preProcessSelection',
'onMouseDown',
'onMouseMove',
'onMouseDrag',
'onMouseUp'
]);
this._hitOptions = {
segments: true,
stroke: true,
curves: true,
fill: true,
guide: false
};
2017-09-11 14:23:30 -04:00
this.boundingBoxTool = new BoundingBoxTool();
this.selectionBoxMode = false;
this.selectionRect = null;
2017-09-11 10:52:00 -04:00
}
componentDidMount () {
if (this.props.isSelectModeActive) {
this.activateTool(this.props);
}
}
componentWillReceiveProps (nextProps) {
if (nextProps.isSelectModeActive && !this.props.isSelectModeActive) {
this.activateTool();
} else if (!nextProps.isSelectModeActive && this.props.isSelectModeActive) {
this.deactivateTool();
}
}
shouldComponentUpdate () {
return false; // Static component, for now
}
2017-09-11 14:23:30 -04:00
getHitOptions (preselectedOnly) {
2017-09-11 10:52:00 -04:00
this._hitOptions.tolerance = SelectMode.TOLERANCE / paper.view.zoom;
2017-09-11 14:23:30 -04:00
if (preselectedOnly) {
this._hitOptions.selected = true;
} else {
delete this._hitOptions.selected;
}
2017-09-11 10:52:00 -04:00
return this._hitOptions;
}
activateTool () {
clearSelection();
2017-09-11 14:23:30 -04:00
selectRootItem();
2017-09-11 10:52:00 -04:00
this.tool = new paper.Tool();
this.tool.onMouseDown = function (event) {
2017-09-11 14:23:30 -04:00
if (event.event.button > 0) return; // only first mouse button
this.props.clearHoveredItem();
if (!this.boundingBoxTool.onMouseDown(
event, event.modifiers.alt, event.modifiers.shift, true /* preselectedOnly */)) {
this.selectionBoxMode = true;
}
2017-09-11 10:52:00 -04:00
};
this.tool.onMouseMove = function (event) {
2017-09-11 14:23:30 -04:00
this.props.setHoveredItem(getHoveredItem(event, this.getHitOptions()));
2017-09-11 10:52:00 -04:00
};
this.tool.onMouseDrag = function (event) {
2017-09-11 14:23:30 -04:00
if (event.event.button > 0) return; // only first mouse button
if (this.selectionBoxMode) {
this.selectionRect = rectSelect(event);
// Remove this rect on the next drag and up event
this.selectionRect.removeOnDrag();
} else {
this.boundingBoxTool.onMouseDrag(event);
}
2017-09-11 10:52:00 -04:00
};
this.tool.onMouseUp = function (event) {
2017-09-11 14:23:30 -04:00
if (event.event.button > 0) return; // only first mouse button
if (this.selectionBoxMode) {
processRectangularSelection(event, this.selectionRect);
this.selectionRect.remove();
} else {
this.boundingBoxTool.onMouseUp(event);
this.props.onUpdateSvg();
}
this.selectionBoxMode = false;
this.selectionRect = null;
2017-09-11 10:52:00 -04:00
};
this.tool.activate();
}
deactivateTool () {
this.props.setHoveredItem();
this.tool.remove();
this.tool = null;
this.hitResult = null;
}
render () {
return (
<SelectModeComponent onMouseDown={this.props.handleMouseDown} />
);
}
}
SelectMode.propTypes = {
2017-09-11 14:23:30 -04:00
clearHoveredItem: PropTypes.func.isRequired,
2017-09-11 10:52:00 -04:00
handleMouseDown: PropTypes.func.isRequired,
isSelectModeActive: PropTypes.bool.isRequired,
2017-09-11 14:23:30 -04:00
onUpdateSvg: PropTypes.func.isRequired,
setHoveredItem: PropTypes.func.isRequired
2017-09-11 10:52:00 -04:00
};
const mapStateToProps = state => ({
isSelectModeActive: state.scratchPaint.mode === Modes.SELECT
});
const mapDispatchToProps = dispatch => ({
setHoveredItem: hoveredItem => {
dispatch(setHoveredItem(hoveredItem));
},
2017-09-11 14:23:30 -04:00
clearHoveredItem: () => {
dispatch(clearHoveredItem());
},
2017-09-11 10:52:00 -04:00
handleMouseDown: () => {
dispatch(changeMode(Modes.SELECT));
}
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(SelectMode);