Move select tool out of select mode

This commit is contained in:
DD 2017-09-21 18:20:44 -04:00
parent f15a3dbe02
commit 4bc4d92415
12 changed files with 135 additions and 199 deletions

View file

@ -35,7 +35,15 @@ class PaperCanvas extends React.Component {
onLoad: function (item) { onLoad: function (item) {
// Remove viewbox // Remove viewbox
if (item.clipped) { if (item.clipped) {
let mask;
for (const child of item.children) {
if (child.isClipMask()) {
mask = child;
break;
}
}
item.clipped = false; item.clipped = false;
mask.remove();
// Consider removing clip mask here? // Consider removing clip mask here?
} }
while (item.reduce() !== item) { while (item.reduce() !== item) {

View file

@ -7,7 +7,6 @@ import Modes from '../modes/modes';
import {changeMode} from '../reducers/modes'; import {changeMode} from '../reducers/modes';
import {setHoveredItem, clearHoveredItem} from '../reducers/hover'; import {setHoveredItem, clearHoveredItem} from '../reducers/hover';
import {selectSubItems} from '../helper/selection';
import ReshapeTool from '../helper/selection-tools/reshape-tool'; import ReshapeTool from '../helper/selection-tools/reshape-tool';
import ReshapeModeComponent from '../components/reshape-mode.jsx'; import ReshapeModeComponent from '../components/reshape-mode.jsx';
import paper from 'paper'; import paper from 'paper';
@ -41,15 +40,12 @@ class ReshapeMode extends React.Component {
return false; // Static component, for now return false; // Static component, for now
} }
activateTool () { activateTool () {
selectSubItems(); this.tool = new ReshapeTool(this.props.setHoveredItem, this.props.clearHoveredItem, this.props.onUpdateSvg);
this.tool = new ReshapeTool(this.props.setHoveredItem, this.props.clearHoveredItem);
this.tool.setPrevHoveredItem(this.props.hoveredItem); this.tool.setPrevHoveredItem(this.props.hoveredItem);
this.tool.activate(); this.tool.activate();
paper.settings.handleSize = 8;
} }
deactivateTool () { deactivateTool () {
paper.settings.handleSize = 0; this.tool.deactivateTool();
this.props.clearHoveredItem();
this.tool.remove(); this.tool.remove();
this.tool = null; this.tool = null;
this.hitResult = null; this.hitResult = null;
@ -64,10 +60,10 @@ class ReshapeMode extends React.Component {
ReshapeMode.propTypes = { ReshapeMode.propTypes = {
clearHoveredItem: PropTypes.func.isRequired, clearHoveredItem: PropTypes.func.isRequired,
handleMouseDown: PropTypes.func.isRequired, handleMouseDown: PropTypes.func.isRequired,
hoveredItem: PropTypes.instanceOf(paper.Item), // eslint-disable-line react/no-unused-prop-types hoveredItem: PropTypes.instanceOf(paper.Item),
isReshapeModeActive: PropTypes.bool.isRequired, isReshapeModeActive: PropTypes.bool.isRequired,
onUpdateSvg: PropTypes.func.isRequired, // eslint-disable-line react/no-unused-prop-types onUpdateSvg: PropTypes.func.isRequired,
setHoveredItem: PropTypes.func.isRequired // eslint-disable-line react/no-unused-prop-types setHoveredItem: PropTypes.func.isRequired
}; };
const mapStateToProps = state => ({ const mapStateToProps = state => ({

View file

@ -7,36 +7,17 @@ import Modes from '../modes/modes';
import {changeMode} from '../reducers/modes'; import {changeMode} from '../reducers/modes';
import {setHoveredItem, clearHoveredItem} from '../reducers/hover'; import {setHoveredItem, clearHoveredItem} from '../reducers/hover';
import {getHoveredItem} from '../helper/hover'; import SelectTool from '../helper/selection-tools/select-tool';
import {rectSelect} from '../helper/guides';
import {selectRootItem, processRectangularSelection} from '../helper/selection';
import SelectModeComponent from '../components/select-mode.jsx'; import SelectModeComponent from '../components/select-mode.jsx';
import BoundingBoxTool from '../helper/selection-tools/bounding-box-tool';
import SelectionBoxTool from '../helper/selection-tools/selection-box-tool';
import paper from 'paper'; import paper from 'paper';
class SelectMode extends React.Component { class SelectMode extends React.Component {
static get TOLERANCE () {
return 6;
}
constructor (props) { constructor (props) {
super(props); super(props);
bindAll(this, [ bindAll(this, [
'activateTool', 'activateTool',
'deactivateTool', 'deactivateTool'
'getHitOptions'
]); ]);
this._hitOptions = {
segments: true,
stroke: true,
curves: true,
fill: true,
guide: false
};
this.boundingBoxTool = new BoundingBoxTool();
this.selectionBoxTool = new SelectionBoxTool();
this.selectionBoxMode = false;
} }
componentDidMount () { componentDidMount () {
if (this.props.isSelectModeActive) { if (this.props.isSelectModeActive) {
@ -44,6 +25,10 @@ class SelectMode extends React.Component {
} }
} }
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
if (this.tool && nextProps.hoveredItem !== this.props.hoveredItem) {
this.tool.setPrevHoveredItem(nextProps.hoveredItem);
}
if (nextProps.isSelectModeActive && !this.props.isSelectModeActive) { if (nextProps.isSelectModeActive && !this.props.isSelectModeActive) {
this.activateTool(); this.activateTool();
} else if (!nextProps.isSelectModeActive && this.props.isSelectModeActive) { } else if (!nextProps.isSelectModeActive && this.props.isSelectModeActive) {
@ -53,87 +38,14 @@ class SelectMode extends React.Component {
shouldComponentUpdate () { shouldComponentUpdate () {
return false; // Static component, for now return false; // Static component, for now
} }
getHitOptions (preselectedOnly) {
this._hitOptions.tolerance = SelectMode.TOLERANCE / paper.view.zoom;
if (preselectedOnly) {
this._hitOptions.selected = true;
} else {
delete this._hitOptions.selected;
}
return this._hitOptions;
}
activateTool () { activateTool () {
debugger; this.tool = new SelectTool(this.props.setHoveredItem, this.props.clearHoveredItem, this.props.onUpdateSvg);
selectRootItem();
this.boundingBoxTool.setSelectionBounds();
this.tool = new paper.Tool();
// Define these to sate linter
const selectMode = this;
this.tool.onMouseDown = event => {
if (event.event.button > 0) return; // only first mouse button
this.props.clearHoveredItem();
if (!this.boundingBoxTool
.onMouseDown(
event,
event.modifiers.alt,
event.modifiers.shift,
this.getHitOptions(false /* preseelectedOnly */))) {
this.selectionBoxMode = true;
this.selectionBoxTool.onMouseDown(event.modifiers.shift);
}
};
this.tool.onMouseMove = function (event) {
const hoveredItem = getHoveredItem(event, selectMode.getHitOptions());
const oldHoveredItem = selectMode.props.hoveredItem;
if ((!hoveredItem && oldHoveredItem) || // There is no longer a hovered item
(hoveredItem && !oldHoveredItem) || // There is now a hovered item
(hoveredItem && oldHoveredItem && hoveredItem.id !== oldHoveredItem.id)) { // hovered item changed
selectMode.props.setHoveredItem(hoveredItem);
}
};
this.tool.onMouseDrag = function (event) {
if (event.event.button > 0) return; // only first mouse button
if (selectMode.selectionBoxMode) {
selectMode.selectionRect = rectSelect(event);
// Remove this rect on the next drag and up event
selectMode.selectionRect.removeOnDrag();
} else {
selectMode.boundingBoxTool.onMouseDrag(event);
}
};
this.tool.onMouseUp = function (event) {
if (event.event.button > 0) return; // only first mouse button
if (selectMode.selectionBoxMode) {
if (selectMode.selectionRect) {
processRectangularSelection(event, selectMode.selectionRect, Modes.SELECT);
selectMode.selectionRect.remove();
}
selectMode.boundingBoxTool.setSelectionBounds();
} else {
selectMode.boundingBoxTool.onMouseUp(event);
selectMode.props.onUpdateSvg();
}
selectMode.selectionBoxMode = false;
selectMode.selectionRect = null;
};
this.tool.activate(); this.tool.activate();
} }
deactivateTool () { deactivateTool () {
debugger; this.tool.deactivateTool();
this.props.clearHoveredItem();
this.boundingBoxTool.removeBoundsPath();
this.tool.remove(); this.tool.remove();
this.tool = null; this.tool = null;
this.hitResult = null;
} }
render () { render () {
return ( return (
@ -145,10 +57,10 @@ class SelectMode extends React.Component {
SelectMode.propTypes = { SelectMode.propTypes = {
clearHoveredItem: PropTypes.func.isRequired, clearHoveredItem: PropTypes.func.isRequired,
handleMouseDown: PropTypes.func.isRequired, handleMouseDown: PropTypes.func.isRequired,
hoveredItem: PropTypes.instanceOf(paper.Item), // eslint-disable-line react/no-unused-prop-types hoveredItem: PropTypes.instanceOf(paper.Item),
isSelectModeActive: PropTypes.bool.isRequired, isSelectModeActive: PropTypes.bool.isRequired,
onUpdateSvg: PropTypes.func.isRequired, // eslint-disable-line react/no-unused-prop-types onUpdateSvg: PropTypes.func.isRequired,
setHoveredItem: PropTypes.func.isRequired // eslint-disable-line react/no-unused-prop-types setHoveredItem: PropTypes.func.isRequired
}; };
const mapStateToProps = state => ({ const mapStateToProps = state => ({

View file

@ -28,17 +28,19 @@ const Modes = keyMirror({
* On mouse down, the type of function (move, scale, rotate) is determined based on what is clicked * On mouse down, the type of function (move, scale, rotate) is determined based on what is clicked
* (scale handle, rotate handle, the object itself). This determines the mode of the tool, which then * (scale handle, rotate handle, the object itself). This determines the mode of the tool, which then
* delegates actions to the MoveTool, RotateTool or ScaleTool accordingly. * delegates actions to the MoveTool, RotateTool or ScaleTool accordingly.
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
*/ */
class BoundingBoxTool { class BoundingBoxTool {
constructor () { constructor (onUpdateSvg) {
this.onUpdateSvg = onUpdateSvg;
this.mode = null; this.mode = null;
this.boundsPath = null; this.boundsPath = null;
this.boundsScaleHandles = []; this.boundsScaleHandles = [];
this.boundsRotHandles = []; this.boundsRotHandles = [];
this._modeMap = {}; this._modeMap = {};
this._modeMap[Modes.SCALE] = new ScaleTool(); this._modeMap[Modes.SCALE] = new ScaleTool(onUpdateSvg);
this._modeMap[Modes.ROTATE] = new RotateTool(); this._modeMap[Modes.ROTATE] = new RotateTool(onUpdateSvg);
this._modeMap[Modes.MOVE] = new MoveTool(); this._modeMap[Modes.MOVE] = new MoveTool(onUpdateSvg);
} }
/** /**
@ -75,8 +77,13 @@ class BoundingBoxTool {
this.mode = Modes.MOVE; this.mode = Modes.MOVE;
} }
const hitProperties = {
hitResult: hitResult,
clone: event.modifiers.alt,
multiselect: event.modifiers.shift
};
if (this.mode === Modes.MOVE) { if (this.mode === Modes.MOVE) {
this._modeMap[this.mode].onMouseDown(hitResult, clone, multiselect); this._modeMap[this.mode].onMouseDown(hitProperties);
} else if (this.mode === Modes.SCALE) { } else if (this.mode === Modes.SCALE) {
this._modeMap[this.mode].onMouseDown( this._modeMap[this.mode].onMouseDown(
hitResult, this.boundsPath, this.boundsScaleHandles, this.boundsRotHandles, getSelectedItems()); hitResult, this.boundsPath, this.boundsScaleHandles, this.boundsRotHandles, getSelectedItems());
@ -100,10 +107,9 @@ class BoundingBoxTool {
this.setSelectionBounds(); this.setSelectionBounds();
} }
setSelectionBounds () { setSelectionBounds () {
debugger;
this.removeBoundsPath(); this.removeBoundsPath();
const items = getSelectedItems(); const items = getSelectedItems(true /* recursive */);
if (items.length <= 0) return; if (items.length <= 0) return;
let rect = null; let rect = null;
@ -181,7 +187,6 @@ class BoundingBoxTool {
} }
} }
removeBoundsPath () { removeBoundsPath () {
debugger;
removeHelperItems(); removeHelperItems();
this.boundsPath = null; this.boundsPath = null;
this.boundsScaleHandles.length = 0; this.boundsScaleHandles.length = 0;

View file

@ -1,8 +1,12 @@
import {clearSelection, getSelectedItems} from '../selection'; import {clearSelection, getSelectedItems} from '../selection';
class HandleTool { class HandleTool {
constructor () { /**
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
*/
constructor (onUpdateSvg) {
this.hitType = null; this.hitType = null;
this.onUpdateSvg = onUpdateSvg;
} }
/** /**
* @param {!object} hitProperties Describes the mouse event * @param {!object} hitProperties Describes the mouse event
@ -58,6 +62,7 @@ class HandleTool {
} }
onMouseUp () { onMouseUp () {
// @todo add back undo // @todo add back undo
this.onUpdateSvg();
} }
} }

View file

@ -4,8 +4,12 @@ import {snapDeltaToAngle} from '../math';
import {clearSelection, cloneSelection, getSelectedItems, setItemSelection} from '../selection'; import {clearSelection, cloneSelection, getSelectedItems, setItemSelection} from '../selection';
class MoveTool { class MoveTool {
constructor () { /**
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
*/
constructor (onUpdateSvg) {
this.selectedItems = null; this.selectedItems = null;
this.onUpdateSvg = onUpdateSvg;
} }
/** /**
@ -41,7 +45,7 @@ class MoveTool {
this._select(item, true, hitProperties.subselect); this._select(item, true, hitProperties.subselect);
} }
if (hitProperties.clone) cloneSelection(hitProperties.subselect); if (hitProperties.clone) cloneSelection(hitProperties.subselect);
this.selectedItems = getSelectedItems(hitProperties.subselect); this.selectedItems = getSelectedItems(true /* subselect */);
} }
/** /**
* Sets the selection state of an item. * Sets the selection state of an item.
@ -90,6 +94,7 @@ class MoveTool {
// @todo add back undo // @todo add back undo
// pg.undo.snapshot('moveSelection'); // pg.undo.snapshot('moveSelection');
this.onUpdateSvg();
} }
} }

View file

@ -4,7 +4,10 @@ import {clearSelection, getSelectedItems} from '../selection';
/** Subtool of ReshapeTool for moving control points. */ /** Subtool of ReshapeTool for moving control points. */
class PointTool { class PointTool {
constructor () { /**
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
*/
constructor (onUpdateSvg) {
/** /**
* Deselection often does not happen until mouse up. If the mouse is dragged before * Deselection often does not happen until mouse up. If the mouse is dragged before
* mouse up, deselection is cancelled. This variable keeps track of which paper.Item to deselect. * mouse up, deselection is cancelled. This variable keeps track of which paper.Item to deselect.
@ -21,6 +24,7 @@ class PointTool {
*/ */
this.invertDeselect = false; this.invertDeselect = false;
this.selectedItems = null; this.selectedItems = null;
this.onUpdateSvg = onUpdateSvg;
} }
/** /**
@ -185,9 +189,8 @@ class PointTool {
} }
this.selectedItems = null; this.selectedItems = null;
// @todo add back undo // @todo add back undo
this.onUpdateSvg();
} }
} }
export default PointTool; export default PointTool;
// - bounding box when switching between select and reshape

View file

@ -26,10 +26,11 @@ class ReshapeTool extends paper.Tool {
static get DOUBLE_CLICK_MILLIS () { static get DOUBLE_CLICK_MILLIS () {
return 250; return 250;
} }
constructor (setHoveredItem, clearHoveredItem) { constructor (setHoveredItem, clearHoveredItem, onUpdateSvg) {
super(); super();
this.setHoveredItem = setHoveredItem; this.setHoveredItem = setHoveredItem;
this.clearHoveredItem = clearHoveredItem; this.clearHoveredItem = clearHoveredItem;
this.onUpdateSvg = onUpdateSvg;
this.prevHoveredItem = null; this.prevHoveredItem = null;
this._hitOptionsSelected = { this._hitOptionsSelected = {
match: function (item) { match: function (item) {
@ -72,10 +73,10 @@ class ReshapeTool extends paper.Tool {
this.mode = ReshapeModes.SELECTION_BOX; this.mode = ReshapeModes.SELECTION_BOX;
this.selectionRect = null; this.selectionRect = null;
this._modeMap = {}; this._modeMap = {};
this._modeMap[ReshapeModes.FILL] = new MoveTool(); this._modeMap[ReshapeModes.FILL] = new MoveTool(onUpdateSvg);
this._modeMap[ReshapeModes.POINT] = new PointTool(); this._modeMap[ReshapeModes.POINT] = new PointTool(onUpdateSvg);
this._modeMap[ReshapeModes.HANDLE] = new HandleTool(); this._modeMap[ReshapeModes.HANDLE] = new HandleTool(onUpdateSvg);
this._modeMap[ReshapeModes.SELECTION_BOX] = new SelectionBoxTool(); this._modeMap[ReshapeModes.SELECTION_BOX] = new SelectionBoxTool(Modes.RESHAPE);
// We have to set these functions instead of just declaring them because // We have to set these functions instead of just declaring them because
// paper.js tools hook up the listeners in the setter functions. // paper.js tools hook up the listeners in the setter functions.
@ -84,6 +85,8 @@ class ReshapeTool extends paper.Tool {
this.onMouseDrag = this.handleMouseDrag; this.onMouseDrag = this.handleMouseDrag;
this.onMouseUp = this.handleMouseUp; this.onMouseUp = this.handleMouseUp;
this.onKeyUp = this.handleKeyUp; this.onKeyUp = this.handleKeyUp;
paper.settings.handleSize = 8;
} }
getHitOptions (preselectedOnly) { getHitOptions (preselectedOnly) {
this._hitOptions.tolerance = ReshapeTool.TOLERANCE / paper.view.zoom; this._hitOptions.tolerance = ReshapeTool.TOLERANCE / paper.view.zoom;
@ -193,8 +196,13 @@ class ReshapeTool extends paper.Tool {
// Backspace, delete // Backspace, delete
if (event.key === 'delete' || event.key === 'backspace') { if (event.key === 'delete' || event.key === 'backspace') {
deleteSelection(Modes.RESHAPE); deleteSelection(Modes.RESHAPE);
this.onUpdateSvg();
} }
} }
deactivateTool() {
paper.settings.handleSize = 0;
this.clearHoveredItem();
}
} }
export default ReshapeTool; export default ReshapeTool;

View file

@ -1,10 +1,14 @@
import paper from 'paper'; import paper from 'paper';
class RotateTool { class RotateTool {
constructor () { /**
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
*/
constructor (onUpdateSvg) {
this.rotItems = []; this.rotItems = [];
this.rotGroupPivot = null; this.rotGroupPivot = null;
this.prevRot = []; this.prevRot = [];
this.onUpdateSvg = onUpdateSvg;
} }
/** /**
@ -57,7 +61,7 @@ class RotateTool {
this.prevRot = []; this.prevRot = [];
// @todo add back undo // @todo add back undo
// pg.undo.snapshot('rotateSelection'); this.onUpdateSvg();
} }
} }

View file

@ -1,7 +1,10 @@
import paper from 'paper'; import paper from 'paper';
class ScaleTool { class ScaleTool {
constructor () { /**
* @param {!function} onUpdateSvg A callback to call when the image visibly changes
*/
constructor (onUpdateSvg) {
this.pivot = null; this.pivot = null;
this.origPivot = null; this.origPivot = null;
this.corner = null; this.corner = null;
@ -14,6 +17,7 @@ class ScaleTool {
this.scaleItems = []; this.scaleItems = [];
this.boundsScaleHandles = []; this.boundsScaleHandles = [];
this.boundsRotHandles = []; this.boundsRotHandles = [];
this.onUpdateSvg = onUpdateSvg;
} }
/** /**
@ -113,7 +117,7 @@ class ScaleTool {
} }
} }
} }
onMouseUp (event) { onMouseUp () {
this.pivot = null; this.pivot = null;
this.origPivot = null; this.origPivot = null;
this.corner = null; this.corner = null;
@ -150,7 +154,7 @@ class ScaleTool {
this.itemGroup.remove(); this.itemGroup.remove();
// @todo add back undo // @todo add back undo
// pg.undo.snapshot('scaleSelection'); this.onUpdateSvg();
} }
getRectCornerNameByIndex (index) { getRectCornerNameByIndex (index) {
switch (index) { switch (index) {

View file

@ -1,11 +1,11 @@
import Modes from '../../modes/modes'; import Modes from '../../modes/modes';
import {rectSelect} from '../guides'; import {rectSelect} from '../guides';
import {clearSelection, processRectangularSelection} from '../selection'; import {clearSelection, processRectangularSelection} from '../selection';
import {getHoveredItem} from '../hover';
class SelectionBoxTool { class SelectionBoxTool {
constructor () { constructor (mode) {
this.selectionRect = null; this.selectionRect = null;
this.mode = mode;
} }
/** /**
* @param {boolean} multiselect Whether to multiselect on mouse down (e.g. shift key held) * @param {boolean} multiselect Whether to multiselect on mouse down (e.g. shift key held)

View file

@ -3,7 +3,7 @@ import Modes from '../modes/modes';
import {getAllPaperItems} from './helper'; import {getAllPaperItems} from './helper';
import {getItemsGroup, isGroup} from './group'; import {getItemsGroup, isGroup} from './group';
import {getRootItem, isGroupItem, isCompoundPathItem, isPathItem, isPGTextItem} from './item'; import {getRootItem, isCompoundPathItem, isBoundsItem, isPathItem, isPGTextItem} from './item';
import {getItemsCompoundPath, isCompoundPath, isCompoundPathChild} from './compound-path'; import {getItemsCompoundPath, isCompoundPath, isCompoundPathChild} from './compound-path';
const getAllSelectableItems = function () { const getAllSelectableItems = function () {
@ -34,37 +34,40 @@ const selectItemSegments = function (item, state) {
} }
}; };
const setGroupSelection = function (root, selected) { const setGroupSelection = function (root, selected, fullySelected) {
// fully selected segments need to be unselected first root.fullySelected = fullySelected;
root.fullySelected = false;
// then the item can be normally selected
root.selected = selected; root.selected = selected;
// select children of compound-path or group // select children of compound-path or group
if (isCompoundPath(root) || isGroup(root)) { if (isCompoundPath(root) || isGroup(root)) {
const children = root.children; const children = root.children;
if (children) { if (children) {
for (let i = 0; i < children.length; i++) { for (const child of children) {
children[i].selected = selected; if (isGroup(child)) {
setGroupSelection(child, selected, fullySelected);
} else {
child.fullySelected = fullySelected;
child.selected = selected;
}
} }
} }
} }
}; };
const setItemSelection = function (item, state) { const setItemSelection = function (item, state, fullySelected) {
const parentGroup = getItemsGroup(item); const parentGroup = getItemsGroup(item);
const itemsCompoundPath = getItemsCompoundPath(item); const itemsCompoundPath = getItemsCompoundPath(item);
// if selection is in a group, select group // if selection is in a group, select group
if (parentGroup) { if (parentGroup) {
// do it recursive // do it recursive
setItemSelection(parentGroup, state); setItemSelection(parentGroup, state, fullySelected);
} else if (itemsCompoundPath) { } else if (itemsCompoundPath) {
setGroupSelection(itemsCompoundPath, state); setGroupSelection(itemsCompoundPath, state, fullySelected);
} else { } else {
if (item.data && item.data.noSelect) { if (item.data && item.data.noSelect) {
return; return;
} }
setGroupSelection(item, state); setGroupSelection(item, state, fullySelected);
} }
// @todo: Update toolbar state on change // @todo: Update toolbar state on change
@ -311,34 +314,34 @@ const getSelectedPaths = function () {
return paths; return paths;
}; };
// const checkBoundsItem = function (selectionRect, item, event) { const checkBoundsItem = function (selectionRect, item, event) {
// const itemBounds = new paper.Path([ const itemBounds = new paper.Path([
// item.localToGlobal(item.internalBounds.topLeft), item.localToGlobal(item.internalBounds.topLeft),
// item.localToGlobal(item.internalBounds.topRight), item.localToGlobal(item.internalBounds.topRight),
// item.localToGlobal(item.internalBounds.bottomRight), item.localToGlobal(item.internalBounds.bottomRight),
// item.localToGlobal(item.internalBounds.bottomLeft) item.localToGlobal(item.internalBounds.bottomLeft)
// ]); ]);
// itemBounds.closed = true; itemBounds.closed = true;
// itemBounds.guide = true; itemBounds.guide = true;
// for (let i = 0; i < itemBounds.segments.length; i++) { for (let i = 0; i < itemBounds.segments.length; i++) {
// const seg = itemBounds.segments[i]; const seg = itemBounds.segments[i];
// if (selectionRect.contains(seg.point) || if (selectionRect.contains(seg.point) ||
// (i === 0 && selectionRect.getIntersections(itemBounds).length > 0)) { (i === 0 && selectionRect.getIntersections(itemBounds).length > 0)) {
// if (event.modifiers.shift && item.selected) { if (event.modifiers.shift && item.selected) {
// setItemSelection(item, false); setItemSelection(item, false);
// } else { } else {
// setItemSelection(item, true); setItemSelection(item, true);
// } }
// itemBounds.remove(); itemBounds.remove();
// return true; return true;
// } }
// } }
// itemBounds.remove(); itemBounds.remove();
// }; };
const handleRectangularSelectionItems = function (item, event, rect, mode) { const handleRectangularSelectionItems = function (item, event, rect, mode) {
if (isPathItem(item)) { if (isPathItem(item)) {
@ -355,11 +358,9 @@ const handleRectangularSelectionItems = function (item, event, rect, mode) {
seg.selected = true; seg.selected = true;
} }
segmentMode = true; segmentMode = true;
} else { } else {
if (event.modifiers.shift && item.selected) { if (event.modifiers.shift && item.selected) {
setItemSelection(item, false); setItemSelection(item, false);
} else { } else {
setItemSelection(item, true); setItemSelection(item, true);
} }
@ -371,7 +372,7 @@ const handleRectangularSelectionItems = function (item, event, rect, mode) {
// second round checks for path intersections // second round checks for path intersections
const intersections = item.getIntersections(rect); const intersections = item.getIntersections(rect);
if (intersections.length > 0 && !segmentMode) { if (intersections.length > 0 && !segmentMode) {
// if in detail select mode, select the curves that intersect // if in reshape mode, select the curves that intersect
// with the selectionRect // with the selectionRect
if (mode === Modes.RESHAPE) { if (mode === Modes.RESHAPE) {
for (let k = 0; k < intersections.length; k++) { for (let k = 0; k < intersections.length; k++) {
@ -389,7 +390,6 @@ const handleRectangularSelectionItems = function (item, event, rect, mode) {
curve.selected = true; curve.selected = true;
} }
} }
} else { } else {
if (event.modifiers.shift && item.selected) { if (event.modifiers.shift && item.selected) {
setItemSelection(item, false); setItemSelection(item, false);
@ -402,10 +402,10 @@ const handleRectangularSelectionItems = function (item, event, rect, mode) {
} }
// @todo: Update toolbar state on change // @todo: Update toolbar state on change
// } else if (isBoundsItem(item)) { } else if (isBoundsItem(item)) {
// if (checkBoundsItem(rect, item, event)) { if (checkBoundsItem(rect, item, event)) {
// return false; return false;
// } }
} }
return true; return true;
}; };
@ -417,9 +417,8 @@ const rectangularSelectionGroupLoop = function (group, rect, root, event, mode)
if (isGroup(child) || isCompoundPathItem(child)) { if (isGroup(child) || isCompoundPathItem(child)) {
rectangularSelectionGroupLoop(child, rect, root, event, mode); rectangularSelectionGroupLoop(child, rect, root, event, mode);
} else {
} else if (!handleRectangularSelectionItems(child, event, rect, mode)) { handleRectangularSelectionItems(child, event, rect, mode);
return false;
} }
} }
return true; return true;
@ -428,20 +427,16 @@ const rectangularSelectionGroupLoop = function (group, rect, root, event, mode)
const processRectangularSelection = function (event, rect, mode) { const processRectangularSelection = function (event, rect, mode) {
const allItems = getAllSelectableItems(); const allItems = getAllSelectableItems();
itemLoop:
for (let i = 0; i < allItems.length; i++) { for (let i = 0; i < allItems.length; i++) {
const item = allItems[i]; const item = allItems[i];
if (mode === Modes.RESHAPE && isPGTextItem(getRootItem(item))) { if (mode === Modes.RESHAPE && isPGTextItem(getRootItem(item))) {
continue itemLoop; continue;
} }
// check for item segment points inside selectionRect // check for item segment points inside selectionRect
if (isGroup(item) || isCompoundPathItem(item)) { if (isGroup(item) || isCompoundPathItem(item)) {
if (!rectangularSelectionGroupLoop(item, rect, item, event, mode)) { rectangularSelectionGroupLoop(item, rect, item, event, mode);
continue itemLoop; } else {
} handleRectangularSelectionItems(item, event, rect, mode);
} else if (!handleRectangularSelectionItems(item, event, rect, mode)) {
continue itemLoop;
} }
} }
}; };
@ -455,23 +450,15 @@ const selectRootItem = function () {
for (const item of items) { for (const item of items) {
if (isCompoundPathChild(item)) { if (isCompoundPathChild(item)) {
const cp = getItemsCompoundPath(item); const cp = getItemsCompoundPath(item);
setItemSelection(cp, true); setItemSelection(cp, true, true /* fullySelected */);
} }
const rootItem = getRootItem(item); const rootItem = getRootItem(item);
if (item !== rootItem) { if (item !== rootItem) {
setItemSelection(item, false); setItemSelection(rootItem, true, true /* fullySelected */);
setItemSelection(rootItem, true);
} }
} }
}; };
const selectSubItems = function () {
// when switching to the reshape tool while having a compound path or group
// selected, deselect the group and select the children instead.
// TODO
};
const shouldShowIfSelection = function () { const shouldShowIfSelection = function () {
return getSelectedItems().length > 0; return getSelectedItems().length > 0;
}; };
@ -500,7 +487,6 @@ export {
removeSelectedSegments, removeSelectedSegments,
processRectangularSelection, processRectangularSelection,
selectRootItem, selectRootItem,
selectSubItems,
shouldShowIfSelection, shouldShowIfSelection,
shouldShowIfSelectionRecursive, shouldShowIfSelectionRecursive,
shouldShowSelectAll shouldShowSelectAll