123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- import inherits from 'inherits';
- import CreateMoveSnapping from 'diagram-js/lib/features/snapping/CreateMoveSnapping';
- import {
- isSnapped,
- setSnapped,
- topLeft,
- bottomRight
- } from 'diagram-js/lib/features/snapping/SnapUtil';
- import { isExpanded } from '../../util/DiUtil';
- import { is } from '../../util/ModelUtil';
- import {
- asTRBL,
- getMid
- } from 'diagram-js/lib/layout/LayoutUtil';
- import { getBoundaryAttachment } from './BpmnSnappingUtil';
- import { forEach } from 'min-dash';
- var HIGH_PRIORITY = 1500;
- /**
- * Snap during create and move.
- *
- * @param {EventBus} eventBus
- * @param {Injector} injector
- */
- export default function BpmnCreateMoveSnapping(eventBus, injector) {
- injector.invoke(CreateMoveSnapping, this);
- // creating first participant
- eventBus.on([ 'create.move', 'create.end' ], HIGH_PRIORITY, setSnappedIfConstrained);
- // snap boundary events
- eventBus.on([
- 'create.move',
- 'create.end',
- 'shape.move.move',
- 'shape.move.end'
- ], HIGH_PRIORITY, function(event) {
- var context = event.context,
- canExecute = context.canExecute,
- target = context.target;
- var canAttach = canExecute && (canExecute === 'attach' || canExecute.attach);
- if (canAttach && !isSnapped(event)) {
- snapBoundaryEvent(event, target);
- }
- });
- }
- inherits(BpmnCreateMoveSnapping, CreateMoveSnapping);
- BpmnCreateMoveSnapping.$inject = [
- 'eventBus',
- 'injector'
- ];
- BpmnCreateMoveSnapping.prototype.initSnap = function(event) {
- var snapContext = CreateMoveSnapping.prototype.initSnap.call(this, event);
- var shape = event.shape;
- var isMove = !!this._elementRegistry.get(shape.id);
- // snap to docking points
- forEach(shape.outgoing, function(connection) {
- var docking = connection.waypoints[0];
- docking = docking.original || docking;
- snapContext.setSnapOrigin(connection.id + '-docking', getDockingSnapOrigin(docking, isMove, event));
- });
- forEach(shape.incoming, function(connection) {
- var docking = connection.waypoints[connection.waypoints.length - 1];
- docking = docking.original || docking;
- snapContext.setSnapOrigin(connection.id + '-docking', getDockingSnapOrigin(docking, isMove, event));
- });
- if (is(shape, 'bpmn:Participant')) {
- // snap to borders with higher priority
- snapContext.setSnapLocations([ 'top-left', 'bottom-right', 'mid' ]);
- }
- return snapContext;
- };
- BpmnCreateMoveSnapping.prototype.addSnapTargetPoints = function(snapPoints, shape, target) {
- CreateMoveSnapping.prototype.addSnapTargetPoints.call(this, snapPoints, shape, target);
- var snapTargets = this.getSnapTargets(shape, target);
- forEach(snapTargets, function(snapTarget) {
- // handle TRBL alignment
- //
- // * with container elements
- // * with text annotations
- if (isContainer(snapTarget) || areAll([ shape, snapTarget ], 'bpmn:TextAnnotation')) {
- snapPoints.add('top-left', topLeft(snapTarget));
- snapPoints.add('bottom-right', bottomRight(snapTarget));
- }
- });
- var elementRegistry = this._elementRegistry;
- // snap to docking points if not create mode
- forEach(shape.incoming, function(connection) {
- if (elementRegistry.get(shape.id)) {
- if (!includes(snapTargets, connection.source)) {
- snapPoints.add('mid', getMid(connection.source));
- }
- var docking = connection.waypoints[0];
- snapPoints.add(connection.id + '-docking', docking.original || docking);
- }
- });
- forEach(shape.outgoing, function(connection) {
- if (elementRegistry.get(shape.id)) {
- if (!includes(snapTargets, connection.target)) {
- snapPoints.add('mid', getMid(connection.target));
- }
- var docking = connection.waypoints[ connection.waypoints.length - 1 ];
- snapPoints.add(connection.id + '-docking', docking.original || docking);
- }
- });
- // add sequence flow parents as snap targets
- if (is(target, 'bpmn:SequenceFlow')) {
- snapPoints = this.addSnapTargetPoints(snapPoints, shape, target.parent);
- }
- return snapPoints;
- };
- BpmnCreateMoveSnapping.prototype.getSnapTargets = function(shape, target) {
- return CreateMoveSnapping.prototype.getSnapTargets.call(this, shape, target)
- .filter(function(snapTarget) {
- // do not snap to lanes
- return !is(snapTarget, 'bpmn:Lane');
- });
- };
- // helpers //////////
- function snapBoundaryEvent(event, target) {
- var targetTRBL = asTRBL(target);
- var direction = getBoundaryAttachment(event, target);
- var context = event.context,
- shape = context.shape;
- var offset;
- if (shape.parent) {
- offset = { x: 0, y: 0 };
- } else {
- offset = getMid(shape);
- }
- if (/top/.test(direction)) {
- setSnapped(event, 'y', targetTRBL.top - offset.y);
- } else if (/bottom/.test(direction)) {
- setSnapped(event, 'y', targetTRBL.bottom - offset.y);
- }
- if (/left/.test(direction)) {
- setSnapped(event, 'x', targetTRBL.left - offset.x);
- } else if (/right/.test(direction)) {
- setSnapped(event, 'x', targetTRBL.right - offset.x);
- }
- }
- function areAll(elements, type) {
- return elements.every(function(el) {
- return is(el, type);
- });
- }
- function isContainer(element) {
- if (is(element, 'bpmn:SubProcess') && isExpanded(element)) {
- return true;
- }
- return is(element, 'bpmn:Participant');
- }
- function setSnappedIfConstrained(event) {
- var context = event.context,
- createConstraints = context.createConstraints;
- if (!createConstraints) {
- return;
- }
- var top = createConstraints.top,
- right = createConstraints.right,
- bottom = createConstraints.bottom,
- left = createConstraints.left;
- if ((left && left >= event.x) || (right && right <= event.x)) {
- setSnapped(event, 'x', event.x);
- }
- if ((top && top >= event.y) || (bottom && bottom <= event.y)) {
- setSnapped(event, 'y', event.y);
- }
- }
- function includes(array, value) {
- return array.indexOf(value) !== -1;
- }
- function getDockingSnapOrigin(docking, isMove, event) {
- return isMove ? (
- {
- x: docking.x - event.x,
- y: docking.y - event.y
- }
- ) : {
- x: docking.x,
- y: docking.y
- };
- }
|