feat(bpmn-snapping): snap boundary event loop when close to source
Closes #903
This commit is contained in:
parent
085cedfda1
commit
a09e0a3bed
|
@ -5,16 +5,23 @@ import {
|
|||
|
||||
import { isCmd } from 'diagram-js/lib/features/keyboard/KeyboardUtil';
|
||||
|
||||
import {
|
||||
getOrientation
|
||||
} from 'diagram-js/lib/layout/LayoutUtil';
|
||||
|
||||
import { is } from '../../util/ModelUtil';
|
||||
|
||||
import { some } from 'min-dash';
|
||||
|
||||
var HIGHER_PRIORITY = 1250;
|
||||
|
||||
var BOUNDARY_TO_HOST_THRESHOLD = 40;
|
||||
|
||||
var TARGET_BOUNDS_PADDING = 20;
|
||||
|
||||
var AXES = [ 'x', 'y' ];
|
||||
|
||||
var abs = Math.abs;
|
||||
|
||||
/**
|
||||
* Snap during connect.
|
||||
|
@ -59,6 +66,9 @@ export default function BpmnConnectSnapping(eventBus, rules) {
|
|||
// snap source
|
||||
context.sourcePosition = mid(source);
|
||||
|
||||
if (is(source, 'bpmn:BoundaryEvent') && target === source.host) {
|
||||
snapBoundaryEventLoop(event, source, target);
|
||||
}
|
||||
} else if (isType(connectionAttrs, 'bpmn:MessageFlow')) {
|
||||
|
||||
if (is(source, 'bpmn:Event')) {
|
||||
|
@ -103,6 +113,37 @@ function snapInsideTarget(event, target) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
// snap outside of Boundary Event surroundings
|
||||
function snapBoundaryEventLoop(event, source, target) {
|
||||
var sourceMid = mid(source),
|
||||
orientation = getOrientation(sourceMid, target, -10),
|
||||
snappingAxes = [];
|
||||
|
||||
if (/top|bottom/.test(orientation)) {
|
||||
snappingAxes.push('x');
|
||||
}
|
||||
|
||||
if (/left|right/.test(orientation)) {
|
||||
snappingAxes.push('y');
|
||||
}
|
||||
|
||||
snappingAxes.forEach(function(axis) {
|
||||
var coordinate = event[axis], newCoordinate;
|
||||
|
||||
if (abs(coordinate - sourceMid[axis]) < BOUNDARY_TO_HOST_THRESHOLD) {
|
||||
if (coordinate > sourceMid[axis]) {
|
||||
newCoordinate = sourceMid[axis] + BOUNDARY_TO_HOST_THRESHOLD;
|
||||
}
|
||||
else {
|
||||
newCoordinate = sourceMid[axis] - BOUNDARY_TO_HOST_THRESHOLD;
|
||||
}
|
||||
|
||||
setSnapped(event, axis, newCoordinate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// helpers //////////
|
||||
|
||||
function snapToPosition(event, position) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<bpmn:dataObject id="DataObject_16xfc7e" />
|
||||
<bpmn:subProcess id="SubProcess" />
|
||||
<bpmn:boundaryEvent id="BoundaryEvent" attachedToRef="SubProcess" />
|
||||
<bpmn:boundaryEvent id="BoundaryEventRight" attachedToRef="SubProcess" />
|
||||
</bpmn:process>
|
||||
<bpmn:process id="Process_2" isExecutable="false">
|
||||
<bpmn:task id="Task_2" />
|
||||
|
@ -57,6 +58,9 @@
|
|||
<bpmndi:BPMNShape id="BoundaryEvent_di" bpmnElement="BoundaryEvent">
|
||||
<dc:Bounds x="582" y="282" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="BoundaryEventRight_di" bpmnElement="BoundaryEventRight">
|
||||
<dc:Bounds x="743" y="200" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
||||
|
|
|
@ -38,6 +38,110 @@ describe('features/snapping - BpmnConnectSnapping', function() {
|
|||
|
||||
describe('connect', function() {
|
||||
|
||||
describe('Boundary Event loop', function() {
|
||||
|
||||
it('should snap to the left',
|
||||
inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var boundaryEvent = elementRegistry.get('BoundaryEvent'),
|
||||
subProcess = elementRegistry.get('SubProcess'),
|
||||
subProcessGfx = elementRegistry.getGraphics(subProcess);
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 600, y: 300 }), boundaryEvent);
|
||||
|
||||
dragging.hover({ element: subProcess, gfx: subProcessGfx });
|
||||
|
||||
dragging.move(canvasEvent({ x: 582, y: 300 }));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var waypoints = boundaryEvent.outgoing[0].waypoints;
|
||||
|
||||
expect(waypoints[3].x).to.eql(560);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('should snap to the right',
|
||||
inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var boundaryEvent = elementRegistry.get('BoundaryEvent'),
|
||||
subProcess = elementRegistry.get('SubProcess'),
|
||||
subProcessGfx = elementRegistry.getGraphics(subProcess);
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 600, y: 300 }), boundaryEvent);
|
||||
|
||||
dragging.hover({ element: subProcess, gfx: subProcessGfx });
|
||||
|
||||
dragging.move(canvasEvent({ x: 618, y: 300 }));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var waypoints = boundaryEvent.outgoing[0].waypoints;
|
||||
|
||||
expect(waypoints[3].x).to.eql(640);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('should snap above',
|
||||
inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var boundaryEvent = elementRegistry.get('BoundaryEventRight'),
|
||||
subProcess = elementRegistry.get('SubProcess'),
|
||||
subProcessGfx = elementRegistry.getGraphics(subProcess);
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 761, y: 218 }), boundaryEvent);
|
||||
|
||||
dragging.hover({ element: subProcess, gfx: subProcessGfx });
|
||||
|
||||
dragging.move(canvasEvent({ x: 761, y: 200 }));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var waypoints = boundaryEvent.outgoing[0].waypoints;
|
||||
|
||||
expect(waypoints[3].y).to.eql(178);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('should snap below',
|
||||
inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var boundaryEvent = elementRegistry.get('BoundaryEventRight'),
|
||||
subProcess = elementRegistry.get('SubProcess'),
|
||||
subProcessGfx = elementRegistry.getGraphics(subProcess);
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 761, y: 218 }), boundaryEvent);
|
||||
|
||||
dragging.hover({ element: subProcess, gfx: subProcessGfx });
|
||||
|
||||
dragging.move(canvasEvent({ x: 761, y: 230 }));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var waypoints = boundaryEvent.outgoing[0].waypoints;
|
||||
|
||||
expect(waypoints[3].y).to.eql(258);
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('should snap event if close to target bounds',
|
||||
inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue