SplitLaneHandler.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import {
  2. getChildLanes,
  3. LANE_INDENTATION
  4. } from '../util/LaneUtil';
  5. /**
  6. * @typedef {import('diagram-js/lib/command/CommandHandler').default} CommandHandler
  7. *
  8. * @typedef {import('../Modeling').default} Modeling
  9. * @typedef {import('diagram-js/lib/i18n/translate/translate').default} Translate
  10. */
  11. /**
  12. * A handler that splits a lane into a number of sub-lanes,
  13. * creating new sub lanes, if necessary.
  14. *
  15. * @implements {CommandHandler}
  16. *
  17. * @param {Modeling} modeling
  18. * @param {Translate} translate
  19. */
  20. export default function SplitLaneHandler(modeling, translate) {
  21. this._modeling = modeling;
  22. this._translate = translate;
  23. }
  24. SplitLaneHandler.$inject = [
  25. 'modeling',
  26. 'translate'
  27. ];
  28. SplitLaneHandler.prototype.preExecute = function(context) {
  29. var modeling = this._modeling,
  30. translate = this._translate;
  31. var shape = context.shape,
  32. newLanesCount = context.count;
  33. var childLanes = getChildLanes(shape),
  34. existingLanesCount = childLanes.length;
  35. if (existingLanesCount > newLanesCount) {
  36. throw new Error(translate('more than {count} child lanes', { count: newLanesCount }));
  37. }
  38. var newLanesHeight = Math.round(shape.height / newLanesCount);
  39. // Iterate from top to bottom in child lane order,
  40. // resizing existing lanes and creating new ones
  41. // so that they split the parent proportionally.
  42. //
  43. // Due to rounding related errors, the bottom lane
  44. // needs to take up all the remaining space.
  45. var laneY,
  46. laneHeight,
  47. laneBounds,
  48. newLaneAttrs,
  49. idx;
  50. for (idx = 0; idx < newLanesCount; idx++) {
  51. laneY = shape.y + idx * newLanesHeight;
  52. // if bottom lane
  53. if (idx === newLanesCount - 1) {
  54. laneHeight = shape.height - (newLanesHeight * idx);
  55. } else {
  56. laneHeight = newLanesHeight;
  57. }
  58. laneBounds = {
  59. x: shape.x + LANE_INDENTATION,
  60. y: laneY,
  61. width: shape.width - LANE_INDENTATION,
  62. height: laneHeight
  63. };
  64. if (idx < existingLanesCount) {
  65. // resize existing lane
  66. modeling.resizeShape(childLanes[idx], laneBounds);
  67. } else {
  68. // create a new lane at position
  69. newLaneAttrs = {
  70. type: 'bpmn:Lane'
  71. };
  72. modeling.createShape(newLaneAttrs, laneBounds, shape);
  73. }
  74. }
  75. };