ToggleElementCollapseBehaviour.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import inherits from 'inherits';
  2. import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
  3. import {
  4. getBusinessObject,
  5. is
  6. } from '../../../util/ModelUtil';
  7. import {
  8. computeChildrenBBox
  9. } from 'diagram-js/lib/features/resize/ResizeUtil';
  10. var LOW_PRIORITY = 500;
  11. export default function ToggleElementCollapseBehaviour(
  12. eventBus, elementFactory, modeling,
  13. resize) {
  14. CommandInterceptor.call(this, eventBus);
  15. function hideEmptyLabels(children) {
  16. if (children.length) {
  17. children.forEach(function(child) {
  18. if (child.type === 'label' && !child.businessObject.name) {
  19. child.hidden = true;
  20. }
  21. });
  22. }
  23. }
  24. function expandedBounds(shape, defaultSize) {
  25. var children = shape.children,
  26. newBounds = defaultSize,
  27. visibleElements,
  28. visibleBBox;
  29. visibleElements = filterVisible(children).concat([ shape ]);
  30. visibleBBox = computeChildrenBBox(visibleElements);
  31. if (visibleBBox) {
  32. // center to visibleBBox with max(defaultSize, childrenBounds)
  33. newBounds.width = Math.max(visibleBBox.width, newBounds.width);
  34. newBounds.height = Math.max(visibleBBox.height, newBounds.height);
  35. newBounds.x = visibleBBox.x + (visibleBBox.width - newBounds.width) / 2;
  36. newBounds.y = visibleBBox.y + (visibleBBox.height - newBounds.height) / 2;
  37. } else {
  38. // center to collapsed shape with defaultSize
  39. newBounds.x = shape.x + (shape.width - newBounds.width) / 2;
  40. newBounds.y = shape.y + (shape.height - newBounds.height) / 2;
  41. }
  42. return newBounds;
  43. }
  44. function collapsedBounds(shape, defaultSize) {
  45. return {
  46. x: shape.x + (shape.width - defaultSize.width) / 2,
  47. y: shape.y + (shape.height - defaultSize.height) / 2,
  48. width: defaultSize.width,
  49. height: defaultSize.height
  50. };
  51. }
  52. this.executed([ 'shape.toggleCollapse' ], LOW_PRIORITY, function(e) {
  53. var context = e.context,
  54. shape = context.shape;
  55. if (!is(shape, 'bpmn:SubProcess')) {
  56. return;
  57. }
  58. if (!shape.collapsed) {
  59. // all children got made visible through djs, hide empty labels
  60. hideEmptyLabels(shape.children);
  61. // remove collapsed marker
  62. getBusinessObject(shape).di.isExpanded = true;
  63. } else {
  64. // place collapsed marker
  65. getBusinessObject(shape).di.isExpanded = false;
  66. }
  67. });
  68. this.reverted([ 'shape.toggleCollapse' ], LOW_PRIORITY, function(e) {
  69. var context = e.context;
  70. var shape = context.shape;
  71. // revert removing/placing collapsed marker
  72. if (!shape.collapsed) {
  73. getBusinessObject(shape).di.isExpanded = true;
  74. } else {
  75. getBusinessObject(shape).di.isExpanded = false;
  76. }
  77. });
  78. this.postExecuted([ 'shape.toggleCollapse' ], LOW_PRIORITY, function(e) {
  79. var shape = e.context.shape,
  80. defaultSize = elementFactory._getDefaultSize(shape),
  81. newBounds;
  82. if (shape.collapsed) {
  83. // resize to default size of collapsed shapes
  84. newBounds = collapsedBounds(shape, defaultSize);
  85. } else {
  86. // resize to bounds of max(visible children, defaultSize)
  87. newBounds = expandedBounds(shape, defaultSize);
  88. }
  89. modeling.resizeShape(shape, newBounds, null, {
  90. autoResize: shape.collapsed ? false : 'nwse'
  91. });
  92. });
  93. }
  94. inherits(ToggleElementCollapseBehaviour, CommandInterceptor);
  95. ToggleElementCollapseBehaviour.$inject = [
  96. 'eventBus',
  97. 'elementFactory',
  98. 'modeling'
  99. ];
  100. // helpers //////////////////////
  101. function filterVisible(elements) {
  102. return elements.filter(function(e) {
  103. return !e.hidden;
  104. });
  105. }