diff --git a/lib/features/grid-snapping/behavior/LayoutConnectionBehavior.js b/lib/features/grid-snapping/behavior/LayoutConnectionBehavior.js index 849375fa..7c357c50 100644 --- a/lib/features/grid-snapping/behavior/LayoutConnectionBehavior.js +++ b/lib/features/grid-snapping/behavior/LayoutConnectionBehavior.js @@ -4,6 +4,10 @@ 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; @@ -30,11 +34,11 @@ export default function LayoutConnectionBehavior(eventBus, gridSnapping, modelin return; } - if (hasMiddleSegments(waypoints)) { - modeling.updateProperties(connection, { - waypoints: self.snapMiddleSegments(waypoints) - }); + if (!hasMiddleSegments(waypoints)) { + return; } + + modeling.updateWaypoints(connection, self.snapMiddleSegments(waypoints)); }); } @@ -54,34 +58,23 @@ inherits(LayoutConnectionBehavior, CommandInterceptor); * @returns {Array} */ LayoutConnectionBehavior.prototype.snapMiddleSegments = function(waypoints) { - var gridSnapping = this._gridSnapping; + var gridSnapping = this._gridSnapping, + snapped; - var middleSegments = getMiddleSegments(waypoints); + waypoints = waypoints.slice(); - middleSegments.forEach(function(middleSegment) { - var segmentStart = middleSegment.start, - segmentEnd = middleSegment.end; + for (var i = 1; i < waypoints.length - 2; i++) { - var aligned = pointsAligned(segmentStart, segmentEnd); + snapped = snapSegment(gridSnapping, waypoints[i], waypoints[i + 1]); - if (horizontallyAligned(aligned)) { - - // snap horizontally - segmentStart.y = segmentEnd.y = gridSnapping.snapValue(segmentStart.y); - } - - if (verticallyAligned(aligned)) { - - // snap vertically - segmentStart.x = segmentEnd.x = gridSnapping.snapValue(segmentStart.x); - } - }); + waypoints[i] = snapped[0]; + waypoints[i + 1] = snapped[1]; + } return waypoints; }; - // helpers ////////// /** @@ -124,15 +117,28 @@ function verticallyAligned(aligned) { * * @returns {Array} */ -function getMiddleSegments(waypoints) { - var middleSegments = []; +function snapSegment(gridSnapping, segmentStart, segmentEnd) { - for (var i = 1; i < waypoints.length - 2; i++) { - middleSegments.push({ - start: waypoints[i], - end: waypoints[i + 1] - }); + var aligned = pointsAligned(segmentStart, segmentEnd); + + var snapped = {}; + + if (horizontallyAligned(aligned)) { + + // snap horizontally + snapped.y = gridSnapping.snapValue(segmentStart.y); } - return middleSegments; -} + 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 ]; +} \ No newline at end of file diff --git a/test/spec/features/grid-snapping/behavior/LayoutConnectionBehavior.bpmn b/test/spec/features/grid-snapping/behavior/LayoutConnectionBehavior.bpmn index 36a66039..077cd26c 100644 --- a/test/spec/features/grid-snapping/behavior/LayoutConnectionBehavior.bpmn +++ b/test/spec/features/grid-snapping/behavior/LayoutConnectionBehavior.bpmn @@ -1,11 +1,17 @@ - + - + + SequenceFlow_1 + + + SequenceFlow_1 + + @@ -24,6 +30,15 @@ + + + + + + + + + diff --git a/test/spec/features/grid-snapping/behavior/LayoutConnectionBehaviorSpec.js b/test/spec/features/grid-snapping/behavior/LayoutConnectionBehaviorSpec.js index bebd1606..b8d43892 100644 --- a/test/spec/features/grid-snapping/behavior/LayoutConnectionBehaviorSpec.js +++ b/test/spec/features/grid-snapping/behavior/LayoutConnectionBehaviorSpec.js @@ -76,7 +76,7 @@ describe('features/grid-snapping - layout connection', function() { })); - it('should NOT sap on reconnect start', inject(function(modeling) { + it('should NOT snap on reconnect start', inject(function(modeling) { // when modeling.moveElements([ task1 ], { x: 50, y: 50 }); @@ -87,7 +87,7 @@ describe('features/grid-snapping - layout connection', function() { })); - it('should NOT sap on reconnect end', inject(function(modeling) { + it('should NOT snap on reconnect end', inject(function(modeling) { // when modeling.moveElements([ task2 ], { x: -50, y: -50 }); @@ -97,6 +97,36 @@ describe('features/grid-snapping - layout connection', function() { expect(connection.waypoints[2]).to.eql({ x: 225, y: 190 }); })); + + it('should snap', inject(function(modeling, elementRegistry) { + + // given + var flow = elementRegistry.get('SequenceFlow_1'); + + // when + modeling.layoutConnection(flow); + + // then + expect(flow.waypoints[1]).to.eql({ x: 530, y: 242 }); + expect(flow.waypoints[2]).to.eql({ x: 530, y: 310 }); + })); + + + it('should UNDO snap', inject(function(modeling, commandStack, elementRegistry) { + + // given + var flow = elementRegistry.get('SequenceFlow_1'); + + modeling.layoutConnection(flow); + + // when + commandStack.undo(); + + // then + expect(flow.waypoints[1]).to.eql({ x: 526, y: 242 }); + expect(flow.waypoints[2]).to.eql({ x: 526, y: 310 }); + })); + }); }); \ No newline at end of file