Skip to content

Commit

Permalink
Ensure we do not return an invalid anchor point during edge routing
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-fleck-at committed Mar 4, 2024
1 parent ffba8f8 commit e4033ca
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 5 deletions.
32 changes: 32 additions & 0 deletions packages/client/src/features/routing/glsp-bezier-edge-router.ts
@@ -0,0 +1,32 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { BezierEdgeRouter, GConnectableElement, GParentElement, GRoutableElement, Point } from '@eclipse-glsp/sprotty';
import { injectable } from 'inversify';

@injectable()
export class GLSPBezierEdgeRouter extends BezierEdgeRouter {
override getTranslatedAnchor(
connectable: GConnectableElement,
refPoint: Point,
refContainer: GParentElement,
edge: GRoutableElement,
anchorCorrection?: number | undefined
): Point {
// users may define all kinds of anchors and anchor computers, we want to make sure we return a valid one in any case
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
return Point.isValid(anchor) ? anchor : refPoint;
}
}
Expand Up @@ -14,7 +14,15 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { ManhattanEdgeRouter, ResolvedHandleMove, GRoutableElement, almostEquals } from '@eclipse-glsp/sprotty';
import {
GConnectableElement,
GParentElement,
GRoutableElement,
ManhattanEdgeRouter,
Point,
ResolvedHandleMove,
almostEquals
} from '@eclipse-glsp/sprotty';

export class GLSPManhattanEdgeRouter extends ManhattanEdgeRouter {
protected override applyInnerHandleMoves(edge: GRoutableElement, moves: ResolvedHandleMove[]): void {
Expand Down Expand Up @@ -56,4 +64,16 @@ export class GLSPManhattanEdgeRouter extends ManhattanEdgeRouter {
}
});
}

override getTranslatedAnchor(
connectable: GConnectableElement,
refPoint: Point,
refContainer: GParentElement,
edge: GRoutableElement,
anchorCorrection?: number | undefined
): Point {
// users may define all kinds of anchors and anchor computers, we want to make sure we return a valid one in any case
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
return Point.isValid(anchor) ? anchor : refPoint;
}
}
32 changes: 32 additions & 0 deletions packages/client/src/features/routing/glsp-polyline-edge-router.ts
@@ -0,0 +1,32 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { GConnectableElement, GParentElement, GRoutableElement, Point, PolylineEdgeRouter } from '@eclipse-glsp/sprotty';
import { injectable } from 'inversify';

@injectable()
export class GLSPPolylineEdgeRouter extends PolylineEdgeRouter {
override getTranslatedAnchor(
connectable: GConnectableElement,
refPoint: Point,
refContainer: GParentElement,
edge: GRoutableElement,
anchorCorrection?: number | undefined
): Point {
// users may define all kinds of anchors and anchor computers, we want to make sure we return a valid one in any case
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
return Point.isValid(anchor) ? anchor : refPoint;
}
}
1 change: 1 addition & 0 deletions packages/client/src/features/routing/index.ts
Expand Up @@ -14,4 +14,5 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
export * from './glsp-manhattan-edge-router';
export * from './glsp-polyline-edge-router';
export * from './routing-module';
8 changes: 4 additions & 4 deletions packages/client/src/features/routing/routing-module.ts
Expand Up @@ -17,7 +17,6 @@ import {
AddRemoveBezierSegmentCommand,
AnchorComputerRegistry,
BezierDiamondAnchor,
BezierEdgeRouter,
BezierEllipseAnchor,
BezierRectangleAnchor,
DiamondAnchor,
Expand All @@ -27,13 +26,14 @@ import {
ManhattanDiamondAnchor,
ManhattanEllipticAnchor,
ManhattanRectangularAnchor,
PolylineEdgeRouter,
RectangleAnchor,
TYPES,
bindAsService,
configureCommand
} from '@eclipse-glsp/sprotty';
import { GLSPManhattanEdgeRouter } from './glsp-manhattan-edge-router';
import { GLSPPolylineEdgeRouter } from './glsp-polyline-edge-router';
import { GLSPBezierEdgeRouter } from './glsp-bezier-edge-router';

export const routingModule = new FeatureModule((bind, unbind, isBound, rebind) => {
const context = { bind, unbind, isBound, rebind };
Expand All @@ -45,12 +45,12 @@ export const routingModule = new FeatureModule((bind, unbind, isBound, rebind) =
bindAsService(context, TYPES.IAnchorComputer, ManhattanRectangularAnchor);
bindAsService(context, TYPES.IAnchorComputer, ManhattanDiamondAnchor);

bindAsService(context, TYPES.IEdgeRouter, PolylineEdgeRouter);
bindAsService(context, TYPES.IEdgeRouter, GLSPPolylineEdgeRouter);
bindAsService(context, TYPES.IAnchorComputer, EllipseAnchor);
bindAsService(context, TYPES.IAnchorComputer, RectangleAnchor);
bindAsService(context, TYPES.IAnchorComputer, DiamondAnchor);

bindAsService(context, TYPES.IEdgeRouter, BezierEdgeRouter);
bindAsService(context, TYPES.IEdgeRouter, GLSPBezierEdgeRouter);
bindAsService(context, TYPES.IAnchorComputer, BezierEllipseAnchor);
bindAsService(context, TYPES.IAnchorComputer, BezierRectangleAnchor);
bindAsService(context, TYPES.IAnchorComputer, BezierDiamondAnchor);
Expand Down
1 change: 1 addition & 0 deletions packages/protocol/src/index.ts
Expand Up @@ -18,4 +18,5 @@ export * from './client-server-protocol';
export * from './model';
export * from './re-exports';
export * from './sprotty-actions';
export * from './sprotty-geometry-point';
export * from './utils';
33 changes: 33 additions & 0 deletions packages/protocol/src/sprotty-geometry-point.ts
@@ -0,0 +1,33 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
/* eslint-disable @typescript-eslint/no-shadow */

import { Point } from 'sprotty-protocol/lib/utils/geometry';

declare module 'sprotty-protocol/lib/utils/geometry' {
namespace Point {
/**
* Type guard to check if a point is valid. For a point to be valid it needs to be defined and have valid x and y coordinates.
*
* @param point the point to be checked for validity
*/
function isValid(point?: Point): point is Point;
}
}

Point.isValid = (point?: Point): point is Point => point !== undefined && !isNaN(point.x) && !isNaN(point.y);

export { Point };

0 comments on commit e4033ca

Please sign in to comment.