import { forEach } from 'min-dash'; import { is } from '../../../util/ModelUtil'; import { isExpanded } from '../../../util/DiUtil'; import { LANE_MIN_DIMENSIONS, PARTICIPANT_MIN_DIMENSIONS, SUB_PROCESS_MIN_DIMENSIONS, TEXT_ANNOTATION_MIN_DIMENSIONS } from './ResizeBehavior'; import { getChildLanes } from '../util/LaneUtil'; var max = Math.max; export default function SpaceToolBehavior(eventBus) { eventBus.on('spaceTool.getMinDimensions', function(context) { var shapes = context.shapes, axis = context.axis, start = context.start, minDimensions = {}; forEach(shapes, function(shape) { var id = shape.id; if (is(shape, 'bpmn:Participant')) { if (isHorizontal(axis)) { minDimensions[ id ] = PARTICIPANT_MIN_DIMENSIONS; } else { minDimensions[ id ] = { width: PARTICIPANT_MIN_DIMENSIONS.width, height: getParticipantMinHeight(shape, start) }; } } if (is(shape, 'bpmn:SubProcess') && isExpanded(shape)) { minDimensions[ id ] = SUB_PROCESS_MIN_DIMENSIONS; } if (is(shape, 'bpmn:TextAnnotation')) { minDimensions[ id ] = TEXT_ANNOTATION_MIN_DIMENSIONS; } }); return minDimensions; }); } SpaceToolBehavior.$inject = [ 'eventBus' ]; // helpers ////////// function isHorizontal(axis) { return axis === 'x'; } /** * Get minimum height for participant taking lanes into account. * * @param {} participant * @param {number} start * * @returns {Object} */ function getParticipantMinHeight(participant, start) { var lanesMinHeight; if (!hasChildLanes(participant)) { return PARTICIPANT_MIN_DIMENSIONS.height; } lanesMinHeight = getLanesMinHeight(participant, start); return max(PARTICIPANT_MIN_DIMENSIONS.height, lanesMinHeight); } function hasChildLanes(element) { return !!getChildLanes(element).length; } function getLanesMinHeight(participant, resizeStart) { var lanes = getChildLanes(participant), resizedLane; // find the nested lane which is currently resized resizedLane = findResizedLane(lanes, resizeStart); // resized lane cannot shrink below the minimum height // but remaining lanes' dimensions are kept intact return participant.height - resizedLane.height + LANE_MIN_DIMENSIONS.height; } /** * Find nested lane which is currently resized. * * @param {Array} lanes * @param {number} resizeStart */ function findResizedLane(lanes, resizeStart) { var i, lane, childLanes; for (i = 0; i < lanes.length; i++) { lane = lanes[i]; // resizing current lane or a lane nested if (resizeStart >= lane.y && resizeStart <= lane.y + lane.height) { childLanes = getChildLanes(lane); // a nested lane is resized if (childLanes.length) { return findResizedLane(childLanes, resizeStart); } // current lane is the resized one return lane; } } }