import { forEach } from 'min-dash'; import { getMovedSourceAnchor, getMovedTargetAnchor } from './AnchorsHelper'; import MoveClosure from './MoveClosure'; /** * A helper that is able to carry out serialized move * operations on multiple elements. * * @param {Modeling} modeling */ export default function MoveHelper(modeling) { this._modeling = modeling; } /** * Move the specified elements and all children by the given delta. * * This moves all enclosed connections, too and layouts all affected * external connections. * * @param {Array} elements * @param {Point} delta * @param {djs.model.Base} newParent applied to the first level of shapes * * @return {Array} list of touched elements */ MoveHelper.prototype.moveRecursive = function(elements, delta, newParent) { if (!elements) { return []; } else { return this.moveClosure(this.getClosure(elements), delta, newParent); } }; /** * Move the given closure of elmements. * * @param {Object} closure * @param {Point} delta * @param {djs.model.Base} [newParent] * @param {djs.model.Base} [newHost] */ MoveHelper.prototype.moveClosure = function(closure, delta, newParent, newHost, primaryShape) { var modeling = this._modeling; var allShapes = closure.allShapes, allConnections = closure.allConnections, enclosedConnections = closure.enclosedConnections, topLevel = closure.topLevel, keepParent = false; if (primaryShape && primaryShape.parent === newParent) { keepParent = true; } // move all shapes forEach(allShapes, function(shape) { // move the element according to the given delta modeling.moveShape(shape, delta, topLevel[shape.id] && !keepParent && newParent, { recurse: false, layout: false }); }); // move all child connections / layout external connections forEach(allConnections, function(c) { var sourceMoved = !!allShapes[c.source.id], targetMoved = !!allShapes[c.target.id]; if (enclosedConnections[c.id] && sourceMoved && targetMoved) { modeling.moveConnection(c, delta, topLevel[c.id] && !keepParent && newParent); } else { modeling.layoutConnection(c, { connectionStart: sourceMoved && getMovedSourceAnchor(c, c.source, delta), connectionEnd: targetMoved && getMovedTargetAnchor(c, c.target, delta) }); } }); }; /** * Returns the closure for the selected elements * * @param {Array} elements * @return {MoveClosure} closure */ MoveHelper.prototype.getClosure = function(elements) { return new MoveClosure().addAll(elements, true); };