| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- import Command from './command'
- import history from '../history'
- import { Data, GroupShape, Shape, ShapeType } from 'types'
- import {
- getCommonBounds,
- getPage,
- getSelectedShapes,
- getShape,
- } from 'utils/utils'
- import { current } from 'immer'
- import { createShape, getShapeUtils } from 'lib/shape-utils'
- import { PropsOfType } from 'types'
- import { v4 as uuid } from 'uuid'
-
- export default function ungroupCommand(data: Data) {
- const cData = current(data)
- const { currentPageId, selectedIds } = cData
-
- const selectedGroups = getSelectedShapes(cData)
- .filter((shape) => shape.type === ShapeType.Group)
- .sort((a, b) => a.childIndex - b.childIndex)
-
- // Are all of the shapes already in the same group?
- // - ungroup the shapes
- // Otherwise...
- // - remove the shapes from any existing group and add them to a new one
-
- history.execute(
- data,
- new Command({
- name: 'ungroup_shapes',
- category: 'canvas',
- do(data) {
- const { shapes } = getPage(data)
-
- // Remove shapes from old parents
- for (const oldGroupShape of selectedGroups) {
- const siblings = (
- oldGroupShape.parentId === currentPageId
- ? Object.values(shapes).filter(
- (shape) => shape.parentId === currentPageId
- )
- : shapes[oldGroupShape.parentId].children.map((id) => shapes[id])
- ).sort((a, b) => a.childIndex - b.childIndex)
-
- const trueIndex = siblings.findIndex((s) => s.id === oldGroupShape.id)
-
- let step: number
-
- if (trueIndex === siblings.length - 1) {
- step = 1
- } else {
- step =
- (siblings[trueIndex + 1].childIndex - oldGroupShape.childIndex) /
- (oldGroupShape.children.length + 1)
- }
-
- data.selectedIds.clear()
-
- // Move shapes to page
- oldGroupShape.children
- .map((id) => shapes[id])
- .forEach(({ id }, i) => {
- const shape = shapes[id]
- data.selectedIds.add(id)
- getShapeUtils(shape)
- .setProperty(shape, 'parentId', oldGroupShape.parentId)
- .setProperty(
- shape,
- 'childIndex',
- oldGroupShape.childIndex + step * i
- )
- })
-
- delete shapes[oldGroupShape.id]
- }
- },
- undo(data) {
- const { shapes } = getPage(data, currentPageId)
- selectedIds.clear()
- selectedGroups.forEach((group) => {
- selectedIds.add(group.id)
- shapes[group.id] = group
- group.children.forEach((id, i) => {
- const shape = shapes[id]
- getShapeUtils(shape)
- .setProperty(shape, 'parentId', group.id)
- .setProperty(shape, 'childIndex', i)
- })
- })
- },
- })
- )
- }
-
- function getShapeDepth(data: Data, id: string, depth = 0) {
- if (id === data.currentPageId) {
- return depth
- }
-
- return getShapeDepth(data, getShape(data, id).parentId, depth + 1)
- }
|