| /***************************************************************************** |
| * Copyright (c) 2019 CEA LIST, and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation |
| * |
| *****************************************************************************/ |
| |
| package org.eclipse.papyrus.interoperability.sysml16.sysml14.blackboxes.notation; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.PrecisionPoint; |
| import org.eclipse.draw2d.geometry.Straight; |
| import org.eclipse.gmf.runtime.notation.Bounds; |
| import org.eclipse.gmf.runtime.notation.Connector; |
| import org.eclipse.gmf.runtime.notation.Diagram; |
| import org.eclipse.gmf.runtime.notation.Edge; |
| import org.eclipse.gmf.runtime.notation.IdentityAnchor; |
| import org.eclipse.gmf.runtime.notation.LayoutConstraint; |
| import org.eclipse.gmf.runtime.notation.Node; |
| import org.eclipse.gmf.runtime.notation.NotationFactory; |
| import org.eclipse.gmf.runtime.notation.RelativeBendpoints; |
| import org.eclipse.gmf.runtime.notation.View; |
| import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint; |
| import org.eclipse.m2m.qvt.oml.blackbox.java.Operation; |
| import org.eclipse.m2m.qvt.oml.blackbox.java.Operation.Kind; |
| import org.eclipse.papyrus.infra.gmfdiag.tooling.runtime.linklf.AbsoluteBendpointsConvention; |
| |
| /** |
| * This allows to define the needed methods of UML for the transformations. |
| */ |
| public class NotationBlackboxHelper { |
| |
| /** |
| * This allows to remove an object from a collection. |
| * |
| * @param parentView |
| * The parent view. |
| * @param eObjectToRemove |
| * The object to remove from the collection. |
| */ |
| @Operation(kind = Kind.HELPER) |
| public void removeFromOwnerView(final View parentView, final View eObjectToRemove) { |
| if (null != parentView && eObjectToRemove instanceof View) { |
| if (parentView.getChildren().contains(eObjectToRemove)) { |
| parentView.removeChild(eObjectToRemove); |
| } else if (parentView instanceof Diagram && eObjectToRemove instanceof Edge && ((Diagram) parentView).getEdges().contains(eObjectToRemove)) { |
| ((Diagram) parentView).removeEdge((Edge) eObjectToRemove); |
| } |
| } |
| } |
| |
| /** |
| * This allows to create the bendpoint for the information flow. |
| * |
| * @param informationFlowEdge |
| * The information flow connector. |
| */ |
| @Operation(kind = Kind.HELPER) |
| public void createBendpointsForInformationFlow(final Connector informationFlowEdge) { |
| |
| // Create bendpoints with (0, 0) as source and target |
| final RelativeBendpoints bendpoints = NotationFactory.eINSTANCE.createRelativeBendpoints(); |
| final List<RelativeBendpoint> points = new ArrayList<>(2); |
| |
| final Point point = new Point(0, 0); |
| points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point)); |
| points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point)); |
| |
| bendpoints.setPoints(points); |
| informationFlowEdge.setBendpoints(bendpoints); |
| } |
| |
| /** |
| * This allows to create the bendpoint for the association. |
| * |
| * @param associationEdge |
| * The association connector. |
| */ |
| @Operation(kind = Kind.HELPER) |
| public void createBendpointsForAssociation(final Connector associationEdge) { |
| |
| // Get the source and target views |
| final View sourceView = associationEdge.getSource(); |
| final View targetView = associationEdge.getTarget(); |
| |
| final RelativeBendpoints bendpoints = NotationFactory.eINSTANCE.createRelativeBendpoints(); |
| final List<RelativeBendpoint> points = new ArrayList<>(2); |
| |
| // Check if the source and target views are nodes |
| if (sourceView instanceof Node && targetView instanceof Node) { |
| |
| // Initialization |
| int sourceX = 0; |
| int sourceY = 0; |
| int sourceWidth = 0; |
| int sourceHeight = 0; |
| |
| int targetX = 0; |
| int targetY = 0; |
| int targetWidth = 0; |
| int targetHeight = 0; |
| |
| // Get the source layout constraint values |
| LayoutConstraint sourceLayoutConstraint = ((Node) sourceView).getLayoutConstraint(); |
| if (sourceLayoutConstraint instanceof Bounds) { |
| sourceX = ((Bounds) sourceLayoutConstraint).getX(); |
| sourceY = ((Bounds) sourceLayoutConstraint).getY(); |
| sourceWidth = ((Bounds) sourceLayoutConstraint).getWidth(); |
| if (sourceWidth == 0) { |
| sourceWidth = 1; |
| } |
| sourceHeight = ((Bounds) sourceLayoutConstraint).getHeight(); |
| if (sourceHeight == 0) { |
| sourceHeight = 1; |
| } |
| } |
| |
| // Get the target layout constraint values |
| final LayoutConstraint targetLayoutConstraint = ((Node) targetView).getLayoutConstraint(); |
| if (targetLayoutConstraint instanceof Bounds) { |
| targetX = ((Bounds) targetLayoutConstraint).getX(); |
| targetY = ((Bounds) targetLayoutConstraint).getY(); |
| targetWidth = ((Bounds) targetLayoutConstraint).getWidth(); |
| if (targetWidth == 0) { |
| targetWidth = 1; |
| } |
| targetHeight = ((Bounds) targetLayoutConstraint).getHeight(); |
| if (targetHeight == 0) { |
| targetHeight = 1; |
| } |
| } |
| |
| if (sourceView == targetView) { |
| // If the source and the target are the same object, the bendpoints must be with the center of the shape |
| final Point point = new Point(sourceX + (sourceWidth / 2), sourceY + (sourceHeight / 2)); |
| points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point)); |
| points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point)); |
| } else { |
| |
| final Straight centerToCenterStraight = new Straight(new PrecisionPoint(sourceX + (sourceWidth / 2), sourceY + (sourceHeight / 2)), new PrecisionPoint(targetX + (targetWidth / 2), targetY + (targetHeight / 2))); |
| PrecisionPoint intersectPointForFirstRectangle = null; |
| PrecisionPoint intersectPointForSecondRectangle = null; |
| |
| // Calculate the point of the intersection for the first node |
| final Straight rightFirstRectangleStraight = new Straight(new PrecisionPoint(sourceX + sourceWidth, sourceY), new PrecisionPoint(sourceX + sourceWidth, sourceY + sourceHeight)); |
| if (rightFirstRectangleStraight.intersects(centerToCenterStraight)) { |
| intersectPointForFirstRectangle = rightFirstRectangleStraight.getIntersection(centerToCenterStraight).toPoint(); |
| } else { |
| final Straight bottomFirstRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY + sourceHeight), new PrecisionPoint(sourceX + sourceWidth, sourceY + sourceHeight)); |
| if (bottomFirstRectangleStraight.intersects(centerToCenterStraight)) { |
| intersectPointForFirstRectangle = bottomFirstRectangleStraight.getIntersection(centerToCenterStraight).toPoint(); |
| } else { |
| final Straight leftFirstRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY), new PrecisionPoint(sourceX, sourceY + sourceHeight)); |
| if (leftFirstRectangleStraight.intersects(centerToCenterStraight)) { |
| intersectPointForFirstRectangle = leftFirstRectangleStraight.getIntersection(centerToCenterStraight).toPoint(); |
| } else { |
| final Straight topFirstRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY), new PrecisionPoint(sourceX + sourceWidth, sourceY)); |
| if (topFirstRectangleStraight.intersects(centerToCenterStraight)) { |
| intersectPointForFirstRectangle = topFirstRectangleStraight.getIntersection(centerToCenterStraight).toPoint(); |
| } |
| } |
| } |
| } |
| |
| // Calculate the point of the intersection for the second node |
| final Straight rightSecondRectangleStraight = new Straight(new PrecisionPoint(sourceX + sourceWidth, sourceY), new PrecisionPoint(sourceX + sourceWidth, sourceY + sourceHeight)); |
| if (rightSecondRectangleStraight.intersects(centerToCenterStraight)) { |
| intersectPointForSecondRectangle = rightSecondRectangleStraight.getIntersection(centerToCenterStraight).toPoint(); |
| } else { |
| final Straight bottomSecondRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY + sourceHeight), new PrecisionPoint(sourceX + sourceWidth, sourceY + sourceHeight)); |
| if (bottomSecondRectangleStraight.intersects(centerToCenterStraight)) { |
| intersectPointForSecondRectangle = bottomSecondRectangleStraight.getIntersection(centerToCenterStraight).toPoint(); |
| } else { |
| final Straight leftSecondRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY), new PrecisionPoint(sourceX, sourceY + sourceHeight)); |
| if (leftSecondRectangleStraight.intersects(centerToCenterStraight)) { |
| intersectPointForSecondRectangle = leftSecondRectangleStraight.getIntersection(centerToCenterStraight).toPoint(); |
| } else { |
| final Straight topSecondRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY), new PrecisionPoint(sourceX + sourceWidth, sourceY)); |
| if (topSecondRectangleStraight.intersects(centerToCenterStraight)) { |
| intersectPointForSecondRectangle = topSecondRectangleStraight.getIntersection(centerToCenterStraight).toPoint(); |
| } |
| } |
| } |
| } |
| |
| if (null != intersectPointForFirstRectangle && null != intersectPointForSecondRectangle) { |
| // If the intersections are found, create the correct source and target points |
| final Point sourcePoint = new Point(sourceX + sourceWidth, targetY + (targetHeight / 2)); |
| final Point targetPoint = new Point(targetX, sourceY + (sourceHeight / 2)); |
| points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(sourcePoint)); |
| points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(targetPoint)); |
| } |
| } |
| } |
| |
| // If no points are created, create points to (0, 0) |
| if (points.isEmpty()) { |
| final Point point = new Point(0, 0); |
| points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point)); |
| points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point)); |
| } |
| |
| bendpoints.setPoints(points); |
| associationEdge.setBendpoints(bendpoints); |
| } |
| |
| /** |
| * This allows to create the bendpoint for the association Tether edge. |
| * |
| * @param associationTetherEdge |
| * The association Tether edge. |
| */ |
| @Operation(kind = Kind.HELPER) |
| public void createBendpointsForAssociationTetherEdge(final Connector associationTetherEdge) { |
| // Create bendpoints with (-50, -49) as source and target |
| final RelativeBendpoints bendpoints = NotationFactory.eINSTANCE.createRelativeBendpoints(); |
| final List<RelativeBendpoint> points = new ArrayList<>(2); |
| |
| final Point point = new Point(-50, -49); |
| points.add(new RelativeBendpoint(point.x, point.y, 0, 0)); |
| points.add(new RelativeBendpoint(point.x, point.y, 0, 0)); |
| |
| bendpoints.setPoints(points); |
| associationTetherEdge.setBendpoints(bendpoints); |
| |
| // Create the identityAnchor in the middle of the association |
| final IdentityAnchor identityAnchor = NotationFactory.eINSTANCE.createIdentityAnchor(); |
| identityAnchor.setId("(0.5,0.5)"); |
| associationTetherEdge.setSourceAnchor(identityAnchor); |
| } |
| } |