feat(snapping): snap message flows to bpmn:Event mid
This snaps source / target to the element mid, if the element is a `bpmn:Event`. There is usually no more than one snap point for an event other than the center. Closes #850
This commit is contained in:
parent
cdacc69a3d
commit
6689af6f5b
|
@ -1,8 +1,7 @@
|
|||
import inherits from 'inherits';
|
||||
|
||||
import {
|
||||
forEach,
|
||||
assign
|
||||
forEach
|
||||
} from 'min-dash';
|
||||
|
||||
import {
|
||||
|
@ -179,9 +178,23 @@ export default function BpmnSnapping(eventBus, canvas, bpmnRules, elementRegistr
|
|||
context.sourcePosition = mid(source);
|
||||
|
||||
// snap target
|
||||
assign(event, mid(target));
|
||||
} else {
|
||||
snapToPosition(event, mid(target));
|
||||
} else
|
||||
|
||||
if (connection.type === 'bpmn:MessageFlow') {
|
||||
|
||||
if (is(source, 'bpmn:Event')) {
|
||||
// snap source
|
||||
context.sourcePosition = mid(source);
|
||||
}
|
||||
|
||||
if (is(target, 'bpmn:Event')) {
|
||||
// snap target
|
||||
snapToPosition(event, mid(target));
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
// otherwise reset source snap
|
||||
context.sourcePosition = context.initialSourcePosition;
|
||||
}
|
||||
|
@ -455,3 +468,9 @@ function snapBoundaryEvent(event, shape, target) {
|
|||
setSnapped(event, 'x', targetTRBL.right);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function snapToPosition(event, position) {
|
||||
setSnapped(event, 'x', position.x);
|
||||
setSnapped(event, 'y', position.y);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.1.1">
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.1.1">
|
||||
<bpmn:collaboration id="Collaboration_1">
|
||||
<bpmn:participant id="Participant_1" processRef="Process_1" />
|
||||
<bpmn:participant id="Participant_2" processRef="Process_1e043dv" />
|
||||
|
@ -13,6 +13,7 @@
|
|||
<bpmn:process id="Process_1e043dv" isExecutable="false">
|
||||
<bpmn:task id="Task_2" />
|
||||
<bpmn:dataStoreReference id="DataStoreReference_1" />
|
||||
<bpmn:intermediateThrowEvent id="IntermediateEvent" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
|
||||
|
@ -46,6 +47,9 @@
|
|||
<dc:Bounds x="214" y="147" width="0" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="IntermediateEvent_di" bpmnElement="IntermediateEvent">
|
||||
<dc:Bounds x="175" y="222" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
||||
|
|
|
@ -706,107 +706,111 @@ describe('features/snapping - BpmnSnapping', function() {
|
|||
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
|
||||
|
||||
|
||||
it('should snap sequence flow on global connect', inject(function(connect, dragging, elementRegistry) {
|
||||
describe('sequence flow', function() {
|
||||
|
||||
// given
|
||||
var startEvent = elementRegistry.get('StartEvent_1'),
|
||||
task = elementRegistry.get('Task_1');
|
||||
it('should snap on global connect', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
var mid = {
|
||||
x: startEvent.x + startEvent.width / 2,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
};
|
||||
// given
|
||||
var startEvent = elementRegistry.get('StartEvent_1'),
|
||||
task = elementRegistry.get('Task_1');
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: mid.x + 10, y: mid.y + 10 }), startEvent);
|
||||
var mid = {
|
||||
x: startEvent.x + startEvent.width / 2,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
};
|
||||
|
||||
dragging.hover({
|
||||
element: task,
|
||||
gfx: elementRegistry.getGraphics(task)
|
||||
});
|
||||
// when
|
||||
connect.start(canvasEvent({ x: mid.x + 10, y: mid.y + 10 }), startEvent);
|
||||
|
||||
dragging.hover({
|
||||
element: task,
|
||||
gfx: elementRegistry.getGraphics(task)
|
||||
});
|
||||
|
||||
dragging.move(canvasEvent({
|
||||
x: task.x + task.width / 2,
|
||||
y: task.y + task.height / 2
|
||||
}));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var expected = [
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: startEvent.x + startEvent.width / 2,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
},
|
||||
x: startEvent.x + startEvent.width,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
},
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: task.x + task.width / 2,
|
||||
y: task.y + task.height / 2
|
||||
},
|
||||
x: task.x,
|
||||
y: task.y + task.height / 2
|
||||
}
|
||||
];
|
||||
|
||||
expect(startEvent.outgoing[0].waypoints).to.eql(expected);
|
||||
|
||||
dragging.move(canvasEvent({
|
||||
x: task.x + task.width / 2,
|
||||
y: task.y + task.height / 2
|
||||
}));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var expected = [
|
||||
{
|
||||
original:
|
||||
it('should snap on connect', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var startEvent = elementRegistry.get('StartEvent_1'),
|
||||
task = elementRegistry.get('Task_1');
|
||||
|
||||
var mid = { x: task.x + task.width / 2, y: task.y + task.height / 2 };
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 0, y: 0 }), startEvent);
|
||||
|
||||
dragging.hover({
|
||||
element: task,
|
||||
gfx: elementRegistry.getGraphics(task)
|
||||
});
|
||||
|
||||
dragging.move(canvasEvent({ x: mid.x + 10, y: mid.y + 10 }));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var expected = [
|
||||
{
|
||||
x: startEvent.x + startEvent.width / 2,
|
||||
original:
|
||||
{
|
||||
x: startEvent.x + startEvent.width / 2,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
},
|
||||
x: startEvent.x + startEvent.width,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
},
|
||||
x: startEvent.x + startEvent.width,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
},
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: task.x + task.width / 2,
|
||||
original:
|
||||
{
|
||||
x: task.x + task.width / 2,
|
||||
y: task.y + task.height / 2
|
||||
},
|
||||
x: task.x,
|
||||
y: task.y + task.height / 2
|
||||
},
|
||||
x: task.x,
|
||||
y: task.y + task.height / 2
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
expect(startEvent.outgoing[0].waypoints).to.eql(expected);
|
||||
expect(startEvent.outgoing[0].waypoints).to.eql(expected);
|
||||
|
||||
}));
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('should snap sequence flow on connect', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var startEvent = elementRegistry.get('StartEvent_1'),
|
||||
task = elementRegistry.get('Task_1');
|
||||
|
||||
var mid = { x: task.x + task.width / 2, y: task.y + task.height / 2 };
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 0, y: 0 }), startEvent);
|
||||
|
||||
dragging.hover({
|
||||
element: task,
|
||||
gfx: elementRegistry.getGraphics(task)
|
||||
});
|
||||
|
||||
dragging.move(canvasEvent({ x: mid.x + 10, y: mid.y + 10 }));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var expected = [
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: startEvent.x + startEvent.width / 2,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
},
|
||||
x: startEvent.x + startEvent.width,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
},
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: task.x + task.width / 2,
|
||||
y: task.y + task.height / 2
|
||||
},
|
||||
x: task.x,
|
||||
y: task.y + task.height / 2
|
||||
}
|
||||
];
|
||||
|
||||
expect(startEvent.outgoing[0].waypoints).to.eql(expected);
|
||||
|
||||
}));
|
||||
|
||||
|
||||
it('should snap data output association on connect', inject(function(connect, dragging, elementRegistry) {
|
||||
it('should snap data output association', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var startEvent = elementRegistry.get('StartEvent_1'),
|
||||
|
@ -853,7 +857,7 @@ describe('features/snapping - BpmnSnapping', function() {
|
|||
}));
|
||||
|
||||
|
||||
it('should snap data input association on connect', inject(function(connect, dragging, elementRegistry) {
|
||||
it('should snap data input association', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var dataStoreReference = elementRegistry.get('DataStoreReference_1'),
|
||||
|
@ -900,105 +904,213 @@ describe('features/snapping - BpmnSnapping', function() {
|
|||
}));
|
||||
|
||||
|
||||
it('should NOT snap message flow on global connect', inject(function(connect, dragging, elementRegistry) {
|
||||
describe('message flow', function() {
|
||||
|
||||
// given
|
||||
var task1 = elementRegistry.get('Task_1'),
|
||||
task2 = elementRegistry.get('Task_2');
|
||||
it('should NOT snap Task -> Task on global connect', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
var task1Mid = { x: task1.x + task1.width / 2, y: task1.y + task1.height / 2 },
|
||||
task2Mid = { x: task2.x + task2.width / 2, y: task2.y + task2.height / 2 };
|
||||
// given
|
||||
var task1 = elementRegistry.get('Task_1'),
|
||||
task2 = elementRegistry.get('Task_2');
|
||||
|
||||
// when
|
||||
connect.start(null, task1, { x: 320, y: task1Mid.y + 20 });
|
||||
var task1Mid = { x: task1.x + task1.width / 2, y: task1.y + task1.height / 2 },
|
||||
task2Mid = { x: task2.x + task2.width / 2, y: task2.y + task2.height / 2 };
|
||||
|
||||
dragging.hover({
|
||||
element: task2,
|
||||
gfx: elementRegistry.getGraphics(task2)
|
||||
});
|
||||
// when
|
||||
connect.start(null, task1, { x: 320, y: task1Mid.y + 20 });
|
||||
|
||||
dragging.hover({
|
||||
element: task2,
|
||||
gfx: elementRegistry.getGraphics(task2)
|
||||
});
|
||||
|
||||
dragging.move(canvasEvent({
|
||||
x: 320,
|
||||
y: task2Mid.y - 20
|
||||
}));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var expected = [
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: 320,
|
||||
y: task1Mid.y + 20
|
||||
},
|
||||
x: 320,
|
||||
y: task1.y + task1.height
|
||||
},
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: 320,
|
||||
y: task2Mid.y - 20
|
||||
},
|
||||
x: 320,
|
||||
y: task2.y
|
||||
}
|
||||
];
|
||||
|
||||
expect(task1.outgoing[0].waypoints).to.eql(expected);
|
||||
|
||||
dragging.move(canvasEvent({
|
||||
x: 320,
|
||||
y: task2Mid.y - 20
|
||||
}));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var expected = [
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: 320,
|
||||
y: task1Mid.y + 20
|
||||
},
|
||||
x: 320,
|
||||
y: task1.y + task1.height
|
||||
},
|
||||
{
|
||||
original:
|
||||
{
|
||||
x: 320,
|
||||
y: task2Mid.y - 20
|
||||
},
|
||||
x: 320,
|
||||
y: task2.y
|
||||
}
|
||||
];
|
||||
it('should NOT snap Task -> Task on connect', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
expect(task1.outgoing[0].waypoints).to.eql(expected);
|
||||
// given
|
||||
var task1 = elementRegistry.get('Task_1'),
|
||||
task2 = elementRegistry.get('Task_2');
|
||||
|
||||
}));
|
||||
var task1Mid = { x: task1.x + task1.width / 2, y: task1.y + task1.height / 2 },
|
||||
task2Mid = { x: task2.x + task2.width / 2, y: task2.y + task2.height / 2 };
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 0, y: 0 }), task1);
|
||||
|
||||
it('should NOT snap message flow on connect', inject(function(connect, dragging, elementRegistry) {
|
||||
dragging.hover({
|
||||
element: task2,
|
||||
gfx: elementRegistry.getGraphics(task2)
|
||||
});
|
||||
|
||||
// given
|
||||
var task1 = elementRegistry.get('Task_1'),
|
||||
task2 = elementRegistry.get('Task_2');
|
||||
|
||||
var task1Mid = { x: task1.x + task1.width / 2, y: task1.y + task1.height / 2 },
|
||||
task2Mid = { x: task2.x + task2.width / 2, y: task2.y + task2.height / 2 };
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 0, y: 0 }), task1);
|
||||
|
||||
dragging.hover({
|
||||
element: task2,
|
||||
gfx: elementRegistry.getGraphics(task2)
|
||||
});
|
||||
|
||||
dragging.move(canvasEvent({
|
||||
x: task2Mid.x + 20,
|
||||
y: task2Mid.y - 20
|
||||
}));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
expect(task1.outgoing[0].waypoints.length).to.equal(4);
|
||||
|
||||
expect(task1.outgoing[0].waypoints[0]).to.eql({
|
||||
original:
|
||||
{
|
||||
x: task1Mid.x,
|
||||
y: task1Mid.y
|
||||
},
|
||||
x: task1Mid.x,
|
||||
y: task1.y + task1.height
|
||||
});
|
||||
|
||||
expect(task1.outgoing[0].waypoints[3]).to.eql({
|
||||
original:
|
||||
{
|
||||
dragging.move(canvasEvent({
|
||||
x: task2Mid.x + 20,
|
||||
y: task2Mid.y - 20
|
||||
},
|
||||
x: task2Mid.x + 20,
|
||||
y: task2.y
|
||||
});
|
||||
}));
|
||||
|
||||
}));
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
expect(task1.outgoing[0].waypoints.length).to.equal(4);
|
||||
|
||||
expect(task1.outgoing[0].waypoints[0]).to.eql({
|
||||
original:
|
||||
{
|
||||
x: task1Mid.x,
|
||||
y: task1Mid.y
|
||||
},
|
||||
x: task1Mid.x,
|
||||
y: task1.y + task1.height
|
||||
});
|
||||
|
||||
expect(task1.outgoing[0].waypoints[3]).to.eql({
|
||||
original:
|
||||
{
|
||||
x: task2Mid.x + 20,
|
||||
y: task2Mid.y - 20
|
||||
},
|
||||
x: task2Mid.x + 20,
|
||||
y: task2.y
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
|
||||
it('should snap Task -> Event on connect', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var task = elementRegistry.get('Task_2'),
|
||||
event = elementRegistry.get('StartEvent_1');
|
||||
|
||||
var taskMid = { x: task.x + task.width / 2, y: task.y + task.height / 2 },
|
||||
eventMid = { x: event.x + event.width / 2, y: event.y + event.height / 2 };
|
||||
|
||||
// when
|
||||
connect.start(canvasEvent({ x: 0, y: 0 }), task);
|
||||
|
||||
dragging.hover({
|
||||
element: event,
|
||||
gfx: elementRegistry.getGraphics(event)
|
||||
});
|
||||
|
||||
dragging.move(canvasEvent({
|
||||
x: eventMid.x + 10,
|
||||
y: eventMid.y - 10
|
||||
}));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var connection = task.outgoing[0];
|
||||
|
||||
expect(connection.waypoints.length).to.equal(4);
|
||||
|
||||
expect(connection.waypoints[0]).to.eql({
|
||||
original:
|
||||
{
|
||||
x: taskMid.x,
|
||||
y: taskMid.y
|
||||
},
|
||||
x: taskMid.x,
|
||||
y: task.y
|
||||
});
|
||||
|
||||
expect(connection.waypoints[3]).to.eql({
|
||||
original:
|
||||
{
|
||||
x: eventMid.x,
|
||||
y: eventMid.y
|
||||
},
|
||||
x: eventMid.x,
|
||||
y: event.y + event.height
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
|
||||
it('should snap IntermediateEvent -> Task on global connect', inject(function(connect, dragging, elementRegistry) {
|
||||
|
||||
// given
|
||||
var event = elementRegistry.get('IntermediateEvent'),
|
||||
task = elementRegistry.get('Task_1');
|
||||
|
||||
var eventMid = { x: event.x + event.width / 2, y: event.y + event.height / 2 },
|
||||
taskMid = { x: task.x + task.width / 2, y: task.y + task.height / 2 };
|
||||
|
||||
// when
|
||||
connect.start(null, event, { x: eventMid.x - 10, y: eventMid.y + 10 });
|
||||
|
||||
dragging.hover({
|
||||
element: task,
|
||||
gfx: elementRegistry.getGraphics(task)
|
||||
});
|
||||
|
||||
dragging.move(canvasEvent({
|
||||
x: taskMid.x + 10,
|
||||
y: taskMid.y - 10
|
||||
}));
|
||||
|
||||
dragging.end();
|
||||
|
||||
// then
|
||||
var connection = event.outgoing[0];
|
||||
|
||||
expect(connection.waypoints.length).to.equal(4);
|
||||
|
||||
expect(connection.waypoints[0]).to.eql({
|
||||
original:
|
||||
{
|
||||
x: eventMid.x,
|
||||
y: eventMid.y
|
||||
},
|
||||
x: eventMid.x,
|
||||
y: event.y
|
||||
});
|
||||
|
||||
expect(connection.waypoints[3]).to.eql({
|
||||
original:
|
||||
{
|
||||
x: taskMid.x + 10,
|
||||
y: taskMid.y - 10
|
||||
},
|
||||
x: taskMid.x + 10,
|
||||
y: task.y + task.height
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue