diff --git a/src/components/paint-editor/paint-editor.jsx b/src/components/paint-editor/paint-editor.jsx index 37d45c70..7e5c82e9 100644 --- a/src/components/paint-editor/paint-editor.jsx +++ b/src/components/paint-editor/paint-editor.jsx @@ -225,6 +225,7 @@ class PaintEditorComponent extends React.Component { rotationCenterY={this.props.rotationCenterY} svg={this.props.svg} svgId={this.props.svgId} + onUpdateSvg={this.props.onUpdateSvg} /> diff --git a/src/containers/paper-canvas.jsx b/src/containers/paper-canvas.jsx index 5548db6b..b2835132 100644 --- a/src/containers/paper-canvas.jsx +++ b/src/containers/paper-canvas.jsx @@ -3,11 +3,14 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import paper from '@scratch/paper'; +import Modes from '../modes/modes'; import {performSnapshot} from '../helper/undo'; import {undoSnapshot, clearUndoState} from '../reducers/undo'; import {isGroup, ungroupItems} from '../helper/group'; import {setupLayers} from '../helper/layer'; +import {deleteSelection, getSelectedLeafItems} from '../helper/selection'; +import {setSelectedItems} from '../reducers/selected-items'; import styles from './paper-canvas.css'; @@ -16,10 +19,12 @@ class PaperCanvas extends React.Component { super(props); bindAll(this, [ 'setCanvas', - 'importSvg' + 'importSvg', + 'handleKeyDown' ]); } componentDidMount () { + document.addEventListener('keydown', this.handleKeyDown); paper.setup(this.canvas); // Don't show handles by default paper.settings.handleSize = 0; @@ -45,6 +50,19 @@ class PaperCanvas extends React.Component { } componentWillUnmount () { paper.remove(); + document.removeEventListener('keydown', this.handleKeyDown); + } + handleKeyDown (event) { + if (event.target instanceof HTMLInputElement) { + // Ignore delete if a text input field is focused + return; + } + // Backspace, delete + if (event.key.toLowerCase() === 'delete' || event.key.toLowerCase() === 'backspace') { + if (deleteSelection(this.props.mode, this.props.onUpdateSvg)) { + this.props.setSelectedItems(); + } + } } importSvg (svg, rotationCenterX, rotationCenterY) { const paperCanvas = this; @@ -111,22 +129,31 @@ class PaperCanvas extends React.Component { PaperCanvas.propTypes = { canvasRef: PropTypes.func, clearUndo: PropTypes.func.isRequired, + mode: PropTypes.instanceOf(Modes), + onUpdateSvg: PropTypes.func.isRequired, rotationCenterX: PropTypes.number, rotationCenterY: PropTypes.number, + setSelectedItems: PropTypes.func.isRequired, svg: PropTypes.string, svgId: PropTypes.string, undoSnapshot: PropTypes.func.isRequired }; +const mapStateToProps = state => ({ + mode: state.scratchPaint.mode +}); const mapDispatchToProps = dispatch => ({ undoSnapshot: snapshot => { dispatch(undoSnapshot(snapshot)); }, clearUndo: () => { dispatch(clearUndoState()); + }, + setSelectedItems: () => { + dispatch(setSelectedItems(getSelectedLeafItems())); } }); export default connect( - null, + mapStateToProps, mapDispatchToProps )(PaperCanvas); diff --git a/src/helper/selection-tools/reshape-tool.js b/src/helper/selection-tools/reshape-tool.js index 15a50f44..80a340c6 100644 --- a/src/helper/selection-tools/reshape-tool.js +++ b/src/helper/selection-tools/reshape-tool.js @@ -4,7 +4,6 @@ import keyMirror from 'keymirror'; import Modes from '../../modes/modes'; import {getHoveredItem} from '../hover'; -import {deleteSelection} from '../selection'; import {getRootItem, isPGTextItem} from '../item'; import MoveTool from './move-tool'; import PointTool from './point-tool'; @@ -67,7 +66,6 @@ class ReshapeTool extends paper.Tool { this.onMouseMove = this.handleMouseMove; this.onMouseDrag = this.handleMouseDrag; this.onMouseUp = this.handleMouseUp; - this.onKeyUp = this.handleKeyUp; paper.settings.handleSize = 8; } @@ -227,12 +225,6 @@ class ReshapeTool extends paper.Tool { this._modeMap[this.mode].onMouseUp(event); this.mode = ReshapeModes.SELECTION_BOX; } - handleKeyUp (event) { - // Backspace, delete - if (event.key === 'delete' || event.key === 'backspace') { - deleteSelection(Modes.RESHAPE, this.onUpdateSvg); - } - } deactivateTool () { paper.settings.handleSize = 0; this.clearHoveredItem(); diff --git a/src/helper/selection-tools/select-tool.js b/src/helper/selection-tools/select-tool.js index 1f3e513d..fb8dada3 100644 --- a/src/helper/selection-tools/select-tool.js +++ b/src/helper/selection-tools/select-tool.js @@ -1,7 +1,7 @@ import Modes from '../../modes/modes'; import {getHoveredItem} from '../hover'; -import {deleteSelection, selectRootItem} from '../selection'; +import {selectRootItem} from '../selection'; import BoundingBoxTool from './bounding-box-tool'; import SelectionBoxTool from './selection-box-tool'; import paper from '@scratch/paper'; @@ -41,7 +41,6 @@ class SelectTool extends paper.Tool { this.onMouseMove = this.handleMouseMove; this.onMouseDrag = this.handleMouseDrag; this.onMouseUp = this.handleMouseUp; - this.onKeyUp = this.handleKeyUp; selectRootItem(); setSelectedItems(); @@ -130,14 +129,6 @@ class SelectTool extends paper.Tool { } this.selectionBoxMode = false; } - handleKeyUp (event) { - // Backspace, delete - if (event.key === 'delete' || event.key === 'backspace') { - deleteSelection(Modes.SELECT, this.onUpdateSvg); - this.clearHoveredItem(); - this.boundingBoxTool.removeBoundsPath(); - } - } deactivateTool () { this.clearHoveredItem(); this.boundingBoxTool.removeBoundsPath(); diff --git a/src/helper/selection.js b/src/helper/selection.js index a5a403b0..9f11b496 100644 --- a/src/helper/selection.js +++ b/src/helper/selection.js @@ -177,17 +177,19 @@ const getSelectedLeafItems = function () { }; const _deleteItemSelection = function (items, onUpdateSvg) { + // @todo: Update toolbar state on change + if (items.length === 0) { + return false; + } for (let i = 0; i < items.length; i++) { items[i].remove(); } - - // @todo: Update toolbar state on change - if (items.length > 0) { - paper.project.view.update(); - onUpdateSvg(); - } + paper.project.view.update(); + onUpdateSvg(); + return true; }; +// Return true if anything was removed const _removeSelectedSegments = function (items, onUpdateSvg) { const segmentsToRemove = []; @@ -214,17 +216,18 @@ const _removeSelectedSegments = function (items, onUpdateSvg) { return removedSegments; }; +// Return whether anything was deleted const deleteSelection = function (mode, onUpdateSvg) { if (mode === Modes.RESHAPE) { const selectedItems = getSelectedLeafItems(); // If there are points selected remove them. If not delete the item selected. - if (!_removeSelectedSegments(selectedItems, onUpdateSvg)) { - _deleteItemSelection(selectedItems, onUpdateSvg); + if (_removeSelectedSegments(selectedItems, onUpdateSvg)) { + return true; } - } else { - const selectedItems = getSelectedRootItems(); - _deleteItemSelection(selectedItems, onUpdateSvg); + return _deleteItemSelection(selectedItems, onUpdateSvg); } + const selectedItems = getSelectedRootItems(); + return _deleteItemSelection(selectedItems, onUpdateSvg); }; const cloneSelection = function (recursive, onUpdateSvg) { diff --git a/src/helper/tools/oval-tool.js b/src/helper/tools/oval-tool.js index 282f3fe3..fff6bf5c 100644 --- a/src/helper/tools/oval-tool.js +++ b/src/helper/tools/oval-tool.js @@ -1,7 +1,7 @@ import paper from '@scratch/paper'; import Modes from '../../modes/modes'; import {styleShape} from '../style-path'; -import {clearSelection, deleteSelection} from '../selection'; +import {clearSelection} from '../selection'; import BoundingBoxTool from '../selection-tools/bounding-box-tool'; /** @@ -117,13 +117,6 @@ class OvalTool extends paper.Tool { } } } - handleKeyUp (event) { - // Backspace, delete - if (event.key === 'delete' || event.key === 'backspace') { - deleteSelection(Modes.RESHAPE, this.onUpdateSvg); - this.boundingBoxTool.removeBoundsPath(); - } - } deactivateTool () { this.boundingBoxTool.removeBoundsPath(); } diff --git a/src/helper/tools/rect-tool.js b/src/helper/tools/rect-tool.js index ba5496d2..b7447ad8 100644 --- a/src/helper/tools/rect-tool.js +++ b/src/helper/tools/rect-tool.js @@ -1,7 +1,7 @@ import paper from '@scratch/paper'; import Modes from '../../modes/modes'; import {styleShape} from '../style-path'; -import {clearSelection, deleteSelection} from '../selection'; +import {clearSelection} from '../selection'; import BoundingBoxTool from '../selection-tools/bounding-box-tool'; /** @@ -28,7 +28,6 @@ class RectTool extends paper.Tool { this.onMouseDown = this.handleMouseDown; this.onMouseDrag = this.handleMouseDrag; this.onMouseUp = this.handleMouseUp; - this.onKeyUp = this.handleKeyUp; this.rect = null; this.colorState = null; @@ -111,13 +110,6 @@ class RectTool extends paper.Tool { } } } - handleKeyUp (event) { - // Backspace, delete - if (event.key === 'delete' || event.key === 'backspace') { - deleteSelection(Modes.RESHAPE, this.onUpdateSvg); - this.boundingBoxTool.removeBoundsPath(); - } - } deactivateTool () { this.boundingBoxTool.removeBoundsPath(); }