diff --git a/js/fsm-document.js b/js/fsm-document.js index 086f57c..e7ea0c6 100644 --- a/js/fsm-document.js +++ b/js/fsm-document.js @@ -86,6 +86,14 @@ class FSMDocument { } } + getConnectionsOfState(state) { + return this.connections.filter(connection => connection instanceof Connection && (connection.stateA === state || connection.stateB === state)); + } + + getConnectionsBetweenStates(stateA,stateB) { + return this.getConnectionsOfState(stateA).filter(connection => connection.stateA === stateB || connection.stateB === stateB); + } + addChange(objectType, id, action, fields, oldValues, tryCombiningChanges) { if (this.changesIndex < this.changes.length - 1) { this.changes.splice(this.changesIndex + 1, this.changes.length - this.changesIndex - 1); diff --git a/js/main.js b/js/main.js index 8a37d7e..ac47a9e 100644 --- a/js/main.js +++ b/js/main.js @@ -334,13 +334,13 @@ canvas.addEventListener('mousemove', (event) => { if (movingObject) { if (selectedObject instanceof State) { - if(ctrlPressed || event.ctrlKey) { + if (ctrlPressed || event.ctrlKey) { const prevX = changedValues[0]; const prevY = changedValues[1]; selectedObject.setAnchorPoint(mouse.x, mouse.y); const deltaX = Math.abs(selectedObject.x - prevX); const deltaY = Math.abs(selectedObject.y - prevY); - if(deltaX > deltaY) { + if (deltaX > deltaY) { selectedObject.y = prevY; } else { selectedObject.x = prevX; @@ -360,11 +360,7 @@ document.addEventListener('mouseup', () => { movingObject = false; if (!!selectedObject && activeDocument !== null) { - if (selectedObject instanceof State) { - documents[activeDocument].addChange('state', selectedObject.id, 'edit', changedKeys, changedValues); - } else if (selectedObject instanceof Connection || selectedObject instanceof SelfConnection || selectedObject instanceof StartConnection) { - documents[activeDocument].addChange(selectedObject.constructor.name.toLowerCase(), selectedObject.id, 'edit', changedKeys, changedValues); - } + documents[activeDocument].addChange(selectedObject.constructor.name.toLowerCase(), selectedObject.id, 'edit', changedKeys, changedValues); } if (!!currentConnection && activeDocument !== null) { @@ -373,6 +369,34 @@ document.addEventListener('mouseup', () => { documents[activeDocument].connections.push(currentConnection); resetCaret(); + if (currentConnection instanceof Connection) { + const parallelPart = currentConnection.parallelPart; + const perpendicularPart = currentConnection.perpendicularPart; + const connections = documents[activeDocument].getConnectionsBetweenStates(currentConnection.stateA, currentConnection.stateB).filter(conn => { + return conn.parallelPart === parallelPart && conn.perpendicularPart === perpendicularPart; + }); + + if (connections.length > 1) { + let cx = (currentConnection.stateB.x + currentConnection.stateA.x) / 2; + let cy = (currentConnection.stateB.y + currentConnection.stateA.y) / 2; + const dx = currentConnection.stateB.x - currentConnection.stateA.x; + const dy = currentConnection.stateB.y - currentConnection.stateA.y; + const factorX = Math.sin(dx); + const factorY = Math.cos(dy); + const step = Math.sqrt(dx ** 2 + dy ** 2) * .25; + + cx -= (connections.length / 2 - .5) * step * factorX; + cy -= (connections.length / 2 - .5) * step * factorY; + + connections.forEach(connection => { + connection.setAnchorPoint(cx, cy); + + cx += step * factorX; + cy += step * factorY; + }); + } + } + documents[activeDocument].addChange(selectedObject.constructor.name.toLowerCase(), selectedObject.id, 'add', Object.keys(selectedObject), Object.values(selectedObject)) } currentConnection = null;