convert getSelectedItems(recursive) to 2 functions

This commit is contained in:
DD 2017-10-11 11:32:51 -04:00
parent df8c3f66e3
commit ab244a5e4c
12 changed files with 85 additions and 71 deletions

View file

@ -56,7 +56,7 @@ class Blobbiness {
const oldStrokeColor = this.options ? this.options.strokeColor : null; const oldStrokeColor = this.options ? this.options.strokeColor : null;
const oldStrokeWidth = this.options ? this.options.strokeWidth : null; const oldStrokeWidth = this.options ? this.options.strokeWidth : null;
// If values are mixed, it means the color was set by a selection contained multiple values. // If values are mixed, it means the color was set by a selection contained multiple values.
// In this case keep drawing with the previous values if any. (For stroke width, null indicates) // In this case keep drawing with the previous values if any. (For stroke width, null indicates
// mixed, because stroke width is required to be a number) // mixed, because stroke width is required to be a number)
this.options = { this.options = {
...options, ...options,

View file

@ -4,7 +4,7 @@ import {connect} from 'react-redux';
import bindAll from 'lodash.bindall'; import bindAll from 'lodash.bindall';
import Modes from '../modes/modes'; import Modes from '../modes/modes';
import {changeStrokeWidth} from '../reducers/stroke-width'; import {changeStrokeWidth} from '../reducers/stroke-width';
import {clearSelection, getSelectedItems} from '../helper/selection'; import {clearSelection, getSelectedLeafItems} from '../helper/selection';
import {MIXED} from '../helper/style-path'; import {MIXED} from '../helper/style-path';
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items'; import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
import LineModeComponent from '../components/line-mode.jsx'; import LineModeComponent from '../components/line-mode.jsx';
@ -299,7 +299,7 @@ const mapDispatchToProps = dispatch => ({
dispatch(clearSelectedItems()); dispatch(clearSelectedItems());
}, },
setSelectedItems: () => { setSelectedItems: () => {
dispatch(setSelectedItems(getSelectedItems(true /* recursive */))); dispatch(setSelectedItems(getSelectedLeafItems()));
}, },
handleMouseDown: () => { handleMouseDown: () => {
dispatch(changeMode(Modes.LINE)); dispatch(changeMode(Modes.LINE));

View file

@ -7,7 +7,7 @@ import Modes from '../modes/modes';
import {changeMode} from '../reducers/modes'; import {changeMode} from '../reducers/modes';
import {clearHoveredItem, setHoveredItem} from '../reducers/hover'; import {clearHoveredItem, setHoveredItem} from '../reducers/hover';
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items'; import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
import {getSelectedItems} from '../helper/selection'; import {getSelectedLeafItems} 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';
@ -88,7 +88,7 @@ const mapDispatchToProps = dispatch => ({
dispatch(clearSelectedItems()); dispatch(clearSelectedItems());
}, },
setSelectedItems: () => { setSelectedItems: () => {
dispatch(setSelectedItems(getSelectedItems(true /* recursive */))); dispatch(setSelectedItems(getSelectedLeafItems()));
}, },
handleMouseDown: () => { handleMouseDown: () => {
dispatch(changeMode(Modes.RESHAPE)); dispatch(changeMode(Modes.RESHAPE));

View file

@ -8,7 +8,7 @@ import {changeMode} from '../reducers/modes';
import {clearHoveredItem, setHoveredItem} from '../reducers/hover'; import {clearHoveredItem, setHoveredItem} from '../reducers/hover';
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items'; import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
import {getSelectedItems} from '../helper/selection'; import {getSelectedLeafItems} from '../helper/selection';
import SelectTool from '../helper/selection-tools/select-tool'; import SelectTool from '../helper/selection-tools/select-tool';
import SelectModeComponent from '../components/select-mode.jsx'; import SelectModeComponent from '../components/select-mode.jsx';
@ -86,7 +86,7 @@ const mapDispatchToProps = dispatch => ({
dispatch(clearSelectedItems()); dispatch(clearSelectedItems());
}, },
setSelectedItems: () => { setSelectedItems: () => {
dispatch(setSelectedItems(getSelectedItems(true /* recursive */))); dispatch(setSelectedItems(getSelectedLeafItems()));
}, },
handleMouseDown: () => { handleMouseDown: () => {
dispatch(changeMode(Modes.SELECT)); dispatch(changeMode(Modes.SELECT));

View file

@ -1,13 +1,13 @@
import paper from 'paper'; import paper from 'paper';
import {getRootItem, isGroupItem} from './item'; import {getRootItem, isGroupItem} from './item';
import {clearSelection, getSelectedItems, setItemSelection} from './selection'; import {clearSelection, getSelectedRootItems, setItemSelection} from './selection';
const isGroup = function (item) { const isGroup = function (item) {
return isGroupItem(item); return isGroupItem(item);
}; };
const groupSelection = function (clearSelectedItems) { const groupSelection = function (clearSelectedItems) {
const items = getSelectedItems(); const items = getSelectedRootItems();
if (items.length > 0) { if (items.length > 0) {
const group = new paper.Group(items); const group = new paper.Group(items);
clearSelection(clearSelectedItems); clearSelection(clearSelectedItems);
@ -71,7 +71,7 @@ const ungroupItems = function (items, clearSelectedItems) {
}; };
const ungroupSelection = function () { const ungroupSelection = function () {
const items = getSelectedItems(); const items = getSelectedRootItems();
ungroupItems(items); ungroupItems(items);
}; };
@ -102,12 +102,12 @@ const isGroupChild = function (item) {
}; };
const shouldShowGroup = function () { const shouldShowGroup = function () {
const items = getSelectedItems(); const items = getSelectedRootItems();
return items.length > 1; return items.length > 1;
}; };
const shouldShowUngroup = function () { const shouldShowUngroup = function () {
const items = getSelectedItems(); const items = getSelectedRootItems();
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
const item = items[i]; const item = items[i];
if (isGroup(item) && !item.data.isPGTextItem && item.children && item.children.length > 0) { if (isGroup(item) && !item.data.isPGTextItem && item.children && item.children.length > 0) {

View file

@ -1,6 +1,6 @@
import paper from 'paper'; import paper from 'paper';
import {getGuideLayer} from './layer'; import {getGuideLayer} from './layer';
import {getAllPaperItems} from './selection'; import {getAllRootItems} from './selection';
const GUIDE_BLUE = '#009dec'; const GUIDE_BLUE = '#009dec';
const GUIDE_GREY = '#aaaaaa'; const GUIDE_GREY = '#aaaaaa';
@ -66,7 +66,7 @@ const getGuideColor = function (colorName) {
}; };
const _removePaperItemsByDataTags = function (tags) { const _removePaperItemsByDataTags = function (tags) {
const allItems = getAllPaperItems(true); const allItems = getAllRootItems(true);
for (const item of allItems) { for (const item of allItems) {
for (const tag of tags) { for (const tag of tags) {
if (item.data && item.data[tag]) { if (item.data && item.data[tag]) {
@ -77,7 +77,7 @@ const _removePaperItemsByDataTags = function (tags) {
}; };
const _removePaperItemsByTags = function (tags) { const _removePaperItemsByTags = function (tags) {
const allItems = getAllPaperItems(true); const allItems = getAllRootItems(true);
for (const item of allItems) { for (const item of allItems) {
for (const tag of tags) { for (const tag of tags) {
if (item[tag]) { if (item[tag]) {

View file

@ -1,7 +1,7 @@
import paper from 'paper'; import paper from 'paper';
import keyMirror from 'keymirror'; import keyMirror from 'keymirror';
import {getSelectedItems} from '../selection'; import {getSelectedRootItems} from '../selection';
import {getGuideColor, removeHelperItems} from '../guides'; import {getGuideColor, removeHelperItems} from '../guides';
import {getGuideLayer} from '../layer'; import {getGuideLayer} from '../layer';
@ -90,9 +90,9 @@ class BoundingBoxTool {
this._modeMap[this.mode].onMouseDown(hitProperties); 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, getSelectedRootItems());
} else if (this.mode === Modes.ROTATE) { } else if (this.mode === Modes.ROTATE) {
this._modeMap[this.mode].onMouseDown(hitResult, this.boundsPath, getSelectedItems()); this._modeMap[this.mode].onMouseDown(hitResult, this.boundsPath, getSelectedRootItems());
} }
// while transforming object, never show the bounds stuff // while transforming object, never show the bounds stuff
@ -113,7 +113,7 @@ class BoundingBoxTool {
setSelectionBounds () { setSelectionBounds () {
this.removeBoundsPath(); this.removeBoundsPath();
const items = getSelectedItems(true /* recursive */); const items = getSelectedRootItems();
if (items.length <= 0) return; if (items.length <= 0) return;
let rect = null; let rect = null;

View file

@ -1,4 +1,4 @@
import {clearSelection, getSelectedItems} from '../selection'; import {clearSelection, getSelectedLeafItems} from '../selection';
/** Sub tool of the Reshape tool for moving handles, which adjust bezier curves. */ /** Sub tool of the Reshape tool for moving handles, which adjust bezier curves. */
class HandleTool { class HandleTool {
@ -28,7 +28,7 @@ class HandleTool {
this.hitType = hitProperties.hitResult.type; this.hitType = hitProperties.hitResult.type;
} }
onMouseDrag (event) { onMouseDrag (event) {
const selectedItems = getSelectedItems(true /* recursive */); const selectedItems = getSelectedLeafItems();
for (const item of selectedItems) { for (const item of selectedItems) {
for (const seg of item.segments) { for (const seg of item.segments) {

View file

@ -1,7 +1,7 @@
import {isGroup} from '../group'; import {isGroup} from '../group';
import {isCompoundPathItem, getRootItem} from '../item'; import {isCompoundPathItem, getRootItem} from '../item';
import {snapDeltaToAngle} from '../math'; import {snapDeltaToAngle} from '../math';
import {clearSelection, cloneSelection, getSelectedItems, setItemSelection} from '../selection'; import {clearSelection, cloneSelection, getSelectedLeafItems, setItemSelection} from '../selection';
/** /**
* Tool to handle dragging an item to reposition it in a selection mode. * Tool to handle dragging an item to reposition it in a selection mode.
@ -52,7 +52,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(true /* subselect */); this.selectedItems = getSelectedLeafItems();
} }
/** /**
* Sets the selection state of an item. * Sets the selection state of an item.

View file

@ -1,6 +1,6 @@
import paper from 'paper'; import paper from 'paper';
import {snapDeltaToAngle} from '../math'; import {snapDeltaToAngle} from '../math';
import {clearSelection, getSelectedItems} from '../selection'; import {clearSelection, getSelectedLeafItems} from '../selection';
/** Subtool of ReshapeTool for moving control points. */ /** Subtool of ReshapeTool for moving control points. */
class PointTool { class PointTool {
@ -58,7 +58,7 @@ class PointTool {
hitProperties.hitResult.segment.selected = true; hitProperties.hitResult.segment.selected = true;
} }
this.selectedItems = getSelectedItems(true /* recursive */); this.selectedItems = getSelectedLeafItems();
} }
/** /**
* @param {!object} hitProperties Describes the mouse event * @param {!object} hitProperties Describes the mouse event

View file

@ -10,7 +10,7 @@ import {getItemsCompoundPath, isCompoundPath, isCompoundPathChild} from './compo
* be included in the returned items. * be included in the returned items.
* @return {Array<paper.item>} all top-level (direct descendants of a paper.Layer) items * @return {Array<paper.item>} all top-level (direct descendants of a paper.Layer) items
*/ */
const getAllPaperItems = function (includeGuides) { const getAllRootItems = function (includeGuides) {
includeGuides = includeGuides || false; includeGuides = includeGuides || false;
const allItems = []; const allItems = [];
for (const layer of paper.project.layers) { for (const layer of paper.project.layers) {
@ -29,8 +29,8 @@ const getAllPaperItems = function (includeGuides) {
* @return {Array<paper.item>} all top-level (direct descendants of a paper.Layer) items * @return {Array<paper.item>} all top-level (direct descendants of a paper.Layer) items
* that aren't guide items or helper items. * that aren't guide items or helper items.
*/ */
const getAllSelectableItems = function () { const getAllSelectableRootItems = function () {
const allItems = getAllPaperItems(); const allItems = getAllRootItems();
const selectables = []; const selectables = [];
for (let i = 0; i < allItems.length; i++) { for (let i = 0; i < allItems.length; i++) {
if (allItems[i].data && !allItems[i].data.isHelperItem) { if (allItems[i].data && !allItems[i].data.isHelperItem) {
@ -97,7 +97,7 @@ const setItemSelection = function (item, state, fullySelected) {
}; };
const selectAllItems = function () { const selectAllItems = function () {
const items = getAllSelectableItems(); const items = getAllSelectableRootItems();
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
setItemSelection(items[i], true); setItemSelection(items[i], true);
@ -105,7 +105,7 @@ const selectAllItems = function () {
}; };
const selectAllSegments = function () { const selectAllSegments = function () {
const items = getAllSelectableItems(); const items = getAllSelectableRootItems();
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
selectItemSegments(items[i], true); selectItemSegments(items[i], true);
@ -119,39 +119,53 @@ const clearSelection = function (dispatchClearSelect) {
dispatchClearSelect(); dispatchClearSelect();
}; };
// This gets all selected non-grouped items and groups /**
// (alternative to paper.project.selectedItems, which includes * This gets all selected non-grouped items and groups
// group children in addition to the group) * (alternative to paper.project.selectedItems, which includes
// Returns in increasing Z order * group children in addition to the group)
const getSelectedItems = function (recursive) { * @return {Array<paper.Item>} in increasing Z order.
*/
const getSelectedRootItems = function () {
const allItems = paper.project.selectedItems; const allItems = paper.project.selectedItems;
const itemsAndGroups = []; const itemsAndGroups = [];
if (recursive) { 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 ((isGroup(item) && !isGroup(item.parent)) ||
!isGroup(item.parent)) {
if (item.data && !item.data.isSelectionBound) { if (item.data && !item.data.isSelectionBound) {
itemsAndGroups.push(item); itemsAndGroups.push(item);
} }
} }
} else {
for (let i = 0; i < allItems.length; i++) {
const item = allItems[i];
if ((isGroup(item) && !isGroup(item.parent)) ||
!isGroup(item.parent)) {
if (item.data && !item.data.isSelectionBound) {
itemsAndGroups.push(item);
}
}
}
} }
// sort items by index (0 at bottom) // sort items by index (0 at bottom)
itemsAndGroups.sort((a, b) => parseFloat(a.index) - parseFloat(b.index)); itemsAndGroups.sort((a, b) => parseFloat(a.index) - parseFloat(b.index));
return itemsAndGroups; return itemsAndGroups;
}; };
const deleteItemSelection = function (recursive) { /**
const items = getSelectedItems(recursive); * This gets all selected items that are as deeply nested as possible. Does not
* return the parent groups.
* @return {Array<paper.Item>} in increasing Z order.
*/
const getSelectedLeafItems = function () {
const allItems = paper.project.selectedItems;
const items = [];
for (let i = 0; i < allItems.length; i++) {
const item = allItems[i];
if (!isGroup(item) && item.data && !item.data.isSelectionBound) {
items.push(item);
}
}
// sort items by index (0 at bottom)
items.sort((a, b) => parseFloat(a.index) - parseFloat(b.index));
return items;
};
const deleteItemSelection = function (items) {
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
items[i].remove(); items[i].remove();
} }
@ -162,11 +176,10 @@ const deleteItemSelection = function (recursive) {
// pg.undo.snapshot('deleteItemSelection'); // pg.undo.snapshot('deleteItemSelection');
}; };
const removeSelectedSegments = function (recursive) { const removeSelectedSegments = function (items) {
// @todo add back undo // @todo add back undo
// pg.undo.snapshot('removeSelectedSegments'); // pg.undo.snapshot('removeSelectedSegments');
const items = getSelectedItems(recursive);
const segmentsToRemove = []; const segmentsToRemove = [];
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
@ -190,12 +203,14 @@ const removeSelectedSegments = function (recursive) {
const deleteSelection = function (mode) { const deleteSelection = function (mode) {
if (mode === Modes.RESHAPE) { if (mode === Modes.RESHAPE) {
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(true /* recursive */)) { if (!removeSelectedSegments(selectedItems)) {
deleteItemSelection(true /* recursive */); deleteItemSelection(selectedItems);
} }
} else { } else {
deleteItemSelection(); const selectedItems = getSelectedRootItems();
deleteItemSelection(selectedItems);
} }
}; };
@ -245,7 +260,7 @@ const splitPathRetainSelection = function (path, index, deselectSplitSegments) {
}; };
const splitPathAtSelectedSegments = function () { const splitPathAtSelectedSegments = function () {
const items = getSelectedItems(); const items = getSelectedRootItems();
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
const item = items[i]; const item = items[i];
const segments = item.segments; const segments = item.segments;
@ -301,9 +316,7 @@ const deleteSegments = function (item) {
} }
}; };
const deleteSegmentSelection = function () { const deleteSegmentSelection = function (items) {
const items = getSelectedItems();
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
deleteSegments(items[i]); deleteSegments(items[i]);
} }
@ -315,7 +328,7 @@ const deleteSegmentSelection = function () {
}; };
const cloneSelection = function (recursive) { const cloneSelection = function (recursive) {
const selectedItems = getSelectedItems(recursive); const selectedItems = recursive ? getSelectedLeafItems() : getSelectedRootItems();
for (let i = 0; i < selectedItems.length; i++) { for (let i = 0; i < selectedItems.length; i++) {
const item = selectedItems[i]; const item = selectedItems[i];
item.clone(); item.clone();
@ -327,7 +340,7 @@ const cloneSelection = function (recursive) {
// Only returns paths, no compound paths, groups or any other stuff // Only returns paths, no compound paths, groups or any other stuff
const getSelectedPaths = function () { const getSelectedPaths = function () {
const allPaths = getSelectedItems(); const allPaths = getSelectedRootItems();
const paths = []; const paths = [];
for (let i = 0; i < allPaths.length; i++) { for (let i = 0; i < allPaths.length; i++) {
@ -458,7 +471,7 @@ const _rectangularSelectionGroupLoop = function (group, rect, root, event, mode)
* @param {Modes} mode The mode of the paint editor when drawing the rectangle * @param {Modes} mode The mode of the paint editor when drawing the rectangle
*/ */
const processRectangularSelection = function (event, rect, mode) { const processRectangularSelection = function (event, rect, mode) {
const allItems = getAllSelectableItems(); const allItems = getAllSelectableRootItems();
for (let i = 0; i < allItems.length; i++) { for (let i = 0; i < allItems.length; i++) {
const item = allItems[i]; const item = allItems[i];
@ -480,7 +493,7 @@ const processRectangularSelection = function (event, rect, mode) {
* instead. (otherwise the compound path breaks because of scale-grouping) * instead. (otherwise the compound path breaks because of scale-grouping)
*/ */
const selectRootItem = function () { const selectRootItem = function () {
const items = getSelectedItems(true /* recursive */); const items = getSelectedLeafItems();
for (const item of items) { for (const item of items) {
if (isCompoundPathChild(item)) { if (isCompoundPathChild(item)) {
const cp = getItemsCompoundPath(item); const cp = getItemsCompoundPath(item);
@ -494,11 +507,11 @@ const selectRootItem = function () {
}; };
const shouldShowIfSelection = function () { const shouldShowIfSelection = function () {
return getSelectedItems().length > 0; return getSelectedRootItems().length > 0;
}; };
const shouldShowIfSelectionRecursive = function () { const shouldShowIfSelectionRecursive = function () {
return getSelectedItems(true /* recursive */).length > 0; return getSelectedRootItems().length > 0;
}; };
const shouldShowSelectAll = function () { const shouldShowSelectAll = function () {
@ -506,7 +519,7 @@ const shouldShowSelectAll = function () {
}; };
export { export {
getAllPaperItems, getAllRootItems,
selectAllItems, selectAllItems,
selectAllSegments, selectAllSegments,
clearSelection, clearSelection,
@ -517,8 +530,9 @@ export {
cloneSelection, cloneSelection,
setItemSelection, setItemSelection,
setGroupSelection, setGroupSelection,
getSelectedItems, getSelectedLeafItems,
getSelectedPaths, getSelectedPaths,
getSelectedRootItems,
removeSelectedSegments, removeSelectedSegments,
processRectangularSelection, processRectangularSelection,
selectRootItem, selectRootItem,

View file

@ -1,4 +1,4 @@
import {getSelectedItems} from './selection'; import {getSelectedLeafItems} from './selection';
import {isPGTextItem, isPointTextItem} from './item'; import {isPGTextItem, isPointTextItem} from './item';
import {isGroup} from './group'; import {isGroup} from './group';
@ -9,7 +9,7 @@ const MIXED = 'scratch-paint/style-path/mixed';
* @param {string} colorString New color, css format * @param {string} colorString New color, css format
*/ */
const applyFillColorToSelection = function (colorString) { const applyFillColorToSelection = function (colorString) {
const items = getSelectedItems(true /* recursive */); const items = getSelectedLeafItems;
for (const item of items) { for (const item of items) {
if (isPGTextItem(item)) { if (isPGTextItem(item)) {
for (const child of item.children) { for (const child of item.children) {
@ -38,7 +38,7 @@ const applyFillColorToSelection = function (colorString) {
* @param {string} colorString New color, css format * @param {string} colorString New color, css format
*/ */
const applyStrokeColorToSelection = function (colorString) { const applyStrokeColorToSelection = function (colorString) {
const items = getSelectedItems(true /* recursive */); const items = getSelectedLeafItems();
for (const item of items) { for (const item of items) {
if (isPGTextItem(item)) { if (isPGTextItem(item)) {
@ -69,7 +69,7 @@ const applyStrokeColorToSelection = function (colorString) {
* @param {number} value New stroke width * @param {number} value New stroke width
*/ */
const applyStrokeWidthToSelection = function (value) { const applyStrokeWidthToSelection = function (value) {
const items = getSelectedItems(true /* recursive */); const items = getSelectedLeafItems();
for (const item of items) { for (const item of items) {
if (isGroup(item)) { if (isGroup(item)) {
continue; continue;