Skip to content

Commit

Permalink
fix: create hit boxes for vertical lanes
Browse files Browse the repository at this point in the history
Closes #2093
  • Loading branch information
sombrek authored and barmac committed Feb 16, 2024
1 parent 5d9822f commit 0a2f759
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 87 deletions.
14 changes: 11 additions & 3 deletions lib/features/interaction-events/BpmnInteractionEvents.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { is } from '../../util/ModelUtil';

import { isExpanded } from '../../util/DiUtil';
import {
isExpanded,
isHorizontal
} from '../../util/DiUtil';

/**
* @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
Expand Down Expand Up @@ -100,10 +103,15 @@ BpmnInteractionEvents.prototype._createParticipantHit = function(element, gfx) {
});

// add label hit
this._interactionEvents.createBoxHit(gfx, 'all', {
var box = isHorizontal(element) ? {
width: LABEL_WIDTH,
height: element.height
});
} : {
width: element.width,
height: LABEL_HEIGHT
};

this._interactionEvents.createBoxHit(gfx, 'all', box);

// indicate that we created a hit
return true;
Expand Down
115 changes: 31 additions & 84 deletions test/fixtures/bpmn/collaboration-vertical.bpmn
Original file line number Diff line number Diff line change
@@ -1,101 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="_pHDz0KojEeOJhIBv1RySdg" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.20.0-dev" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_pHDz0KojEeOJhIBv1RySdg" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn2:collaboration id="_Collaboration_2">
<bpmn2:participant id="Participant_0slfi8f" name="Vertical Participant" processRef="Process_1actwad" />
<bpmn2:participant id="Participant_0ylmo80" name="Vertical Participant" processRef="Process_0wthq21" />
<bpmn2:messageFlow id="Flow_10yw2g3" sourceRef="Activity_12bdr6c" targetRef="Activity_1yln18q" />
<bpmn2:participant id="V_Participant_2" name="V_Pool" processRef="Process_1"/>
<bpmn2:participant id="V_Participant_1" name="V_Pool" processRef="Process_2"/>
</bpmn2:collaboration>
<bpmn2:process id="Process_1actwad" isExecutable="false">
<bpmn2:laneSet id="LaneSet_15j8ay0" />
<bpmn2:startEvent id="Event_1bb0isc">
<bpmn2:outgoing>Flow_0udpwgg</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="Activity_12bdr6c">
<bpmn2:incoming>Flow_0udpwgg</bpmn2:incoming>
<bpmn2:outgoing>Flow_1ds0g2d</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="Flow_0udpwgg" sourceRef="Event_1bb0isc" targetRef="Activity_12bdr6c" />
<bpmn2:sequenceFlow id="Flow_1ds0g2d" sourceRef="Activity_12bdr6c" targetRef="Event_07655c0" />
<bpmn2:endEvent id="Event_07655c0">
<bpmn2:incoming>Flow_1ds0g2d</bpmn2:incoming>
</bpmn2:endEvent>
</bpmn2:process>
<bpmn2:process id="Process_0wthq21" isExecutable="false">
<bpmn2:laneSet id="LaneSet_07waj7z">
<bpmn2:lane id="Lane_03h8w7j" />
<bpmn2:lane id="Lane_03olyrg">
<bpmn2:flowNodeRef>Event_04gz91y</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>Activity_1yln18q</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>Event_0wiu8mt</bpmn2:flowNodeRef>
<bpmn2:process id="Process_1" isExecutable="false">
<bpmn2:laneSet id="LaneSet_1" name="Lane Set 1">
<bpmn2:lane id="V_Lane_1" name="V_Lane 1">
<bpmn2:childLaneSet xsi:type="bpmn2:tLaneSet" id="LaneSet_2">
<bpmn2:lane id="V_Lane_2" name="V_Lane 2"/>
<bpmn2:lane id="V_Lane_3" name="V_Lane 3">
<bpmn2:flowNodeRef>Task_1</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:childLaneSet>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="Event_04gz91y">
<bpmn2:outgoing>Flow_1wsapma</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="Activity_1yln18q">
<bpmn2:incoming>Flow_1wsapma</bpmn2:incoming>
<bpmn2:outgoing>Flow_0jjji9q</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="Flow_1wsapma" sourceRef="Event_04gz91y" targetRef="Activity_1yln18q" />
<bpmn2:endEvent id="Event_0wiu8mt">
<bpmn2:incoming>Flow_0jjji9q</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="Flow_0jjji9q" sourceRef="Activity_1yln18q" targetRef="Event_0wiu8mt" />
<bpmn2:task id="Task_1"/>
</bpmn2:process>
<bpmn2:process id="Process_2" isExecutable="false">
<bpmn2:startEvent id="StartEvent_1"/>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="_Collaboration_2">
<bpmndi:BPMNShape id="BPMNShape_018aq7c" bpmnElement="Participant_0ylmo80" isHorizontal="false">
<dc:Bounds x="180" y="84" width="300" height="400" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_0gwv83s" bpmnElement="Lane_03h8w7j" isHorizontal="false">
<dc:Bounds x="330" y="114" width="150" height="370" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_055tj0q" bpmnElement="Lane_03olyrg" isHorizontal="false">
<dc:Bounds x="180" y="114" width="150" height="370" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_04gz91y_di" bpmnElement="Event_04gz91y">
<dc:Bounds x="232" y="132" width="36" height="36" />
<bpmndi:BPMNPlane id="BPMNPV_Lane_1" bpmnElement="_Collaboration_2">
<bpmndi:BPMNShape id="_BPMNShape_V_Participant_2" bpmnElement="V_Participant_2" isHorizontal="false">
<dc:Bounds x="100.0" y="122.0" width="356.0" height="540.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1yln18q_di" bpmnElement="Activity_1yln18q">
<dc:Bounds x="200" y="240" width="100" height="80" />
<bpmndi:BPMNShape id="_BPMNShape_Participant_3" bpmnElement="V_Participant_1" isHorizontal="false">
<dc:Bounds x="515.0" y="122.0" width="100.0" height="600.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0wiu8mt_di" bpmnElement="Event_0wiu8mt">
<dc:Bounds x="232" y="402" width="36" height="36" />
<bpmndi:BPMNShape id="_BPMNShape_V_Lane_2" bpmnElement="V_Lane_1" isHorizontal="false">
<dc:Bounds x="100.0" y="152.0" width="356.0" height="510.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1wsapma_di" bpmnElement="Flow_1wsapma">
<di:waypoint x="250" y="168" />
<di:waypoint x="250" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0jjji9q_di" bpmnElement="Flow_0jjji9q">
<di:waypoint x="250" y="320" />
<di:waypoint x="250" y="402" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Participant_0slfi8f_di" bpmnElement="Participant_0slfi8f" isHorizontal="false">
<dc:Bounds x="570" y="84" width="300" height="400" />
<bpmndi:BPMNLabel />
<bpmndi:BPMNShape id="_BPMNShape_V_Lane_3" bpmnElement="V_Lane_2" isHorizontal="false">
<dc:Bounds x="100.0" y="182.0" width="215.0" height="480.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1bb0isc_di" bpmnElement="Event_1bb0isc">
<dc:Bounds x="692" y="132" width="36" height="36" />
<bpmndi:BPMNShape id="_BPMNShape_V_Lane_4" bpmnElement="V_Lane_3" isHorizontal="false">
<dc:Bounds x="314.0" y="182.0" width="142.0" height="480.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_12bdr6c_di" bpmnElement="Activity_12bdr6c">
<dc:Bounds x="660" y="240" width="100" height="80" />
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_3" bpmnElement="StartEvent_1">
<dc:Bounds x="548.0" y="224.0" width="36.0" height="36.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_07655c0_di" bpmnElement="Event_07655c0">
<dc:Bounds x="692" y="402" width="36" height="36" />
<bpmndi:BPMNShape id="_BPMNShape_Task_3" bpmnElement="Task_1">
<dc:Bounds x="336.0" y="260.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0udpwgg_di" bpmnElement="Flow_0udpwgg">
<di:waypoint x="710" y="168" />
<di:waypoint x="710" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1ds0g2d_di" bpmnElement="Flow_1ds0g2d">
<di:waypoint x="710" y="320" />
<di:waypoint x="710" y="402" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_10yw2g3_di" bpmnElement="Flow_10yw2g3">
<di:waypoint x="660" y="280" />
<di:waypoint x="300" y="280" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
106 changes: 106 additions & 0 deletions test/spec/features/interaction-events/BpmnInteractionEventsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,33 @@ describe('features/interaction-events', function() {

// given
var participant = elementRegistry.get('Participant_1');
var hitZones = getHitZones(participant);

// then
expectToHaveChildren(HIT_ALL_CLS, 1, participant);
expectToHaveChildren(HIT_CLICK_STROKE_CLS, 1, participant);
expectToHaveChildren(HIT_NO_MOVE_CLS, 1, participant);

expectSize(hitZones.all[0], { width: 30, height: participant.height });
expectSize(hitZones.click[0], { width: participant.width, height: participant.height });
expectSize(hitZones.noMove[0], { width: participant.width, height: participant.height });
}));


it('should create THREE hit zones per lane', inject(function(elementRegistry) {

// given
var lane = elementRegistry.get('Lane_1');
var hitZones = getHitZones(lane);

// then
expectToHaveChildren(HIT_ALL_CLS, 1, lane);
expectToHaveChildren(HIT_CLICK_STROKE_CLS, 1, lane);
expectToHaveChildren(HIT_NO_MOVE_CLS, 1, lane);

expectSize(hitZones.all[0], { width: 30, height: lane.height });
expectSize(hitZones.click[0], { width: lane.width, height: lane.height });
expectSize(hitZones.noMove[0], { width: lane.width, height: lane.height });
}));


Expand All @@ -78,10 +88,80 @@ describe('features/interaction-events', function() {
type: 'bpmn:Participant',
isExpanded: false
});
var hitZones = getHitZones(collapsedParticipant);

// then
expectToHaveChildren(HIT_ALL_CLS, 1, collapsedParticipant);
expectSize(hitZones.all[0], { width: collapsedParticipant.width, height: collapsedParticipant.height });
})
);

});


describe('vertical participant hits', function() {

var diagramXML = require('test/fixtures/bpmn/collaboration-vertical.bpmn');

beforeEach(bootstrapModeler(diagramXML, {
modules: testModules
}));

beforeEach(inject(function(dragging) {
dragging.setOptions({ manual: true });
}));


it('should create THREE hit zones per participant', inject(function(elementRegistry) {

// given
var participant = elementRegistry.get('V_Participant_1');
var hitZones = getHitZones(participant);

// then
expectToHaveChildren(HIT_ALL_CLS, 1, participant);
expectToHaveChildren(HIT_CLICK_STROKE_CLS, 1, participant);
expectToHaveChildren(HIT_NO_MOVE_CLS, 1, participant);

expectSize(hitZones.all[0], { width: participant.width, height: 30 });
expectSize(hitZones.click[0], { width: participant.width, height: participant.height });
expectSize(hitZones.noMove[0], { width: participant.width, height: participant.height });
}));


it('should create THREE hit zones per lane', inject(function(elementRegistry) {

// given
var lane = elementRegistry.get('V_Lane_1');
var hitZones = getHitZones(lane);

// then
expectToHaveChildren(HIT_ALL_CLS, 1, lane);
expectToHaveChildren(HIT_CLICK_STROKE_CLS, 1, lane);
expectToHaveChildren(HIT_NO_MOVE_CLS, 1, lane);

expectSize(hitZones.all[0], { width: lane.width, height: 30 });
expectSize(hitZones.click[0], { width: lane.width, height: lane.height });
expectSize(hitZones.noMove[0], { width: lane.width, height: lane.height });
}));


it('should create one hit zone per collapsed participant',
inject(function(elementRegistry, bpmnReplace) {

// given
var participant = elementRegistry.get('V_Participant_1');

// when
var collapsedParticipant = bpmnReplace.replaceElement(participant, {
type: 'bpmn:Participant',
isExpanded: false
});
var hitZones = getHitZones(collapsedParticipant);

// then
expectToHaveChildren(HIT_ALL_CLS, 1, collapsedParticipant);
expectSize(hitZones.all[0], { width: collapsedParticipant.width, height: collapsedParticipant.height });
})
);

Expand Down Expand Up @@ -152,3 +232,29 @@ function expectToHaveChildren(className, expectedCount, element) {
' children mat ' + selector + ' but got ' + realCount
).to.eql(expectedCount);
}

function getHitZones(element) {
var elementRegistry = getBpmnJS().get('elementRegistry'),
gfx = elementRegistry.getGraphics(element);

return {
all: domQueryAll('.' + HIT_ALL_CLS, gfx),
click: domQueryAll('.' + HIT_CLICK_STROKE_CLS, gfx),
noMove: domQueryAll('.' + HIT_NO_MOVE_CLS, gfx)
};
}

function expectSize(element, expectedSize) {
var size = getSize(element);

expect(size.width).to.eql(expectedSize.width);
expect(size.height).to.eql(expectedSize.height);
}

function getSize(element) {
const bbox = element.getBBox();
return {
width: bbox.width,
height: bbox.height
};
}

0 comments on commit 0a2f759

Please sign in to comment.