2017-10-12 18:35:30 -04:00
|
|
|
import paper from '@scratch/paper';
|
2017-09-11 14:23:30 -04:00
|
|
|
import {getRootItem, isGroupItem} from './item';
|
2017-10-11 11:32:51 -04:00
|
|
|
import {clearSelection, getSelectedRootItems, setItemSelection} from './selection';
|
2017-09-11 14:23:30 -04:00
|
|
|
|
|
|
|
const isGroup = function (item) {
|
|
|
|
return isGroupItem(item);
|
|
|
|
};
|
|
|
|
|
2017-10-23 15:38:52 -04:00
|
|
|
const groupItems = function (items, clearSelectedItems, setSelectedItems, onUpdateSvg) {
|
2017-09-11 14:23:30 -04:00
|
|
|
if (items.length > 0) {
|
|
|
|
const group = new paper.Group(items);
|
2017-10-02 15:25:04 -04:00
|
|
|
clearSelection(clearSelectedItems);
|
2017-09-11 14:23:30 -04:00
|
|
|
setItemSelection(group, true);
|
|
|
|
for (let i = 0; i < group.children.length; i++) {
|
|
|
|
group.children[i].selected = true;
|
|
|
|
}
|
2017-10-23 15:38:52 -04:00
|
|
|
setSelectedItems();
|
2017-09-14 14:34:45 -04:00
|
|
|
// @todo: Set selection bounds; enable/disable grouping icons
|
2017-10-23 15:38:52 -04:00
|
|
|
onUpdateSvg();
|
2017-09-11 14:23:30 -04:00
|
|
|
return group;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2017-10-23 15:38:52 -04:00
|
|
|
const groupSelection = function (clearSelectedItems, setSelectedItems, onUpdateSvg) {
|
|
|
|
const items = getSelectedRootItems();
|
|
|
|
return groupItems(items, clearSelectedItems, setSelectedItems, onUpdateSvg);
|
|
|
|
};
|
|
|
|
|
|
|
|
const ungroupLoop = function (group, recursive, setSelectedItems) {
|
2017-10-16 19:31:30 -04:00
|
|
|
// Can't ungroup items that are not groups
|
2017-09-11 14:23:30 -04:00
|
|
|
if (!group || !group.children || !isGroup(group)) return;
|
|
|
|
|
|
|
|
group.applyMatrix = true;
|
|
|
|
// iterate over group children recursively
|
|
|
|
for (let i = 0; i < group.children.length; i++) {
|
2017-10-16 19:31:30 -04:00
|
|
|
let groupChild = group.children[i];
|
2017-09-11 14:23:30 -04:00
|
|
|
if (groupChild.hasChildren()) {
|
|
|
|
// recursion (groups can contain groups, ie. from SVG import)
|
|
|
|
if (recursive) {
|
2017-10-23 15:38:52 -04:00
|
|
|
ungroupLoop(groupChild, recursive, setSelectedItems);
|
2017-09-11 14:23:30 -04:00
|
|
|
continue;
|
|
|
|
}
|
2017-10-16 19:31:30 -04:00
|
|
|
if (groupChild.children.length === 1) {
|
|
|
|
groupChild = groupChild.reduce();
|
|
|
|
}
|
2017-09-11 14:23:30 -04:00
|
|
|
}
|
|
|
|
groupChild.applyMatrix = true;
|
|
|
|
// move items from the group to the activeLayer (ungrouping)
|
|
|
|
groupChild.insertBelow(group);
|
2017-10-23 15:38:52 -04:00
|
|
|
if (setSelectedItems) {
|
2017-10-16 19:31:30 -04:00
|
|
|
groupChild.selected = true;
|
|
|
|
}
|
2017-09-11 14:23:30 -04:00
|
|
|
i--;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// ungroup items (only top hierarchy)
|
2017-10-23 15:38:52 -04:00
|
|
|
const ungroupItems = function (items, setSelectedItems, onUpdateSvg) {
|
|
|
|
if (items.length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
2017-09-11 14:23:30 -04:00
|
|
|
const emptyGroups = [];
|
|
|
|
for (let i = 0; i < items.length; i++) {
|
|
|
|
const item = items[i];
|
|
|
|
if (isGroup(item) && !item.data.isPGTextItem) {
|
2017-10-23 15:38:52 -04:00
|
|
|
ungroupLoop(item, false /* recursive */, setSelectedItems);
|
2017-09-11 14:23:30 -04:00
|
|
|
|
|
|
|
if (!item.hasChildren()) {
|
|
|
|
emptyGroups.push(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-10-23 15:38:52 -04:00
|
|
|
if (setSelectedItems) {
|
|
|
|
setSelectedItems();
|
|
|
|
}
|
2017-09-11 14:23:30 -04:00
|
|
|
// remove all empty groups after ungrouping
|
|
|
|
for (let j = 0; j < emptyGroups.length; j++) {
|
|
|
|
emptyGroups[j].remove();
|
|
|
|
}
|
2017-09-14 14:34:45 -04:00
|
|
|
// @todo: Set selection bounds; enable/disable grouping icons
|
2017-10-23 15:38:52 -04:00
|
|
|
if (onUpdateSvg) {
|
|
|
|
onUpdateSvg();
|
|
|
|
}
|
2017-09-11 14:23:30 -04:00
|
|
|
};
|
|
|
|
|
2017-10-23 15:38:52 -04:00
|
|
|
const ungroupSelection = function (clearSelectedItems, setSelectedItems, onUpdateSvg) {
|
2017-10-11 11:32:51 -04:00
|
|
|
const items = getSelectedRootItems();
|
2017-10-16 19:31:30 -04:00
|
|
|
clearSelection(clearSelectedItems);
|
2017-10-23 15:38:52 -04:00
|
|
|
ungroupItems(items, setSelectedItems, onUpdateSvg);
|
2017-09-11 14:23:30 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
const getItemsGroup = function (item) {
|
|
|
|
const itemParent = item.parent;
|
|
|
|
|
|
|
|
if (isGroup(itemParent)) {
|
|
|
|
return itemParent;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
const isGroupChild = function (item) {
|
|
|
|
const rootItem = getRootItem(item);
|
|
|
|
return isGroup(rootItem);
|
|
|
|
};
|
|
|
|
|
|
|
|
const shouldShowGroup = function () {
|
2017-10-11 11:32:51 -04:00
|
|
|
const items = getSelectedRootItems();
|
2017-09-11 14:23:30 -04:00
|
|
|
return items.length > 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
const shouldShowUngroup = function () {
|
2017-10-11 11:32:51 -04:00
|
|
|
const items = getSelectedRootItems();
|
2017-09-11 14:23:30 -04:00
|
|
|
for (let i = 0; i < items.length; i++) {
|
|
|
|
const item = items[i];
|
|
|
|
if (isGroup(item) && !item.data.isPGTextItem && item.children && item.children.length > 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
export {
|
|
|
|
groupSelection,
|
|
|
|
ungroupSelection,
|
|
|
|
groupItems,
|
|
|
|
ungroupItems,
|
|
|
|
getItemsGroup,
|
|
|
|
isGroup,
|
|
|
|
isGroupChild,
|
|
|
|
shouldShowGroup,
|
|
|
|
shouldShowUngroup
|
|
|
|
};
|