SpaceToolBehavior.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { forEach } from 'min-dash';
  2. import { is } from '../../../util/ModelUtil';
  3. import { isExpanded } from '../../../util/DiUtil';
  4. import {
  5. GROUP_MIN_DIMENSIONS,
  6. LANE_MIN_DIMENSIONS,
  7. PARTICIPANT_MIN_DIMENSIONS,
  8. SUB_PROCESS_MIN_DIMENSIONS,
  9. TEXT_ANNOTATION_MIN_DIMENSIONS
  10. } from './ResizeBehavior';
  11. import { getChildLanes } from '../util/LaneUtil';
  12. /**
  13. * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
  14. *
  15. * @typedef {import('../../../model/Types').Shape} Shape
  16. */
  17. var max = Math.max;
  18. /**
  19. * @param {EventBus} eventBus
  20. */
  21. export default function SpaceToolBehavior(eventBus) {
  22. eventBus.on('spaceTool.getMinDimensions', function(context) {
  23. var shapes = context.shapes,
  24. axis = context.axis,
  25. start = context.start,
  26. minDimensions = {};
  27. forEach(shapes, function(shape) {
  28. var id = shape.id;
  29. if (is(shape, 'bpmn:Participant')) {
  30. if (isHorizontal(axis)) {
  31. minDimensions[ id ] = PARTICIPANT_MIN_DIMENSIONS;
  32. } else {
  33. minDimensions[ id ] = {
  34. width: PARTICIPANT_MIN_DIMENSIONS.width,
  35. height: getParticipantMinHeight(shape, start)
  36. };
  37. }
  38. }
  39. if (is(shape, 'bpmn:SubProcess') && isExpanded(shape)) {
  40. minDimensions[ id ] = SUB_PROCESS_MIN_DIMENSIONS;
  41. }
  42. if (is(shape, 'bpmn:TextAnnotation')) {
  43. minDimensions[ id ] = TEXT_ANNOTATION_MIN_DIMENSIONS;
  44. }
  45. if (is(shape, 'bpmn:Group')) {
  46. minDimensions[ id ] = GROUP_MIN_DIMENSIONS;
  47. }
  48. });
  49. return minDimensions;
  50. });
  51. }
  52. SpaceToolBehavior.$inject = [ 'eventBus' ];
  53. // helpers //////////
  54. function isHorizontal(axis) {
  55. return axis === 'x';
  56. }
  57. /**
  58. * Get minimum height for participant taking lanes into account.
  59. *
  60. * @param {Shape} participant
  61. * @param {number} start
  62. *
  63. * @return {number}
  64. */
  65. function getParticipantMinHeight(participant, start) {
  66. var lanesMinHeight;
  67. if (!hasChildLanes(participant)) {
  68. return PARTICIPANT_MIN_DIMENSIONS.height;
  69. }
  70. lanesMinHeight = getLanesMinHeight(participant, start);
  71. return max(PARTICIPANT_MIN_DIMENSIONS.height, lanesMinHeight);
  72. }
  73. function hasChildLanes(element) {
  74. return !!getChildLanes(element).length;
  75. }
  76. function getLanesMinHeight(participant, resizeStart) {
  77. var lanes = getChildLanes(participant),
  78. resizedLane;
  79. // find the nested lane which is currently resized
  80. resizedLane = findResizedLane(lanes, resizeStart);
  81. // resized lane cannot shrink below the minimum height
  82. // but remaining lanes' dimensions are kept intact
  83. return participant.height - resizedLane.height + LANE_MIN_DIMENSIONS.height;
  84. }
  85. /**
  86. * Find nested lane which is currently resized.
  87. *
  88. * @param {Shape[]} lanes
  89. * @param {number} resizeStart
  90. *
  91. * @return {Shape}
  92. */
  93. function findResizedLane(lanes, resizeStart) {
  94. var i, lane, childLanes;
  95. for (i = 0; i < lanes.length; i++) {
  96. lane = lanes[i];
  97. // resizing current lane or a lane nested
  98. if (resizeStart >= lane.y && resizeStart <= lane.y + lane.height) {
  99. childLanes = getChildLanes(lane);
  100. // a nested lane is resized
  101. if (childLanes.length) {
  102. return findResizedLane(childLanes, resizeStart);
  103. }
  104. // current lane is the resized one
  105. return lane;
  106. }
  107. }
  108. }