mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2025-01-10 14:42:13 -05:00
Move delete out of tools so its always available
This commit is contained in:
parent
67562c8799
commit
7ca851985e
7 changed files with 47 additions and 48 deletions
|
@ -225,6 +225,7 @@ class PaintEditorComponent extends React.Component {
|
||||||
rotationCenterY={this.props.rotationCenterY}
|
rotationCenterY={this.props.rotationCenterY}
|
||||||
svg={this.props.svg}
|
svg={this.props.svg}
|
||||||
svgId={this.props.svgId}
|
svgId={this.props.svgId}
|
||||||
|
onUpdateSvg={this.props.onUpdateSvg}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,11 +3,14 @@ import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import paper from '@scratch/paper';
|
import paper from '@scratch/paper';
|
||||||
|
import Modes from '../modes/modes';
|
||||||
|
|
||||||
import {performSnapshot} from '../helper/undo';
|
import {performSnapshot} from '../helper/undo';
|
||||||
import {undoSnapshot, clearUndoState} from '../reducers/undo';
|
import {undoSnapshot, clearUndoState} from '../reducers/undo';
|
||||||
import {isGroup, ungroupItems} from '../helper/group';
|
import {isGroup, ungroupItems} from '../helper/group';
|
||||||
import {setupLayers} from '../helper/layer';
|
import {setupLayers} from '../helper/layer';
|
||||||
|
import {deleteSelection, getSelectedLeafItems} from '../helper/selection';
|
||||||
|
import {setSelectedItems} from '../reducers/selected-items';
|
||||||
|
|
||||||
import styles from './paper-canvas.css';
|
import styles from './paper-canvas.css';
|
||||||
|
|
||||||
|
@ -16,10 +19,12 @@ class PaperCanvas extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
bindAll(this, [
|
bindAll(this, [
|
||||||
'setCanvas',
|
'setCanvas',
|
||||||
'importSvg'
|
'importSvg',
|
||||||
|
'handleKeyDown'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
|
document.addEventListener('keydown', this.handleKeyDown);
|
||||||
paper.setup(this.canvas);
|
paper.setup(this.canvas);
|
||||||
// Don't show handles by default
|
// Don't show handles by default
|
||||||
paper.settings.handleSize = 0;
|
paper.settings.handleSize = 0;
|
||||||
|
@ -45,6 +50,19 @@ class PaperCanvas extends React.Component {
|
||||||
}
|
}
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
paper.remove();
|
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) {
|
importSvg (svg, rotationCenterX, rotationCenterY) {
|
||||||
const paperCanvas = this;
|
const paperCanvas = this;
|
||||||
|
@ -111,22 +129,31 @@ class PaperCanvas extends React.Component {
|
||||||
PaperCanvas.propTypes = {
|
PaperCanvas.propTypes = {
|
||||||
canvasRef: PropTypes.func,
|
canvasRef: PropTypes.func,
|
||||||
clearUndo: PropTypes.func.isRequired,
|
clearUndo: PropTypes.func.isRequired,
|
||||||
|
mode: PropTypes.instanceOf(Modes),
|
||||||
|
onUpdateSvg: PropTypes.func.isRequired,
|
||||||
rotationCenterX: PropTypes.number,
|
rotationCenterX: PropTypes.number,
|
||||||
rotationCenterY: PropTypes.number,
|
rotationCenterY: PropTypes.number,
|
||||||
|
setSelectedItems: PropTypes.func.isRequired,
|
||||||
svg: PropTypes.string,
|
svg: PropTypes.string,
|
||||||
svgId: PropTypes.string,
|
svgId: PropTypes.string,
|
||||||
undoSnapshot: PropTypes.func.isRequired
|
undoSnapshot: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
mode: state.scratchPaint.mode
|
||||||
|
});
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
undoSnapshot: snapshot => {
|
undoSnapshot: snapshot => {
|
||||||
dispatch(undoSnapshot(snapshot));
|
dispatch(undoSnapshot(snapshot));
|
||||||
},
|
},
|
||||||
clearUndo: () => {
|
clearUndo: () => {
|
||||||
dispatch(clearUndoState());
|
dispatch(clearUndoState());
|
||||||
|
},
|
||||||
|
setSelectedItems: () => {
|
||||||
|
dispatch(setSelectedItems(getSelectedLeafItems()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
null,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps
|
||||||
)(PaperCanvas);
|
)(PaperCanvas);
|
||||||
|
|
|
@ -4,7 +4,6 @@ import keyMirror from 'keymirror';
|
||||||
|
|
||||||
import Modes from '../../modes/modes';
|
import Modes from '../../modes/modes';
|
||||||
import {getHoveredItem} from '../hover';
|
import {getHoveredItem} from '../hover';
|
||||||
import {deleteSelection} from '../selection';
|
|
||||||
import {getRootItem, isPGTextItem} from '../item';
|
import {getRootItem, isPGTextItem} from '../item';
|
||||||
import MoveTool from './move-tool';
|
import MoveTool from './move-tool';
|
||||||
import PointTool from './point-tool';
|
import PointTool from './point-tool';
|
||||||
|
@ -67,7 +66,6 @@ class ReshapeTool extends paper.Tool {
|
||||||
this.onMouseMove = this.handleMouseMove;
|
this.onMouseMove = this.handleMouseMove;
|
||||||
this.onMouseDrag = this.handleMouseDrag;
|
this.onMouseDrag = this.handleMouseDrag;
|
||||||
this.onMouseUp = this.handleMouseUp;
|
this.onMouseUp = this.handleMouseUp;
|
||||||
this.onKeyUp = this.handleKeyUp;
|
|
||||||
|
|
||||||
paper.settings.handleSize = 8;
|
paper.settings.handleSize = 8;
|
||||||
}
|
}
|
||||||
|
@ -227,12 +225,6 @@ class ReshapeTool extends paper.Tool {
|
||||||
this._modeMap[this.mode].onMouseUp(event);
|
this._modeMap[this.mode].onMouseUp(event);
|
||||||
this.mode = ReshapeModes.SELECTION_BOX;
|
this.mode = ReshapeModes.SELECTION_BOX;
|
||||||
}
|
}
|
||||||
handleKeyUp (event) {
|
|
||||||
// Backspace, delete
|
|
||||||
if (event.key === 'delete' || event.key === 'backspace') {
|
|
||||||
deleteSelection(Modes.RESHAPE, this.onUpdateSvg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deactivateTool () {
|
deactivateTool () {
|
||||||
paper.settings.handleSize = 0;
|
paper.settings.handleSize = 0;
|
||||||
this.clearHoveredItem();
|
this.clearHoveredItem();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Modes from '../../modes/modes';
|
import Modes from '../../modes/modes';
|
||||||
|
|
||||||
import {getHoveredItem} from '../hover';
|
import {getHoveredItem} from '../hover';
|
||||||
import {deleteSelection, selectRootItem} from '../selection';
|
import {selectRootItem} from '../selection';
|
||||||
import BoundingBoxTool from './bounding-box-tool';
|
import BoundingBoxTool from './bounding-box-tool';
|
||||||
import SelectionBoxTool from './selection-box-tool';
|
import SelectionBoxTool from './selection-box-tool';
|
||||||
import paper from '@scratch/paper';
|
import paper from '@scratch/paper';
|
||||||
|
@ -41,7 +41,6 @@ class SelectTool extends paper.Tool {
|
||||||
this.onMouseMove = this.handleMouseMove;
|
this.onMouseMove = this.handleMouseMove;
|
||||||
this.onMouseDrag = this.handleMouseDrag;
|
this.onMouseDrag = this.handleMouseDrag;
|
||||||
this.onMouseUp = this.handleMouseUp;
|
this.onMouseUp = this.handleMouseUp;
|
||||||
this.onKeyUp = this.handleKeyUp;
|
|
||||||
|
|
||||||
selectRootItem();
|
selectRootItem();
|
||||||
setSelectedItems();
|
setSelectedItems();
|
||||||
|
@ -130,14 +129,6 @@ class SelectTool extends paper.Tool {
|
||||||
}
|
}
|
||||||
this.selectionBoxMode = false;
|
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 () {
|
deactivateTool () {
|
||||||
this.clearHoveredItem();
|
this.clearHoveredItem();
|
||||||
this.boundingBoxTool.removeBoundsPath();
|
this.boundingBoxTool.removeBoundsPath();
|
||||||
|
|
|
@ -177,17 +177,19 @@ const getSelectedLeafItems = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
const _deleteItemSelection = function (items, onUpdateSvg) {
|
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++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
items[i].remove();
|
items[i].remove();
|
||||||
}
|
}
|
||||||
|
paper.project.view.update();
|
||||||
// @todo: Update toolbar state on change
|
onUpdateSvg();
|
||||||
if (items.length > 0) {
|
return true;
|
||||||
paper.project.view.update();
|
|
||||||
onUpdateSvg();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Return true if anything was removed
|
||||||
const _removeSelectedSegments = function (items, onUpdateSvg) {
|
const _removeSelectedSegments = function (items, onUpdateSvg) {
|
||||||
const segmentsToRemove = [];
|
const segmentsToRemove = [];
|
||||||
|
|
||||||
|
@ -214,17 +216,18 @@ const _removeSelectedSegments = function (items, onUpdateSvg) {
|
||||||
return removedSegments;
|
return removedSegments;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Return whether anything was deleted
|
||||||
const deleteSelection = function (mode, onUpdateSvg) {
|
const deleteSelection = function (mode, onUpdateSvg) {
|
||||||
if (mode === Modes.RESHAPE) {
|
if (mode === Modes.RESHAPE) {
|
||||||
const selectedItems = getSelectedLeafItems();
|
const selectedItems = getSelectedLeafItems();
|
||||||
// If there are points selected remove them. If not delete the item selected.
|
// If there are points selected remove them. If not delete the item selected.
|
||||||
if (!_removeSelectedSegments(selectedItems, onUpdateSvg)) {
|
if (_removeSelectedSegments(selectedItems, onUpdateSvg)) {
|
||||||
_deleteItemSelection(selectedItems, onUpdateSvg);
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
return _deleteItemSelection(selectedItems, onUpdateSvg);
|
||||||
const selectedItems = getSelectedRootItems();
|
|
||||||
_deleteItemSelection(selectedItems, onUpdateSvg);
|
|
||||||
}
|
}
|
||||||
|
const selectedItems = getSelectedRootItems();
|
||||||
|
return _deleteItemSelection(selectedItems, onUpdateSvg);
|
||||||
};
|
};
|
||||||
|
|
||||||
const cloneSelection = function (recursive, onUpdateSvg) {
|
const cloneSelection = function (recursive, onUpdateSvg) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import paper from '@scratch/paper';
|
import paper from '@scratch/paper';
|
||||||
import Modes from '../../modes/modes';
|
import Modes from '../../modes/modes';
|
||||||
import {styleShape} from '../style-path';
|
import {styleShape} from '../style-path';
|
||||||
import {clearSelection, deleteSelection} from '../selection';
|
import {clearSelection} from '../selection';
|
||||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
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 () {
|
deactivateTool () {
|
||||||
this.boundingBoxTool.removeBoundsPath();
|
this.boundingBoxTool.removeBoundsPath();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import paper from '@scratch/paper';
|
import paper from '@scratch/paper';
|
||||||
import Modes from '../../modes/modes';
|
import Modes from '../../modes/modes';
|
||||||
import {styleShape} from '../style-path';
|
import {styleShape} from '../style-path';
|
||||||
import {clearSelection, deleteSelection} from '../selection';
|
import {clearSelection} from '../selection';
|
||||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,6 @@ class RectTool extends paper.Tool {
|
||||||
this.onMouseDown = this.handleMouseDown;
|
this.onMouseDown = this.handleMouseDown;
|
||||||
this.onMouseDrag = this.handleMouseDrag;
|
this.onMouseDrag = this.handleMouseDrag;
|
||||||
this.onMouseUp = this.handleMouseUp;
|
this.onMouseUp = this.handleMouseUp;
|
||||||
this.onKeyUp = this.handleKeyUp;
|
|
||||||
|
|
||||||
this.rect = null;
|
this.rect = null;
|
||||||
this.colorState = 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 () {
|
deactivateTool () {
|
||||||
this.boundingBoxTool.removeBoundsPath();
|
this.boundingBoxTool.removeBoundsPath();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue