/***************************************************************************** * Copyright (c) 2011 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: * * CEA LIST - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.locator; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Rectangle; /** * <pre> * This class provides convenience methods to manage Port location. * * The method are base on the Port and its graphical parent bounds (given as Rectangle), which can either be * based on the figure bounds or the view bounds. * </pre> */ public class PortPositionLocatorUtils { /** * Get the valid border location of the Port with the proposed location on * the parent. * @param parentFigureBounds the parent bounds. * @param proposedFigureBounds the proposed Port bounds. * @param borderItemOffset the overlapping size of the Port over its parent figure. * @return the allowed bounds for the Port (location relative to parent * TopLeft point). */ public static Rectangle getBorderLocation(Rectangle parentFigureBounds, Rectangle proposedFigureBounds, int borderItemOffset) { // Initialize port location with proposed location // and resolve the bounds of it graphical parent Rectangle realLocation = proposedFigureBounds.getCopy(); Rectangle parentRec = parentFigureBounds.getCopy(); // Calculate Max position around the graphical parent (1/2 size or the // port around // the graphical parent bounds. int xMin = - borderItemOffset; int xMax = - borderItemOffset + parentRec.width; int yMin = - borderItemOffset; int yMax = - borderItemOffset + parentRec.height; // Modify Port location if MAX X or Y are exceeded if(realLocation.x < xMin) { realLocation.x = xMin; } if(realLocation.x > xMax) { realLocation.x = xMax; } if(realLocation.y < yMin) { realLocation.y = yMin; } if(realLocation.y > yMax) { realLocation.y = yMax; } // Ensure the port is positioned on its parent borders and not in the // middle. // Modify position if needed. if((realLocation.y != yMin) && (realLocation.y != yMax)) { if((realLocation.x != xMin) && (realLocation.x != xMax)) { if(realLocation.x <= (xMin + (parentRec.width / 2))) { realLocation.x = xMin; } else { realLocation.x = xMax; } } } // Return constrained location return realLocation; } /** * Get the current side (on the parent) where the Port is located. * @param parentFigureBounds the parent bounds. * @param proposedFigureBounds the proposed Port bounds. * @param borderItemOffset the overlapping size of the Port over its parent figure. * @return the position of the port around its parent. This position can be * <ul> * <li>{@linkplain PositionConstants#NORTH}</li> * <li> {@linkplain PositionConstants#SOUTH}</li> * <li> {@linkplain PositionConstants#EAST}</li> * <li> {@linkplain PositionConstants#WEST}</li> * <li> {@linkplain PositionConstants#NORTH_EAST}</li> * <li> {@linkplain PositionConstants#NORTH_WEST}</li> * <li> {@linkplain PositionConstants#SOUTH_EAST}</li> * <li> {@linkplain PositionConstants#SOUTH_WEST}</li> * </ul> */ public static int getCurrentSideOfParent(Rectangle parentFigureBounds, Rectangle figureBounds, int borderItemOffset) { int position = PositionConstants.NONE; // we are not on EAST, not on WEST, but we are on the NORTH if((figureBounds.x != parentFigureBounds.width - borderItemOffset) && (figureBounds.x != -borderItemOffset) && (figureBounds.y == -borderItemOffset)) { position = PositionConstants.NORTH; // we are not on the EAST and not on the WEST, but we are on the // SOUTH } else if((figureBounds.x != parentFigureBounds.width - borderItemOffset) && (figureBounds.x != -borderItemOffset) && (figureBounds.y == parentFigureBounds.height - borderItemOffset)) { position = PositionConstants.SOUTH; // we are on the EAST, but we are not on the NORTH and not on the // SOUTH } else if((figureBounds.x == parentFigureBounds.width - borderItemOffset) && (figureBounds.y != -borderItemOffset) && (figureBounds.y != parentFigureBounds.height - borderItemOffset)) { position = PositionConstants.EAST; // we are on the WEST, but we are not on the on the NORTH and not on // the SOUTH } else if((figureBounds.x == -borderItemOffset) && (figureBounds.y != -borderItemOffset) && (figureBounds.y != parentFigureBounds.height - borderItemOffset)) { position = PositionConstants.WEST; // we are on the NORTH and on the EAST } else if((figureBounds.x == parentFigureBounds.width - borderItemOffset) && (figureBounds.y == -borderItemOffset)) { position = PositionConstants.NORTH_EAST; // we are on the NORTH and on the WEST } else if((figureBounds.x == -borderItemOffset) && (figureBounds.y == -borderItemOffset)) { position = PositionConstants.NORTH_WEST; // we are on the EAST and on the SOUTH } else if((figureBounds.x == parentFigureBounds.width - borderItemOffset) && (figureBounds.y == parentFigureBounds.height - borderItemOffset)) { position = PositionConstants.SOUTH_EAST; // we are on the WEST and on the SOUTH } else if((figureBounds.x == -borderItemOffset) && (figureBounds.y == parentFigureBounds.height - borderItemOffset)) { position = PositionConstants.SOUTH_WEST; } return position; } }