| /***************************************************************************** |
| * Copyright (c) 2015 CEA LIST. |
| * |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Sebastien Revol (CEA LIST) sebastien.revol@cea.fr - Initial API and implementation |
| * Vincent Lorenzo (CEa LIST) vincent.lorenzo@cea.fr - bugs 496176, 499237 |
| *****************************************************************************/ |
| |
| package org.eclipse.papyrus.interoperability.rpy.blackboxes; |
| |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg; |
| import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg.KeyPoint; |
| import org.eclipse.gmf.runtime.notation.Connector; |
| import org.eclipse.gmf.runtime.notation.IdentityAnchor; |
| import org.eclipse.gmf.runtime.notation.NotationFactory; |
| import org.eclipse.gmf.runtime.notation.RelativeBendpoints; |
| 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.interoperability.rpy.geometry.rpygeometry.Point; |
| import org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.RpyGeometryFactory; |
| import org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.RpyShape; |
| import org.eclipse.papyrus.interoperability.rpy.geometry.utils.RpyShapeOperations; |
| import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIAnchor; |
| import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIAssociationEnd; |
| import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIDiagramFrame; |
| import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIObjectLink; |
| import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.GraphElementsType; |
| |
| /** |
| * @author sr246418 |
| * |
| */ |
| |
| public class Rpy2PapyrusNotationBlackboxes { |
| |
| /** the size of the transform field */ |
| public static final int M_TRANSFORM_SIZE = 6; |
| |
| /** the index of intersting value in m transform */ |
| public static final int M_TRANSFORM_X_RATIO_INDEX = 0; |
| public static final int M_TRANSFORM_Y_RATIO_INDEX = 3; |
| public static final int M_TRANSFORM_X_POSITION_INDEX = 4; |
| public static final int M_TRANSFORM_Y_POSITION_INDEX = 5; |
| |
| /** the index of the x and y value for each points of the rectangle */ |
| public static final int M_POLYGON__RECTANGLE_NB_POINTS_INDEX = 0; |
| |
| /** the index of the x and y value for each points of the rectangle */ |
| public static final int M_POLYGON__RECTANGLE_TOP_LEFT_CORNER_X_INDEX = 1; |
| public static final int M_POLYGON__RECTANGLE_TOP_LEFT_CORNER_Y_INDEX = 2; |
| public static final int M_POLYGON__RECTANGLE_BOTTOM_LEFT_CORNER_X_INDEX = 3; |
| public static final int M_POLYGON__RECTANGLE_BOTTOM_LEFT_CORNER_Y_INDEX = 4; |
| public static final int M_POLYGON__RECTANGLE_BOTTOM_RIGHT_CORNER_X_INDEX = 5; |
| public static final int M_POLYGON__RECTANGLE_BOTTOM_RIGHT_CORNER__Y_INDEX = 6; |
| public static final int M_POLYGON__RECTANGLE_TOP_RIGHT_CORNER_X_INDEX = 7; |
| public static final int M_POLYGON__RECTANGLE_TOP_RIGHT_CORNER_Y_INDEX = 8; |
| |
| /** X and Y indexes for a point in an array */ |
| public static final int X_INDEX = 0; |
| public static final int Y_INDEX = 1; |
| |
| /** code returned when we are not able to get the wanted value */ |
| public static final int ERROR_CODE = Integer.MAX_VALUE; |
| |
| /** names of structural feature */ |
| public static final String M_TRANSFORM = "m_transform"; //$NON-NLS-1$ |
| public static final String M_POLYGON = "m_polygon"; //$NON-NLS-1$ |
| public static final String M_pPARENT = "m_pParent"; //$NON-NLS-1$ |
| |
| // TODO : try to link me to GMF value! |
| private static final int MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS = -643984; |
| |
| @Operation(kind = Kind.HELPER) |
| public boolean contains(final String aString, final String aPotentialSubString) { |
| if (null == aString || aPotentialSubString == null) { |
| return false; |
| } |
| return aString.contains(aPotentialSubString); |
| } |
| |
| // TODO add GMF source and target object to get their size and location ? |
| // 0 : source, 1 : target, 2, ... bendpoints if required |
| // TODO : we advice to manage anchor and bendpoints in the same method, to be able to make required adjutment |
| /** |
| * @param |
| * a |
| * Rpy association |
| * @param |
| * result |
| * @return a list, where the 2 first values are the source anchor and the target anchors. |
| * |
| * TODO update documentation when we will manage bendpoint too in the same method |
| * //TODO speak about the magic number |
| * //TODO try to set one anchor term to 0 or 1 each time |
| * //TODO : property m_line_style is not yet exploited : 0 is straight, 2 is rectilinear |
| * |
| */ |
| @Operation(kind = Kind.QUERY) |
| public void addAnchorsAndBendpoints(Object association, Connector result) { |
| if (!isARpyLink(association)) { |
| return; |
| } |
| // 1. we need to get all in absolute position |
| // find source and target anchor in absolute location |
| final List<String> rpySourceAnchorAsString = getM_SourcePort(association); |
| final List<String> rpyTargetAnchorAsString = getM_TargetPort(association); |
| final GraphElementsType sourceGraphicalObject = getM_pSource(association); |
| final GraphElementsType targetGraphicalObject = getM_pTarget(association); |
| final RpyShape sourceShape = RpyShapeOperations.createRpyShape(sourceGraphicalObject); |
| final RpyShape targetShape = RpyShapeOperations.createRpyShape(targetGraphicalObject); |
| |
| |
| final Point rpySourceAnchor = RpyGeometryFactory.eINSTANCE.createPoint(); |
| rpySourceAnchor.setX(Double.valueOf(rpySourceAnchorAsString.get(0))); |
| rpySourceAnchor.setY(Double.valueOf(rpySourceAnchorAsString.get(1))); |
| final Point rpySourceAnchorInAbsolute = sourceShape.getTransform().multiply(rpySourceAnchor); |
| |
| |
| final Point rpyTargetAnchor = RpyGeometryFactory.eINSTANCE.createPoint(); |
| rpyTargetAnchor.setX(Double.valueOf(rpyTargetAnchorAsString.get(0))); |
| rpyTargetAnchor.setY(Double.valueOf(rpyTargetAnchorAsString.get(1))); |
| final Point rpyTargetAnchorInAbsolute = targetShape.getTransform().multiply(rpyTargetAnchor); |
| |
| |
| // 2. determine bendpoints in absolute location |
| final List<String> rpyBendpointsAsString = getM_arrow(association); |
| final List<Point> rpyBendpointsInAbsolute = new ArrayList<Point>(); |
| if (rpyBendpointsAsString.size() > 0) { |
| for (int i = 1; i < Integer.valueOf(rpyBendpointsAsString.get(0)) * 2; i = i + 2) { |
| Point newPoint = RpyGeometryFactory.eINSTANCE.createPoint(); |
| newPoint.setX(Double.valueOf(rpyBendpointsAsString.get(i))); |
| newPoint.setY(Double.valueOf(rpyBendpointsAsString.get(i + 1))); |
| rpyBendpointsInAbsolute.add(newPoint); |
| } |
| } |
| |
| |
| // 3. here we get the source anchor, the target anchor and the bendpoints in absolute location |
| // it is here we could do some adjustment to fix round errors |
| // TODO : fix round errors!? |
| // /!\ fixing error could make problems for link linked to link ? |
| // bendpoint could be not in the good location, if we add/remove an offset to the compartemnt contents! |
| |
| // 4. we can now determine source anchor, target anchor and bendpoints |
| final Point sourceAnchorInRelative = RpyGeometryFactory.eINSTANCE.createPoint(); |
| sourceAnchorInRelative.setX(rpySourceAnchorInAbsolute.getX() - sourceShape.getAbsolutePosition().getX()); |
| sourceAnchorInRelative.setY(rpySourceAnchorInAbsolute.getY() - sourceShape.getAbsolutePosition().getY()); |
| |
| final Point targetAnchorInRelative = RpyGeometryFactory.eINSTANCE.createPoint(); |
| targetAnchorInRelative.setX(rpyTargetAnchorInAbsolute.getX() - targetShape.getAbsolutePosition().getX()); |
| targetAnchorInRelative.setY(rpyTargetAnchorInAbsolute.getY() - targetShape.getAbsolutePosition().getY()); |
| |
| final Point firstBendpoint = RpyGeometryFactory.eINSTANCE.createPoint(); |
| firstBendpoint.setX(rpySourceAnchorInAbsolute.getX()); |
| firstBendpoint.setY(rpySourceAnchorInAbsolute.getY()); |
| |
| final Point lastBendpoint = RpyGeometryFactory.eINSTANCE.createPoint(); |
| lastBendpoint.setX(rpyTargetAnchorInAbsolute.getX()); |
| lastBendpoint.setY(rpyTargetAnchorInAbsolute.getY()); |
| |
| |
| // we create the bendpoints list |
| List<RelativeBendpoint> gmfBendpoints = new ArrayList<RelativeBendpoint>(); |
| // source bendpoints |
| gmfBendpoints.add(new RelativeBendpoint(firstBendpoint.getIntX(), firstBendpoint.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS)); |
| |
| // intermediate bendpoints |
| for (Point current : rpyBendpointsInAbsolute) { |
| gmfBendpoints.add(new RelativeBendpoint(current.getIntX(), current.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS)); |
| } |
| |
| // last bendpoints |
| gmfBendpoints.add(new RelativeBendpoint(lastBendpoint.getIntX(), lastBendpoint.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS)); |
| |
| // we register the bendpoints into the connector |
| RelativeBendpoints bendpoints12 = NotationFactory.eINSTANCE.createRelativeBendpoints(); |
| bendpoints12.setPoints(gmfBendpoints); |
| result.setBendpoints(bendpoints12); |
| |
| IdentityAnchor sourceAnchor = NotationFactory.eINSTANCE.createIdentityAnchor(); |
| sourceAnchor.setId(getAnchorFromAbsolutePosition(sourceShape, sourceAnchorInRelative)); |
| |
| IdentityAnchor targetAnchor = NotationFactory.eINSTANCE.createIdentityAnchor(); |
| targetAnchor.setId(getAnchorFromAbsolutePosition(targetShape, targetAnchorInRelative)); |
| |
| result.setSourceAnchor(sourceAnchor); |
| result.setTargetAnchor(targetAnchor); |
| // |
| |
| // TODO : rewritte anchor code |
| // String sourceAnchor = getAnchorFromAbsolutePosition(sourceShape, rpySourceAnchorAsString); |
| // String targetAnchor = getAnchorFromAbsolutePosition(targetShape, rpyTargetAnchorAsString); |
| // List<String> returnedValues = new ArrayList<>(); |
| // returnedValues.add(sourceAnchor); |
| // returnedValues.add(targetAnchor); |
| // |
| // return returnedValues; |
| } |
| |
| /** |
| * |
| * @param anObject |
| * an object |
| * @return |
| * <code>true</code> if the object can be considered as a rpy link |
| */ |
| private boolean isARpyLink(final Object anObject) { |
| if (getM_pSource(anObject) != null && getM_pTarget(anObject) != null && getM_SourcePort(anObject).size() == 2 && getM_TargetPort(anObject).size() == 2) { |
| return true; |
| } |
| return false; |
| } |
| |
| private List<String> getM_arrow(Object anObject) { |
| if (anObject instanceof CGIObjectLink) { |
| return ((CGIObjectLink) anObject).getM_arrow(); |
| } else if (anObject instanceof CGIAnchor) { |
| return ((CGIAnchor) anObject).getM_arrow(); |
| } else if (anObject instanceof CGIAssociationEnd) { |
| return ((CGIAssociationEnd) anObject).getM_arrow(); |
| } |
| return Collections.emptyList(); |
| } |
| |
| private GraphElementsType getM_pSource(Object anObject) { |
| if (anObject instanceof CGIObjectLink) { |
| return (GraphElementsType) ((CGIObjectLink) anObject).getM_pSource(); |
| } else if (anObject instanceof CGIAnchor) { |
| return (GraphElementsType) ((CGIAnchor) anObject).getM_pSource(); |
| } else if (anObject instanceof CGIAssociationEnd) { |
| return (GraphElementsType) ((CGIAssociationEnd) anObject).getM_pSource(); |
| } |
| return null; |
| } |
| |
| private GraphElementsType getM_pTarget(Object anObject) { |
| if (anObject instanceof CGIObjectLink) { |
| return (GraphElementsType) ((CGIObjectLink) anObject).getM_pTarget(); |
| } else if (anObject instanceof CGIAnchor) { |
| return (GraphElementsType) ((CGIAnchor) anObject).getM_pTarget(); |
| } else if (anObject instanceof CGIAssociationEnd) { |
| return (GraphElementsType) ((CGIAssociationEnd) anObject).getM_pTarget(); |
| } |
| return null; |
| } |
| |
| private List<String> getM_SourcePort(Object anObject) { |
| if (anObject instanceof CGIObjectLink) { |
| return ((CGIObjectLink) anObject).getM_SourcePort(); |
| } else if (anObject instanceof CGIAnchor) { |
| return ((CGIAnchor) anObject).getM_SourcePort(); |
| } else if (anObject instanceof CGIAssociationEnd) { |
| return ((CGIAssociationEnd) anObject).getM_SourcePort(); |
| } |
| return Collections.emptyList(); |
| } |
| |
| private List<String> getM_TargetPort(Object anObject) { |
| if (anObject instanceof CGIObjectLink) { |
| return ((CGIObjectLink) anObject).getM_TargetPort(); |
| } else if (anObject instanceof CGIAnchor) { |
| return ((CGIAnchor) anObject).getM_TargetPort(); |
| } else if (anObject instanceof CGIAssociationEnd) { |
| return ((CGIAssociationEnd) anObject).getM_TargetPort(); |
| } |
| return Collections.emptyList(); |
| } |
| |
| |
| /** This method has been developed (not yet finished and not yet usable) to be able to create link on link */ |
| @Operation(kind = Kind.QUERY) |
| // TODO : finish me! |
| public void addAnchorsAndBendpoints_V2_FOR_LinkONLink(CGIAnchor association, Connector result) { |
| // 1. we need to get all in absolute position |
| // find source and target anchor in absolute location |
| final List<String> rpySourceAnchorAsString = association.getM_SourcePort(); |
| final List<String> rpyTargetAnchorAsString = association.getM_TargetPort(); |
| final GraphElementsType sourceGraphicalObject = (GraphElementsType) association.getM_pSource(); |
| final GraphElementsType targetGraphicalObject = (GraphElementsType) association.getM_pTarget(); |
| Point newTargetAnchorInAbsolute = null;// RpyGeometryFactory.eINSTANCE.createPoint(); |
| |
| // ------------------this part of the code has been done to be able to create anchor on a link (comment link linked to an other link!!!!----- |
| |
| if (targetGraphicalObject instanceof CGIObjectLink) {// we are connected on a link, so rpyTargetAnchorAsString could have a first value in % and the second one seem be 0 |
| CGIObjectLink link = ((CGIObjectLink) targetGraphicalObject); |
| Connector tmp = NotationFactory.eINSTANCE.createConnector(); |
| addAnchorsAndBendpoints(link, tmp); |
| // 1. calculate the full length of the link: |
| final RelativeBendpoints bendpoints = (RelativeBendpoints) tmp.getBendpoints(); |
| double length = 0; |
| List<LineSeg> linesSegs = new ArrayList<LineSeg>(); |
| // Iterator<RelativeBendpoint> iter = bendpoints.getPoints().iterator(); |
| List<Double> cumulatedLength = new ArrayList<>(); |
| for (int i = 1; i < bendpoints.getPoints().size(); i++) { |
| RelativeBendpoint pt1 = (RelativeBendpoint) bendpoints.getPoints().get(i - 1); |
| RelativeBendpoint pt2 = (RelativeBendpoint) bendpoints.getPoints().get(i); |
| linesSegs.add(new LineSeg(new org.eclipse.draw2d.geometry.Point(pt1.getSourceX(), pt1.getSourceY()), new org.eclipse.draw2d.geometry.Point(pt2.getSourceX(), pt2.getSourceY()))); |
| } |
| |
| |
| for (LineSeg lineSeg : linesSegs) { |
| length += lineSeg.length(); |
| cumulatedLength.add(Double.valueOf(length)); |
| } |
| |
| double percentage = Double.valueOf(rpyTargetAnchorAsString.get(0)); |
| double wantedLength = length * percentage / 100.00; |
| |
| int wantedLineSeg = -1; |
| int iter = 0; |
| while (wantedLineSeg == -1 && iter < cumulatedLength.size()) { |
| if (cumulatedLength.get(iter) > wantedLength) { |
| // i is the index of the lineseg on which the good length is obtained |
| wantedLineSeg = iter; |
| } |
| } |
| |
| double needToCrossOnThisLineSeg = -1; |
| if (iter == 0) { |
| needToCrossOnThisLineSeg = wantedLength; |
| } else { |
| needToCrossOnThisLineSeg = wantedLength - cumulatedLength.get(wantedLineSeg - 1); |
| } |
| LineSeg w = linesSegs.get(iter); |
| double percentage12 = 100 * needToCrossOnThisLineSeg / linesSegs.get(iter).length(); |
| double xOffset = ((double) w.getTerminus().x - (double) w.getOrigin().x) * percentage12 / 100.0; |
| double yOffset = ((double) w.getTerminus().y - (double) w.getOrigin().y) * percentage12 / 100.0; |
| newTargetAnchorInAbsolute = RpyGeometryFactory.eINSTANCE.createPoint(); |
| newTargetAnchorInAbsolute.setX(w.getOrigin().x + xOffset); |
| newTargetAnchorInAbsolute.setY(w.getOrigin().y + yOffset); |
| |
| org.eclipse.draw2d.geometry.Point ptResult = new org.eclipse.draw2d.geometry.Point(); |
| KeyPoint toto = KeyPoint.ORIGIN; |
| w.pointOn((long) needToCrossOnThisLineSeg, toto, ptResult); |
| |
| // double tmpLength = 0; |
| // Iterator<LineSeg> iter = linesSegs.iterator(); |
| // |
| // while (tmpLength < wantedLength && iter.hasNext()) { |
| // LineSeg current = iter.next(); |
| // tmpLength += current.length(); |
| // } |
| // |
| // int segIndex = -1; |
| // for (int i = 0; i < cumulatedLength.size(); i++) { |
| // if (wantedLength > cumulatedLength.get(i)) { |
| // segIndex = i - 1; |
| // } |
| // } |
| // double requiredLengthOnThisSeg = wantedLength - cumulatedLength.get(segIndex); |
| int j = 0; |
| j++; |
| Connector c = null; |
| // c. |
| } |
| |
| final RpyShape sourceShape = RpyShapeOperations.createRpyShape(sourceGraphicalObject); |
| final RpyShape targetShape = RpyShapeOperations.createRpyShape(targetGraphicalObject); |
| |
| |
| final Point rpySourceAnchor = RpyGeometryFactory.eINSTANCE.createPoint(); |
| rpySourceAnchor.setX(Double.valueOf(rpySourceAnchorAsString.get(0))); |
| rpySourceAnchor.setY(Double.valueOf(rpySourceAnchorAsString.get(1))); |
| final Point rpySourceAnchorInAbsolute = sourceShape.getTransform().multiply(rpySourceAnchor); |
| |
| |
| final Point rpyTargetAnchor = RpyGeometryFactory.eINSTANCE.createPoint(); |
| rpyTargetAnchor.setX(Double.valueOf(rpyTargetAnchorAsString.get(0))); |
| rpyTargetAnchor.setY(Double.valueOf(rpyTargetAnchorAsString.get(1))); |
| final Point rpyTargetAnchorInAbsolute; |
| if (newTargetAnchorInAbsolute == null) { |
| rpyTargetAnchorInAbsolute = targetShape.getTransform().multiply(rpyTargetAnchor); |
| } else { |
| rpyTargetAnchorInAbsolute = newTargetAnchorInAbsolute; |
| } |
| |
| // 2. determine bendpoints in absolute location |
| final List<String> rpyBendpointsAsString = association.getM_arrow(); |
| final List<Point> rpyBendpointsInAbsolute = new ArrayList<Point>(); |
| if (rpyBendpointsAsString.size() > 0) { |
| for (int i = 1; i < Integer.valueOf(rpyBendpointsAsString.get(0)) * 2; i = i + 2) { |
| Point newPoint = RpyGeometryFactory.eINSTANCE.createPoint(); |
| newPoint.setX(Double.valueOf(rpyBendpointsAsString.get(i))); |
| newPoint.setY(Double.valueOf(rpyBendpointsAsString.get(i + 1))); |
| rpyBendpointsInAbsolute.add(newPoint); |
| } |
| } |
| |
| |
| // 3. here we get the source anchor, the target anchor and the bendpoints in absolute location |
| // it is here we could do some adjustment to fix round errors |
| // TODO : fix round errors!? |
| // /!\ fixing error could make problems for link linked to link ? |
| // bendpoint could be not in the good location, if we add/remove an offset to the compartemnt contents! |
| |
| |
| |
| // 4. we can now determine source anchor, target anchor and bendpoints |
| final Point sourceAnchorInRelative = RpyGeometryFactory.eINSTANCE.createPoint(); |
| sourceAnchorInRelative.setX(rpySourceAnchorInAbsolute.getX() - sourceShape.getAbsolutePosition().getX()); |
| sourceAnchorInRelative.setY(rpySourceAnchorInAbsolute.getY() - sourceShape.getAbsolutePosition().getY()); |
| |
| final Point targetAnchorInRelative = RpyGeometryFactory.eINSTANCE.createPoint(); |
| targetAnchorInRelative.setX(rpyTargetAnchorInAbsolute.getX() - targetShape.getAbsolutePosition().getX()); |
| targetAnchorInRelative.setY(rpyTargetAnchorInAbsolute.getY() - targetShape.getAbsolutePosition().getY()); |
| |
| final Point firstBendpoint = RpyGeometryFactory.eINSTANCE.createPoint(); |
| firstBendpoint.setX(rpySourceAnchorInAbsolute.getX()); |
| firstBendpoint.setY(rpySourceAnchorInAbsolute.getY()); |
| |
| final Point lastBendpoint = RpyGeometryFactory.eINSTANCE.createPoint(); |
| lastBendpoint.setX(rpyTargetAnchorInAbsolute.getX()); |
| lastBendpoint.setY(rpyTargetAnchorInAbsolute.getY()); |
| |
| |
| // we create the bendpoints list |
| List<RelativeBendpoint> gmfBendpoints = new ArrayList<RelativeBendpoint>(); |
| // source bendpoints |
| gmfBendpoints.add(new RelativeBendpoint(firstBendpoint.getIntX(), firstBendpoint.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS)); |
| |
| // intermediate bendpoints |
| for (Point current : rpyBendpointsInAbsolute) { |
| gmfBendpoints.add(new RelativeBendpoint(current.getIntX(), current.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS)); |
| } |
| |
| // last bendpoints |
| gmfBendpoints.add(new RelativeBendpoint(lastBendpoint.getIntX(), lastBendpoint.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS)); |
| |
| // we register the bendpoints into the connector |
| RelativeBendpoints bendpoints12 = NotationFactory.eINSTANCE.createRelativeBendpoints(); |
| bendpoints12.setPoints(gmfBendpoints); |
| result.setBendpoints(bendpoints12); |
| |
| IdentityAnchor sourceAnchor = NotationFactory.eINSTANCE.createIdentityAnchor(); |
| sourceAnchor.setId(getAnchorFromAbsolutePosition(sourceShape, sourceAnchorInRelative)); |
| |
| IdentityAnchor targetAnchor = NotationFactory.eINSTANCE.createIdentityAnchor(); |
| targetAnchor.setId(getAnchorFromAbsolutePosition(targetShape, targetAnchorInRelative)); |
| |
| result.setSourceAnchor(sourceAnchor); |
| result.setTargetAnchor(targetAnchor); |
| } |
| |
| protected String getAnchorFromAbsolutePosition(RpyShape shape, Point point) { |
| float newxRatio = 0;// = new Float(xPort) / new Float(shape.getWidth()); |
| float newyRatio = 0;// = new Float(yPort) / new Float(shape.getHeight()); |
| newxRatio = new Float(point.getX()) / new Float(shape.getWidth()); |
| newyRatio = new Float(point.getY()) / new Float(shape.getHeight()); |
| if (newxRatio > 1) { |
| newxRatio = 1; |
| } |
| if (newyRatio > 1) { |
| newyRatio = 1; |
| } |
| |
| String id = "(" + newxRatio + "," + newyRatio + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| return id; |
| } |
| |
| @Deprecated |
| protected String getAnchorFromAbsolutePosition(RpyShape shape, List<String> port) { |
| Point point = RpyGeometryFactory.eINSTANCE.createPoint(); |
| point.setX(Double.valueOf(port.get(0))); |
| point.setY(Double.valueOf(port.get(1))); |
| Point res = shape.getTransform().multiply(point); |
| res.setX(res.getX() - shape.getAbsolutePosition().getX()); |
| res.setY(res.getY() - shape.getAbsolutePosition().getY()); |
| |
| double[] topLeft = new double[] { shape.getParentRelativePosition().getX(), shape.getParentRelativePosition().getY() }; |
| double[] topRight = new double[] { shape.getParentRelativePosition().getX() + (double) shape.getWidth(), shape.getParentRelativePosition().getY() }; |
| double[] bottomLeft = new double[] { shape.getParentRelativePosition().getX(), shape.getParentRelativePosition().getY() + (double) shape.getHeight() }; |
| |
| double xPort = Double.parseDouble(port.get(0)); |
| if (xPort < topLeft[X_INDEX]) { |
| xPort = topLeft[X_INDEX]; |
| } |
| if (xPort > topRight[X_INDEX]) { |
| xPort = topRight[X_INDEX]; |
| } |
| |
| double yPort = Double.parseDouble(port.get(1)); |
| if (yPort < topLeft[Y_INDEX]) { |
| yPort = topLeft[Y_INDEX]; |
| } |
| if (yPort > bottomLeft[Y_INDEX]) { |
| yPort = bottomLeft[Y_INDEX]; |
| } |
| |
| float newxRatio = new Float(xPort) / new Float(shape.getWidth()); |
| float newyRatio = new Float(yPort) / new Float(shape.getHeight()); |
| newxRatio = new Float(res.getX()) / new Float(shape.getWidth()); |
| newyRatio = new Float(res.getY()) / new Float(shape.getHeight()); |
| if (newxRatio > 1) { |
| newxRatio = 1; |
| } |
| if (newyRatio > 1) { |
| newyRatio = 1; |
| } |
| |
| String id = "(" + newxRatio + "," + newyRatio + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| return id; |
| } |
| |
| @Operation(kind = Kind.HELPER) |
| public String getAnchorId(List<String> polygon, List<String> transform, List<String> port) { |
| |
| // int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) }; |
| |
| int[] topLeft = new int[] { Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_TOP_LEFT_CORNER_X_INDEX)), Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_TOP_LEFT_CORNER_Y_INDEX)) }; |
| int[] topRight = new int[] { Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_TOP_RIGHT_CORNER_X_INDEX)), Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_TOP_RIGHT_CORNER_Y_INDEX)) }; |
| int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_BOTTOM_LEFT_CORNER_X_INDEX)), Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_BOTTOM_LEFT_CORNER_Y_INDEX)) }; |
| |
| int xPort = Integer.parseInt(port.get(0)); |
| if (xPort < topLeft[X_INDEX]) { |
| xPort = topLeft[X_INDEX]; |
| } |
| if (xPort > topRight[X_INDEX]) { |
| xPort = topRight[X_INDEX]; |
| } |
| |
| int yPort = Integer.parseInt(port.get(1)); |
| if (yPort < topLeft[Y_INDEX]) { |
| yPort = topLeft[Y_INDEX]; |
| } |
| if (yPort > bottomLeft[Y_INDEX]) { |
| yPort = bottomLeft[Y_INDEX]; |
| } |
| |
| float newxRatio = new Float(xPort) / new Float(getRelativeWidth(topRight[0], topLeft[0])); |
| float newyRatio = new Float(yPort) / new Float(getRelativeHeight(bottomLeft[1], topLeft[1])); |
| |
| if (newxRatio > 1) { |
| newxRatio = 1; |
| } |
| if (newyRatio > 1) { |
| newyRatio = 1; |
| } |
| |
| String id = "(" + newxRatio + "," + newyRatio + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| |
| return id; |
| |
| } |
| |
| public static int getRelativeHeight(int a, int b) { |
| return (a - b); |
| } |
| |
| public static int getRelativeWidth(int a, int b) { |
| return (a - b); |
| } |
| |
| /** |
| * |
| * @param polygon |
| * @param transform |
| * @return |
| * |
| * @deprecated since 0.7 |
| */ |
| @Deprecated |
| @Operation(kind = Kind.HELPER) |
| public int getStateHeight(List<String> polygon, List<String> transform) { |
| |
| // State Partition (top left, top right, bottom right, bottom left) not |
| // same for classes |
| int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) }; |
| int[] topRight = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) }; |
| int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) }; |
| int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) }; |
| float xRatio = Float.parseFloat(transform.get(0)); |
| float yRatio = Float.parseFloat(transform.get(3)); |
| return Math.round(yRatio * (bottomLeft[1] - topLeft[1])); |
| } |
| |
| /** |
| * |
| * @param polygon |
| * @param transform |
| * @return |
| * |
| * @deprecated since 0.7 |
| */ |
| @Deprecated |
| @Operation(kind = Kind.HELPER) |
| public int getStateWidth(List<String> polygon, List<String> transform) { |
| int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) }; |
| int[] topRight = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) }; |
| int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) }; |
| int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) }; |
| float xRatio = Float.parseFloat(transform.get(0)); |
| float yRatio = Float.parseFloat(transform.get(3)); |
| return Math.round(xRatio * (topRight[0] - topLeft[0])); |
| } |
| |
| /** |
| * |
| * @param polygon |
| * @param transform |
| * @return |
| * |
| * @deprecated since 0.7 |
| */ |
| @Deprecated |
| @Operation(kind = Kind.HELPER) |
| public int getClassHeight(List<String> polygon, List<String> transform) { |
| |
| // State Partition (top left, top right, bottom right, bottom left) not |
| // same for classes |
| int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) }; |
| int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) }; |
| int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) }; |
| int[] topRight = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) }; |
| float xRatio = Float.parseFloat(transform.get(0)); |
| float yRatio = Float.parseFloat(transform.get(3)); |
| return Math.round(yRatio * (bottomLeft[1] - topLeft[1])); |
| } |
| |
| @Operation(kind = Kind.HELPER) |
| public int getClassWidth(List<String> polygon, List<String> transform) { |
| int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) }; |
| int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) }; |
| int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) }; |
| int[] topRight = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) }; |
| float xRatio = Float.parseFloat(transform.get(0)); |
| float yRatio = Float.parseFloat(transform.get(3)); |
| return Math.round(xRatio * (topRight[0] - topLeft[0])); |
| } |
| |
| |
| /** |
| * |
| * @param m_polygon |
| * the field polygon |
| * @param m_transform |
| * the field transform |
| * @return the width of the object |
| * @deprecated since 0.7. use others method instead |
| */ |
| @Deprecated |
| public int getWidth(List<String> m_polygon, List<String> m_transform) { |
| int[] topLeft = new int[] { Integer.parseInt(m_polygon.get(1)), Integer.parseInt(m_polygon.get(2)) }; |
| // int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) }; |
| // int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) }; |
| int[] topRight = new int[] { Integer.parseInt(m_polygon.get(7)), Integer.parseInt(m_polygon.get(8)) }; |
| float xRatio = Float.parseFloat(m_transform.get(0)); |
| // float yRatio = Float.parseFloat(transform.get(3)); |
| return Math.round(xRatio * (topRight[0] - topLeft[0])); |
| } |
| |
| /** |
| * |
| * @param polygon |
| * the field polygon |
| * @param transform |
| * the field transform |
| * @return the height of the object |
| * @deprecated since 0.7. use others method instead |
| */ |
| @Deprecated |
| public int getHeight(List<String> polygon, List<String> transform) { |
| int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) }; |
| int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) }; |
| // int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) }; |
| // int[] topRight = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) }; |
| // float xRatio = Float.parseFloat(transform.get(0)); |
| float yRatio = Float.parseFloat(transform.get(3)); |
| return Math.round(yRatio * (bottomLeft[1] - topLeft[1])); |
| } |
| |
| |
| /** |
| * |
| * @param element |
| * a graphical element |
| * @return |
| * the X ratio to apply on the object to get its width |
| */ |
| @Operation(kind = Kind.HELPER) |
| public float get_X_Ratio(GraphElementsType element) { |
| float result = 1; |
| final List<String> mTransform = getTransformList(element); |
| if (null != mTransform && mTransform.size() == M_TRANSFORM_SIZE) { |
| result = Float.parseFloat(mTransform.get(M_TRANSFORM_X_RATIO_INDEX)); |
| final GraphElementsType parent = getParent(element); |
| if (!(parent instanceof CGIDiagramFrame)) { |
| result = result * get_X_Ratio(parent); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * |
| * @param element |
| * a graphical element |
| * @return |
| * the X ratio to apply on the object to get its height |
| */ |
| @Operation(kind = Kind.HELPER) |
| public float get_Y_Ratio(final GraphElementsType element) { |
| float result = 1; |
| final List<String> mTransform = getTransformList(element); |
| if (null != mTransform && mTransform.size() == M_TRANSFORM_SIZE) { |
| result = Float.parseFloat(mTransform.get(M_TRANSFORM_Y_RATIO_INDEX)); |
| final GraphElementsType parent = getParent(element); |
| if (!(parent instanceof CGIDiagramFrame)) { |
| result = result * get_Y_Ratio(parent); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * |
| * @param element |
| * a graphical element |
| * @return |
| * the value of the m_pParent field if it exits for the given object or <code>null</code> in other case |
| */ |
| private final GraphElementsType getParent(final GraphElementsType element) { |
| final EStructuralFeature paretnFeature = element.eClass().getEStructuralFeature("m_pParent"); //$NON-NLS-1$ |
| if (null != paretnFeature) { |
| Object value = element.eGet(paretnFeature); |
| if (value instanceof GraphElementsType) { |
| return (GraphElementsType) value; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * |
| * @param element |
| * a graphical element |
| * @return |
| * the value of the m_Transform field if it exits for the given object or <code>null</code> in other case |
| */ |
| @SuppressWarnings("unchecked") |
| protected final List<String> getTransformList(final GraphElementsType element) { |
| List<String> returnedValues = new ArrayList<String>(); |
| final EStructuralFeature mTransformFeature = element.eClass().getEStructuralFeature(M_TRANSFORM); |
| if (null != mTransformFeature) { |
| final Object mTransformValue = element.eGet(mTransformFeature); |
| if (mTransformValue instanceof List<?>) { |
| returnedValues.addAll((List<String>) mTransformValue); |
| } |
| } |
| |
| // We can consider number in e as 0; |
| List<String> toReturn = new ArrayList<String>(); |
| if (returnedValues.size() != 6) { |
| for (int i = 0; i < returnedValues.size(); i++) { |
| String tmp = returnedValues.get(i); |
| if (tmp.startsWith("e")) { |
| continue; |
| } |
| if (!tmp.startsWith("e") && returnedValues.size() > (i + 1)) { |
| String tmp2 = returnedValues.get(i + 1); |
| if (tmp2.startsWith("e")) { |
| tmp += tmp2; |
| } |
| } |
| toReturn.add(tmp); |
| } |
| returnedValues = toReturn; |
| } |
| for (int i = 0; i < returnedValues.size(); i++) { |
| String tmp = returnedValues.get(i); |
| if (tmp.contains("e-")) { |
| returnedValues.set(i, "0"); |
| } |
| } |
| |
| return returnedValues; |
| } |
| |
| /** |
| * |
| * @param element |
| * a graphical element |
| * @return |
| * the value of the m_Polygon field if it exits for the given object or <code>null</code> in other case |
| */ |
| @SuppressWarnings("unchecked") |
| protected final List<String> getPolygonList(GraphElementsType element) { |
| final EStructuralFeature mPolygonFeature = element.eClass().getEStructuralFeature(M_POLYGON); |
| if (null != mPolygonFeature) { |
| final Object mPolygonValue = element.eGet(mPolygonFeature); |
| if (mPolygonValue instanceof List<?>) { |
| return (List<String>) mPolygonValue; |
| } |
| } |
| final EStructuralFeature mPositionlygonFeature = element.eClass().getEStructuralFeature("m_position"); |
| if (null != mPolygonFeature) { |
| final Object mPolygonValue = element.eGet(mPolygonFeature); |
| if (mPolygonValue instanceof List<?>) { |
| return (List<String>) mPolygonValue; |
| } |
| } |
| return null; |
| } |
| |
| @Operation(kind = Kind.HELPER) |
| public int getRectangleWidth(final GraphElementsType element) { |
| RpyShape shape = RpyShapeOperations.createRpyShape(element); |
| return shape.getWidth(); |
| } |
| |
| @Operation(kind = Kind.HELPER) |
| public int getRectangleHeight(final GraphElementsType element) { |
| RpyShape shape = RpyShapeOperations.createRpyShape(element); |
| return shape.getHeight(); |
| } |
| |
| @Operation(kind = Kind.HELPER) |
| public int getX(final GraphElementsType element) { |
| RpyShape shape = RpyShapeOperations.createRpyShape(element); |
| return shape.getParentRelativePosition().getIntX(); |
| } |
| |
| |
| @Operation(kind = Kind.HELPER) |
| public int getY(final GraphElementsType element) { |
| RpyShape shape = RpyShapeOperations.createRpyShape(element); |
| return shape.getParentRelativePosition().getIntY(); |
| } |
| |
| // TODO : move me into an upper plugin |
| /** |
| * |
| * @param aString |
| * a string |
| * @return the parsed result of the string or {@link Integer#MAX_VALUE} if a problem occurred |
| */ |
| protected final int stringToInteger(final String aString) { |
| int result = Integer.MAX_VALUE; |
| if (aString.contains(".")) { //$NON-NLS-1$ |
| result = Float.valueOf(Float.parseFloat(aString)).intValue(); |
| } else { |
| result = Integer.parseInt(aString); |
| } |
| return result; |
| } |
| } |