/****************************************************************************** * Copyright (c) 2002, 2010 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation ****************************************************************************/ package org.eclipse.gmf.tooling.runtime.linklf.router; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.PrecisionRectangle; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.draw2d.geometry.Translatable; import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.RectilinearRouter; /** * Right now extending {@link RectilinearRouter} does not make sense, because * all of the methods of interest are private there. * <p/> * We, however, have extracted this class to at least formally note the copy * paste and distinguish it from copy-paste-with-modifications which are * intended to be placed into subclasses. * <p/> * All of the methods in this class are just the copy-pasted versions of their * private counterparts in {@link RectilinearRouter}, without any changes. * <p> * This class is intentionally made package local, and will be removed once the * respective patch for bug 331779 is merged. * * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=331779 * @since 3.3 */ class RectilinearRouter2 extends RectilinearRouter { /** * [GMFRT] make protected in {@link RectilinearRouter} * <p/> * Iterates through points of a polyline and does the following: if 3 points * lie on the same line the middle point is removed * * @param line * polyline's points */ @Deprecated public static boolean removeRedundantPoints2(PointList line) { int initialNumberOfPoints = line.size(); if (line.size() > 2) { PointList newLine = new PointList(line.size()); newLine.addPoint(line.removePoint(0)); while (line.size() >= 2) { Point p0 = newLine.getLastPoint(); Point p1 = line.getPoint(0); Point p2 = line.getPoint(1); if (p0.x == p1.x && p0.x == p2.x) { // Have two vertical segments in a row // get rid of the point between line.removePoint(0); } else if (p0.y == p1.y && p0.y == p2.y) { // Have two horizontal segments in a row // get rid of the point between line.removePoint(0); } else { newLine.addPoint(line.removePoint(0)); } } while (line.size() > 0) { newLine.addPoint(line.removePoint(0)); } line.removeAllPoints(); line.addAll(newLine); } return line.size() != initialNumberOfPoints; } /** * [GMFRT] make protected in {@link RectilinearRouter} * <p/> * Calculates geographic position of a point located outside the given * rectangle relative to the rectangle * * @param p * point outside of rectangle * @param r * the rectangle * @return geographic position of the point relative to the recatangle */ @Deprecated protected static int getOutisePointOffRectanglePosition2(Point p, Rectangle r) { int position = PositionConstants.NONE; if (r.x > p.x) { position |= PositionConstants.WEST; } else if (r.x + r.width < p.x) { position |= PositionConstants.EAST; } if (r.y > p.y) { position |= PositionConstants.NORTH; } else if (r.y + r.height < p.y) { position |= PositionConstants.SOUTH; } return position; } /** * [GMFRT] make protected in {@link RectilinearRouter} * <p/> * Determines whether the rectilinear line segment coming out of the shape * should be horizontal or vertical based on the anchor geographic position * relative to the shape * * @param anchorRelativeLocation * @return */ @Deprecated protected static int getOffShapeDirection2(int anchorRelativeLocation) { if (anchorRelativeLocation == PositionConstants.EAST || anchorRelativeLocation == PositionConstants.WEST) { return PositionConstants.HORIZONTAL; } else if (anchorRelativeLocation == PositionConstants.NORTH || anchorRelativeLocation == PositionConstants.SOUTH) { return PositionConstants.VERTICAL; } return PositionConstants.NONE; } /** * [GMFRT] make protected in {@link RectilinearRouter} * <p/> * Returns a translation dimension for the anchor point. Translation * dimension translates the anchor point off the shape. The off shape * direction is specified by the relative to the shape geographic position * of the anchor * * @param position * relative to the shape geographic position of the anchor * @param xFactorValue * translation value along x-axis * @param yFactorValue * translation value along y-axis * @return */ @Deprecated protected static Dimension getTranslationValue2(int position, int xFactorValue, int yFactorValue) { Dimension translationDimension = new Dimension(); if (position == PositionConstants.EAST) { translationDimension.width = xFactorValue; } else if (position == PositionConstants.SOUTH) { translationDimension.height = yFactorValue; } else if (position == PositionConstants.WEST) { translationDimension.width = -xFactorValue; } else if (position == PositionConstants.NORTH) { translationDimension.height = -yFactorValue; } return translationDimension; } @Override public void routeLine(Connection conn, int nestedRoutingDepth, PointList newLine) { super.routeLine(conn, nestedRoutingDepth, newLine); } /** * [GMFRT] make protected in {@link RectilinearRouter} * <p/> * Source bounding rectangle relative to connection figure coordinates * * @param conn * connection * @return <code>PrecisionRectangle</code> source bounds relative to * connection's coordinate system */ @Deprecated protected PrecisionRectangle sourceBoundsRelativeToConnection2( Connection conn) { PrecisionRectangle source = new PrecisionRectangle(conn .getSourceAnchor().getOwner().getBounds()); conn.getSourceAnchor().getOwner().translateToAbsolute(source); conn.translateToRelative(source); return source; } /** * [GMFRT] make protected in {@link RectilinearRouter} * <p/> * Target bounding rectangle relative to connection figure coordinates * * @param conn * connection * @return <code>PrecisionRectangle</code> target bounds relative to * connection's coordinate system */ @Deprecated protected PrecisionRectangle targetBoundsRelativeToConnection2( Connection conn) { PrecisionRectangle target = new PrecisionRectangle(conn .getTargetAnchor().getOwner().getBounds()); conn.getTargetAnchor().getOwner().translateToAbsolute(target); conn.translateToRelative(target); return target; } /** * [GMFRT] make protected in {@link RectilinearRouter} * <p/> * Determines the relative to rectangle geographic location of a point. * Example: If shape is closer to the the top edge of the rectangle location * would be north. Method used to determine which side of shape's bounding * rectangle is closer to connection's anchor point. All geometric * quantities must be in the same coordinate system. * * @param anchorPoint * location of the anchor point * @param rect * bounding rectangle of the shape * @return */ @Deprecated protected int getAnchorOffRectangleDirection2(Point anchorPoint, Rectangle rect) { int position = PositionConstants.NORTH; int criteriaValue = Math.abs(anchorPoint.y - rect.y); int tempCriteria = Math.abs(anchorPoint.y - rect.y - rect.height); if (tempCriteria < criteriaValue) { criteriaValue = tempCriteria; position = PositionConstants.SOUTH; } tempCriteria = Math.abs(anchorPoint.x - rect.x); if (tempCriteria < criteriaValue) { criteriaValue = tempCriteria; position = PositionConstants.WEST; } tempCriteria = Math.abs(anchorPoint.x - rect.x - rect.width); if (tempCriteria < criteriaValue) { criteriaValue = tempCriteria; position = PositionConstants.EAST; } return position; } protected static <T extends Translatable> T makeRelative(IFigure figure, T t) { figure.translateToRelative(t); return t; } protected static <T extends Translatable> T makeAbsolute(IFigure figure, T t) { figure.translateToAbsolute(t); return t; } }