diff --git a/src/helper/selection-tools/bounding-box-tool.js b/src/helper/selection-tools/bounding-box-tool.js index 54145d0b..1bbdd25b 100644 --- a/src/helper/selection-tools/bounding-box-tool.js +++ b/src/helper/selection-tools/bounding-box-tool.js @@ -84,8 +84,8 @@ class BoundingBoxTool { const hitProperties = { hitResult: hitResult, - clone: event.modifiers.alt, - multiselect: event.modifiers.shift + clone: clone, + multiselect: multiselect }; if (this.mode === BoundingBoxModes.MOVE) { this._modeMap[this.mode].onMouseDown(hitProperties); diff --git a/src/helper/tools/rect-tool.js b/src/helper/tools/rect-tool.js index c6a451d4..8ec0dfec 100644 --- a/src/helper/tools/rect-tool.js +++ b/src/helper/tools/rect-tool.js @@ -1,12 +1,16 @@ import paper from '@scratch/paper'; import Modes from '../../modes/modes'; import {styleShape} from '../style-path'; +import {clearSelection} from '../selection'; import BoundingBoxTool from '../selection-tools/bounding-box-tool'; /** * Tool for drawing rectangles. */ class RectTool extends paper.Tool { + static get TOLERANCE () { + return 6; + } /** * @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 @@ -14,33 +18,66 @@ class RectTool extends paper.Tool { */ constructor (setSelectedItems, clearSelectedItems, onUpdateSvg) { super(); + this.clearSelectedItems = clearSelectedItems; this.onUpdateSvg = onUpdateSvg; this.prevHoveredItemId = null; this.boundingBoxTool = new BoundingBoxTool(Modes.SELECT, setSelectedItems, clearSelectedItems, onUpdateSvg); // 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.onMouseDrag = this.handleMouseDrag; this.onMouseUp = this.handleMouseUp; this.downPoint = null; this.rect = null; this.colorState = null; + this.isBoundingBoxMode = null; + } + getHitOptions () { + return { + segments: true, + stroke: true, + curves: true, + fill: true, + guide: false, + match: hitResult => + (hitResult.item.data && hitResult.item.data.isHelperItem) || + hitResult.item.selected, // Allow hits on bounding box and selected only + tolerance: RectTool.TOLERANCE / paper.view.zoom + }; } setColorState (colorState) { this.colorState = colorState; } + handleMouseDown (event) { + const clickedItem = paper.project.hitTest(event.point, this.getHitOptions()); + if (clickedItem) { + this.isBoundingBoxMode = true; + this.boundingBoxTool.onMouseDown(event, false /* clone */, false /* multiselect */, this.getHitOptions()); + } else { + this.isBoundingBoxMode = false; + this.boundingBoxTool.removeBoundsPath(); + clearSelection(this.clearSelectedItems); + } + } handleMouseDrag (event) { if (event.event.button > 0) return; // only first mouse button + if (this.isBoundingBoxMode) { + this.boundingBoxTool.onMouseDrag(event); + return; + } + if (this.rect) { this.rect.remove(); } - this.rect = new paper.Path.Rectangle(event.downPoint, event.point); - + + const rect = new paper.Rectangle(event.downPoint, event.point); if (event.modifiers.shift) { - this.rect.height = this.rect.width; + rect.height = rect.width; } + this.rect = new paper.Path.Rectangle(rect); if (event.modifiers.alt) { this.rect.position = event.downPoint; @@ -51,15 +88,21 @@ class RectTool extends paper.Tool { handleMouseUp (event) { if (event.event.button > 0) return; // only first mouse button + if (this.isBoundingBoxMode) { + this.boundingBoxTool.onMouseUp(event); + this.isBoundingBoxMode = null; + return; + } + if (this.rect) { + this.rect.selected = true; + this.boundingBoxTool.setSelectionBounds(); this.onUpdateSvg(); this.rect = null; } } deactivateTool () { - this.downPoint = null; - this.rect = null; - this.colorState = null; + this.boundingBoxTool.removeBoundsPath(); } }