AppendPreview.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import {
  2. assign,
  3. isNil
  4. } from 'min-dash';
  5. const round = Math.round;
  6. /**
  7. * @typedef {import('diagram-js/lib/features/complex-preview/ComplexPreview').default} ComplexPreview
  8. * @typedef {import('diagram-js/lib/layout/ConnectionDocking').default} ConnectionDocking
  9. * @typedef {import('../modeling/ElementFactory').default} ElementFactory
  10. * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
  11. * @typedef {import('diagram-js/lib/layout/ManhattanLayout').default} ManhattanLayout
  12. * @typedef {import('diagram-js/lib/features/rules/Rules').default} Rules
  13. *
  14. * @typedef {import('../../model/Types').Shape} Shape
  15. */
  16. /**
  17. * A preview for appending.
  18. *
  19. * @param {ComplexPreview} complexPreview
  20. * @param {ConnectionDocking} connectionDocking
  21. * @param {ElementFactory} elementFactory
  22. * @param {EventBus} eventBus
  23. * @param {ManhattanLayout} layouter
  24. * @param {Rules} rules
  25. */
  26. export default function AppendPreview(complexPreview, connectionDocking, elementFactory, eventBus, layouter, rules) {
  27. this._complexPreview = complexPreview;
  28. this._connectionDocking = connectionDocking;
  29. this._elementFactory = elementFactory;
  30. this._eventBus = eventBus;
  31. this._layouter = layouter;
  32. this._rules = rules;
  33. }
  34. /**
  35. * Create a preview of appending a shape of the given type to the given source.
  36. *
  37. * @param {Shape} source
  38. * @param {string} type
  39. * @param {Partial<Shape>} options
  40. */
  41. AppendPreview.prototype.create = function(source, type, options) {
  42. const complexPreview = this._complexPreview,
  43. connectionDocking = this._connectionDocking,
  44. elementFactory = this._elementFactory,
  45. eventBus = this._eventBus,
  46. layouter = this._layouter,
  47. rules = this._rules;
  48. const shape = elementFactory.createShape(assign({ type }, options));
  49. const position = eventBus.fire('autoPlace', {
  50. source,
  51. shape
  52. });
  53. if (!position) {
  54. return;
  55. }
  56. assign(shape, {
  57. x: position.x - round(shape.width / 2),
  58. y: position.y - round(shape.height / 2)
  59. });
  60. const connectionCreateAllowed = rules.allowed('connection.create', {
  61. source,
  62. target: shape,
  63. hints: {
  64. targetParent: source.parent
  65. }
  66. });
  67. let connection = null;
  68. if (connectionCreateAllowed) {
  69. connection = elementFactory.createConnection(connectionCreateAllowed);
  70. connection.waypoints = layouter.layoutConnection(connection, {
  71. source,
  72. target: shape
  73. });
  74. connection.waypoints = connectionDocking.getCroppedWaypoints(connection, source, shape);
  75. }
  76. complexPreview.create({
  77. created: [
  78. shape,
  79. connection
  80. ].filter((element) => !isNil(element))
  81. });
  82. };
  83. AppendPreview.prototype.cleanUp = function() {
  84. this._complexPreview.cleanUp();
  85. };
  86. AppendPreview.$inject = [
  87. 'complexPreview',
  88. 'connectionDocking',
  89. 'elementFactory',
  90. 'eventBus',
  91. 'layouter',
  92. 'rules'
  93. ];