package org.eclipse.papyrus.uml.diagram.sequence.apex.command; 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.PrecisionPoint; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeNodeEditPart; import org.eclipse.gmf.runtime.draw2d.ui.figures.BaseSlidableAnchor; import org.eclipse.gmf.runtime.notation.IdentityAnchor; import org.eclipse.papyrus.uml.diagram.common.commands.PreserveAnchorsPositionCommand; /** * @author Jiho * */ public class ApexPreserveAnchorsPositionCommand extends PreserveAnchorsPositionCommand { private Rectangle relativeBounds; public ApexPreserveAnchorsPositionCommand(ShapeNodeEditPart shapeEP, Dimension sizeDelta, int preserveAxis, IFigure figure, int resizeDirection, Object relative) { super(shapeEP, sizeDelta, preserveAxis, figure, resizeDirection); setRelative(relative); } /* (non-Javadoc) * @see org.eclipse.papyrus.uml.diagram.common.commands.PreserveAnchorsPositionCommand#getNewIdStr(org.eclipse.gmf.runtime.notation.IdentityAnchor) */ protected String getNewIdStr(IdentityAnchor anchor) { if (relativeBounds == null) { return super.getNewIdStr(anchor); } Dimension sizeDelta = getSizeDelta(); Rectangle figureBounds = getFigureBounds(); PrecisionPoint pp = BaseSlidableAnchor.parseTerminalString(anchor.getId()); int resizeDirection = getResizeDirection(); if(getPreserveAxis() == PRESERVE_Y || getPreserveAxis() == PRESERVE_XY) { int anchorYPos = (int)Math.round(figureBounds.height * pp.preciseY()); if ((PositionConstants.SOUTH & resizeDirection) != 0 && relativeBounds.bottom() < figureBounds.y + anchorYPos) { resizeDirection &= ~PositionConstants.SOUTH; resizeDirection ^= PositionConstants.NORTH; } else if ((PositionConstants.NORTH & resizeDirection) != 0 && relativeBounds.y > figureBounds.y + anchorYPos) { resizeDirection &= ~PositionConstants.SOUTH; resizeDirection ^= PositionConstants.NORTH; } pp.setPreciseY((double)anchorYPos / (figureBounds.height + sizeDelta.height)); // If the resize direction is NORTH, the location of the figure // move, but the anchor stay visually at the same location if((PositionConstants.NORTH & resizeDirection) != 0) { pp.setPreciseY(pp.preciseY() + ((double)sizeDelta.height / (figureBounds.height + sizeDelta.height))); } if(pp.preciseY() > 1.0) { pp.setPreciseY(1.0); } else if(pp.preciseY() < 0.0) { pp.setPreciseY(0.0); } } if(getPreserveAxis() == PRESERVE_X || getPreserveAxis() == PRESERVE_XY) { int anchorXPos = (int)Math.round(figureBounds.width * pp.preciseX()); if ((PositionConstants.EAST & resizeDirection) != 0 && relativeBounds.right() < figureBounds.x + anchorXPos) { resizeDirection &= ~PositionConstants.EAST; resizeDirection ^= PositionConstants.WEST; } else if ((PositionConstants.WEST & resizeDirection) != 0 && relativeBounds.x > figureBounds.x + anchorXPos) { resizeDirection &= ~PositionConstants.WEST; resizeDirection ^= PositionConstants.EAST; } pp.setPreciseX((double)anchorXPos / (figureBounds.width + sizeDelta.width)); // If the resize direction is WEST, the location of the figure move, // but the anchor stay visually at the same location if((PositionConstants.WEST & resizeDirection) != 0) { pp.setPreciseX(pp.preciseX() + ((double)sizeDelta.width / (figureBounds.width + sizeDelta.width))); } if(pp.preciseX() > 1.0) { pp.setPreciseX(1.0); } else if(pp.preciseX() < 0.0) { pp.setPreciseX(0.0); } } String idStr = (new BaseSlidableAnchor(null, pp)).getTerminal(); return idStr; } public void setRelative(Object relative) { if (relative instanceof Rectangle) { this.relativeBounds = ((Rectangle)relative).getCopy(); } else if (relative instanceof Point) { this.relativeBounds = new Rectangle((Point)relative, new Dimension()); } } }