diff --git a/packages/project-editor/flow/editor/mouse-handler.tsx b/packages/project-editor/flow/editor/mouse-handler.tsx index abb6590c..6691ebc8 100644 --- a/packages/project-editor/flow/editor/mouse-handler.tsx +++ b/packages/project-editor/flow/editor/mouse-handler.tsx @@ -371,57 +371,98 @@ export class DragMouseHandler extends MouseHandlerWithSnapLines { }); } - getConnectionLineAlignedY(context: IFlowContext, event: IPointerEvent) { + getConnectionLineAlignedY( + context: IFlowContext, + event: IPointerEvent, + left: number, + top: number + ) { if (!event.ctrlKey) { return undefined; } + const dxMouseDrag = left - this.selectionBoundingRectAtDown.left; + const dyMouseDrag = top - this.selectionBoundingRectAtDown.top; + let foundConnectionLine; - let foundDx = 0; + let foundLength = 0; for (const connectionLine of (context.document.flow.object as Flow) .connectionLines) { + const sourceComponentIndex = this.selectedObjects.findIndex( + selectedObject => + selectedObject.object == connectionLine.sourceComponent + ); + + const targetComponentIndex = this.selectedObjects.findIndex( + selectedObject => + selectedObject.object == connectionLine.targetComponent + ); + if ( - this.selectedObjects.find( - selectedObject => - selectedObject.object == connectionLine.sourceComponent - ) + (sourceComponentIndex != -1 && targetComponentIndex != -1) || + (sourceComponentIndex == -1 && targetComponentIndex == -1) ) { - // skip connection lines where source is among selected objects continue; } - const selectedObject = this.selectedObjects.find( - selectedObject => - selectedObject.object == connectionLine.targetComponent - ); - if (selectedObject) { - const sourceOutputX = - connectionLine.sourceComponent.geometry.left + - connectionLine.sourceComponent.geometry.outputs[ - connectionLine.output - ].position.x; - - const targetInputX = - this.rects[ - this.selectedObjects.findIndex( - selectedObject => - selectedObject.object == - connectionLine.targetComponent - ) - ].left + - connectionLine.targetComponent.geometry.inputs[ - connectionLine.input - ].position.x; + let sourceOutputX; + let sourceOutputY; + let targetInputX; + let targetInputY; + + const outputPos = + connectionLine.sourceComponent.geometry.outputs[ + connectionLine.output + ].position; + + const inputPos = + connectionLine.targetComponent.geometry.inputs[ + connectionLine.input + ].position; + + if (sourceComponentIndex != -1) { + sourceOutputX = + this.objectPositionsAtDown[sourceComponentIndex].x + + dxMouseDrag + + outputPos.x; + + sourceOutputY = + this.objectPositionsAtDown[sourceComponentIndex].y + + dyMouseDrag + + outputPos.y; + + targetInputX = + connectionLine.targetComponent.geometry.left + inputPos.x; + + targetInputY = + connectionLine.targetComponent.geometry.top + inputPos.y; + } else { + sourceOutputX = + connectionLine.sourceComponent.geometry.left + outputPos.x; + + sourceOutputY = + connectionLine.sourceComponent.geometry.top + outputPos.y; + + targetInputX = + this.objectPositionsAtDown[targetComponentIndex].x + + dxMouseDrag + + inputPos.x; + + targetInputY = + this.objectPositionsAtDown[targetComponentIndex].y + + dyMouseDrag + + inputPos.y; + } + if (sourceOutputX < targetInputX) { const dx = targetInputX - sourceOutputX; + const dy = targetInputY - sourceOutputY; + const length = dx * dx + dy * dy; - if ( - dx > 0 && - (!foundConnectionLine || Math.abs(dx) < Math.abs(foundDx)) - ) { + if (!foundConnectionLine || length < foundLength) { foundConnectionLine = connectionLine; - foundDx = dx; + foundLength = length; } } } @@ -430,33 +471,60 @@ export class DragMouseHandler extends MouseHandlerWithSnapLines { return undefined; } - const topSource = foundConnectionLine.sourceComponent.top; + const sourceComponentIndex = this.selectedObjects.findIndex( + selectedObject => + selectedObject.object == foundConnectionLine.sourceComponent + ); - const topBounding = this.selectionBoundingRectAtDown.top; - const topTarget = - this.objectPositionsAtDown[ - this.selectedObjects.findIndex( - selectedObject => - selectedObject.object == - foundConnectionLine.targetComponent - ) - ].y; + if (sourceComponentIndex != -1) { + const topTarget = foundConnectionLine.targetComponent.top; + const topBounding = this.selectionBoundingRectAtDown.top; + const topSource = + this.objectPositionsAtDown[sourceComponentIndex].y; + + const sourceOutputY = + foundConnectionLine.sourceComponent.geometry.outputs[ + foundConnectionLine.output + ].position.y; + + const targetInputY = + foundConnectionLine.targetComponent.geometry.inputs[ + foundConnectionLine.input + ].position.y; + + return ( + topTarget + + (topBounding - topSource) - + (sourceOutputY - targetInputY) + ); + } else { + const targetComponentIndex = this.selectedObjects.findIndex( + selectedObject => + selectedObject.object == foundConnectionLine.targetComponent + ); - const sourceOutputY = - foundConnectionLine.sourceComponent.geometry.outputs[ - foundConnectionLine.output - ].position.y; + const topSource = foundConnectionLine.sourceComponent.top; - const targetInputY = - foundConnectionLine.targetComponent.geometry.inputs[ - foundConnectionLine.input - ].position.y; + const topBounding = this.selectionBoundingRectAtDown.top; + const topTarget = + this.objectPositionsAtDown[targetComponentIndex].y; - return ( - topSource + - (topBounding - topTarget) - - (targetInputY - sourceOutputY) - ); + const sourceOutputY = + foundConnectionLine.sourceComponent.geometry.outputs[ + foundConnectionLine.output + ].position.y; + + const targetInputY = + foundConnectionLine.targetComponent.geometry.inputs[ + foundConnectionLine.input + ].position.y; + + return ( + topSource + + (topBounding - topTarget) - + (targetInputY - sourceOutputY) + ); + } } down(context: IFlowContext, event: IPointerEvent) { @@ -500,7 +568,9 @@ export class DragMouseHandler extends MouseHandlerWithSnapLines { const connectionLineAlignedY = this.getConnectionLineAlignedY( context, - event + event, + left, + top ); if (connectionLineAlignedY) { top = connectionLineAlignedY;