update
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { isAny } from '../modeling/util/ModelingUtil';
|
||||
|
||||
export default function BpmnGridSnapping(eventBus) {
|
||||
eventBus.on([
|
||||
'create.init',
|
||||
'shape.move.init'
|
||||
], function(event) {
|
||||
var context = event.context,
|
||||
shape = event.shape;
|
||||
|
||||
if (isAny(shape, [
|
||||
'bpmn:Participant',
|
||||
'bpmn:SubProcess',
|
||||
'bpmn:TextAnnotation'
|
||||
])) {
|
||||
if (!context.gridSnappingContext) {
|
||||
context.gridSnappingContext = {};
|
||||
}
|
||||
|
||||
context.gridSnappingContext.snapLocation = 'top-left';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BpmnGridSnapping.$inject = [ 'eventBus' ];
|
||||
@@ -0,0 +1,57 @@
|
||||
import { getNewShapePosition } from '../../auto-place/AutoPlaceUtil';
|
||||
|
||||
import { getMid } from 'diagram-js/lib/layout/LayoutUtil';
|
||||
import { is } from '../../../util/ModelUtil';
|
||||
|
||||
|
||||
export default function AutoPlaceBehavior(eventBus, gridSnapping) {
|
||||
eventBus.on('autoPlace', function(context) {
|
||||
var source = context.source,
|
||||
sourceMid = getMid(source),
|
||||
shape = context.shape;
|
||||
|
||||
var position = getNewShapePosition(source, shape);
|
||||
|
||||
[ 'x', 'y' ].forEach(function(axis) {
|
||||
var options = {};
|
||||
|
||||
// do not snap if x/y equal
|
||||
if (position[ axis ] === sourceMid[ axis ]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (position[ axis ] > sourceMid[ axis ]) {
|
||||
options.min = position[ axis ];
|
||||
} else {
|
||||
options.max = position[ axis ];
|
||||
}
|
||||
|
||||
if (is(shape, 'bpmn:TextAnnotation')) {
|
||||
|
||||
if (isHorizontal(axis)) {
|
||||
options.offset = -shape.width / 2;
|
||||
} else {
|
||||
options.offset = -shape.height / 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
position[ axis ] = gridSnapping.snapValue(position[ axis ], options);
|
||||
|
||||
});
|
||||
|
||||
// must be returned to be considered by auto place
|
||||
return position;
|
||||
});
|
||||
}
|
||||
|
||||
AutoPlaceBehavior.$inject = [
|
||||
'eventBus',
|
||||
'gridSnapping'
|
||||
];
|
||||
|
||||
// helpers //////////
|
||||
|
||||
function isHorizontal(axis) {
|
||||
return axis === 'x';
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { is } from '../../../util/ModelUtil';
|
||||
|
||||
var HIGHER_PRIORITY = 1750;
|
||||
|
||||
|
||||
export default function CreateParticipantBehavior(canvas, eventBus, gridSnapping) {
|
||||
eventBus.on([
|
||||
'create.start',
|
||||
'shape.move.start'
|
||||
], HIGHER_PRIORITY, function(event) {
|
||||
var context = event.context,
|
||||
shape = context.shape,
|
||||
rootElement = canvas.getRootElement();
|
||||
|
||||
if (!is(shape, 'bpmn:Participant') ||
|
||||
!is(rootElement, 'bpmn:Process') ||
|
||||
!rootElement.children.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var createConstraints = context.createConstraints;
|
||||
|
||||
if (!createConstraints) {
|
||||
return;
|
||||
}
|
||||
|
||||
shape.width = gridSnapping.snapValue(shape.width, { min: shape.width });
|
||||
shape.height = gridSnapping.snapValue(shape.height, { min: shape.height });
|
||||
});
|
||||
}
|
||||
|
||||
CreateParticipantBehavior.$inject = [
|
||||
'canvas',
|
||||
'eventBus',
|
||||
'gridSnapping'
|
||||
];
|
||||
@@ -0,0 +1,144 @@
|
||||
import inherits from 'inherits';
|
||||
|
||||
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
||||
|
||||
import { pointsAligned } from 'diagram-js/lib/util/Geometry';
|
||||
|
||||
import {
|
||||
assign
|
||||
} from 'min-dash';
|
||||
|
||||
var HIGH_PRIORITY = 3000;
|
||||
|
||||
|
||||
/**
|
||||
* Snaps connections with Manhattan layout.
|
||||
*/
|
||||
export default function LayoutConnectionBehavior(eventBus, gridSnapping, modeling) {
|
||||
CommandInterceptor.call(this, eventBus);
|
||||
|
||||
this._gridSnapping = gridSnapping;
|
||||
|
||||
var self = this;
|
||||
|
||||
this.postExecuted([
|
||||
'connection.create',
|
||||
'connection.layout'
|
||||
], HIGH_PRIORITY, function(event) {
|
||||
var context = event.context,
|
||||
connection = context.connection,
|
||||
hints = context.hints || {},
|
||||
waypoints = connection.waypoints;
|
||||
|
||||
if (hints.connectionStart || hints.connectionEnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasMiddleSegments(waypoints)) {
|
||||
return;
|
||||
}
|
||||
|
||||
modeling.updateWaypoints(connection, self.snapMiddleSegments(waypoints));
|
||||
});
|
||||
}
|
||||
|
||||
LayoutConnectionBehavior.$inject = [
|
||||
'eventBus',
|
||||
'gridSnapping',
|
||||
'modeling'
|
||||
];
|
||||
|
||||
inherits(LayoutConnectionBehavior, CommandInterceptor);
|
||||
|
||||
/**
|
||||
* Snap middle segments of a given connection.
|
||||
*
|
||||
* @param {Array<Point>} waypoints
|
||||
*
|
||||
* @returns {Array<Point>}
|
||||
*/
|
||||
LayoutConnectionBehavior.prototype.snapMiddleSegments = function(waypoints) {
|
||||
var gridSnapping = this._gridSnapping,
|
||||
snapped;
|
||||
|
||||
waypoints = waypoints.slice();
|
||||
|
||||
for (var i = 1; i < waypoints.length - 2; i++) {
|
||||
|
||||
snapped = snapSegment(gridSnapping, waypoints[i], waypoints[i + 1]);
|
||||
|
||||
waypoints[i] = snapped[0];
|
||||
waypoints[i + 1] = snapped[1];
|
||||
}
|
||||
|
||||
return waypoints;
|
||||
};
|
||||
|
||||
|
||||
// helpers //////////
|
||||
|
||||
/**
|
||||
* Check wether a connection has a middle segments.
|
||||
*
|
||||
* @param {Array} waypoints
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasMiddleSegments(waypoints) {
|
||||
return waypoints.length > 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check wether an alignment is horizontal.
|
||||
*
|
||||
* @param {string} aligned
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function horizontallyAligned(aligned) {
|
||||
return aligned === 'h';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check wether an alignment is vertical.
|
||||
*
|
||||
* @param {string} aligned
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function verticallyAligned(aligned) {
|
||||
return aligned === 'v';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get middle segments from a given connection.
|
||||
*
|
||||
* @param {Array} waypoints
|
||||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
function snapSegment(gridSnapping, segmentStart, segmentEnd) {
|
||||
|
||||
var aligned = pointsAligned(segmentStart, segmentEnd);
|
||||
|
||||
var snapped = {};
|
||||
|
||||
if (horizontallyAligned(aligned)) {
|
||||
|
||||
// snap horizontally
|
||||
snapped.y = gridSnapping.snapValue(segmentStart.y);
|
||||
}
|
||||
|
||||
if (verticallyAligned(aligned)) {
|
||||
|
||||
// snap vertically
|
||||
snapped.x = gridSnapping.snapValue(segmentStart.x);
|
||||
}
|
||||
|
||||
if ('x' in snapped || 'y' in snapped) {
|
||||
segmentStart = assign({}, segmentStart, snapped);
|
||||
segmentEnd = assign({}, segmentEnd, snapped);
|
||||
}
|
||||
|
||||
return [ segmentStart, segmentEnd ];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import AutoPlaceBehavior from './AutoPlaceBehavior';
|
||||
import CreateParticipantBehavior from './CreateParticipantBehavior';
|
||||
import LayoutConnectionBehavior from './LayoutConnectionBehavior';
|
||||
|
||||
export default {
|
||||
__init__: [
|
||||
'gridSnappingAutoPlaceBehavior',
|
||||
'gridSnappingCreateParticipantBehavior',
|
||||
'gridSnappingLayoutConnectionBehavior',
|
||||
],
|
||||
gridSnappingAutoPlaceBehavior: [ 'type', AutoPlaceBehavior ],
|
||||
gridSnappingCreateParticipantBehavior: [ 'type', CreateParticipantBehavior ],
|
||||
gridSnappingLayoutConnectionBehavior: [ 'type', LayoutConnectionBehavior ]
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import BpmnGridSnapping from './BpmnGridSnapping';
|
||||
import GridSnappingModule from 'diagram-js/lib/features/grid-snapping';
|
||||
|
||||
import GridSnappingBehaviorModule from './behavior';
|
||||
|
||||
export default {
|
||||
__depends__: [
|
||||
GridSnappingModule,
|
||||
GridSnappingBehaviorModule
|
||||
],
|
||||
__init__: [ 'bpmnGridSnapping' ],
|
||||
bpmnGridSnapping: [ 'type', BpmnGridSnapping ]
|
||||
};
|
||||
Reference in New Issue
Block a user