/***************************************************************************** * Copyright (c) 2010 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: * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.layout; import java.util.List; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PrecisionRectangle; import org.eclipse.gef.EditPart; import org.eclipse.gef.tools.ToolUtilities; /** * * A special tree for the alignment action * */ public class AlignmentTree extends EditPartTree { /** * this UDI can be used to serialize this class */ private static final long serialVersionUID = 3095221342551975246L; /** * * Constructor. * * @param editpart * the editpart represented by this tree * @param isSelected * Indicates if the represented editpart is selected or not * */ public AlignmentTree(Object editpart, boolean isSelected) { super(editpart, isSelected); } /** * * Constructor. * * @param editparts * the editparts used to build the tree */ public AlignmentTree(List<EditPart> editparts) { super(editparts); } /** * The new position for this element */ private PrecisionRectangle newPosition = null; /** * Gets the new alignment position for the editpart. * * @return the new alignment position for the editpart */ public PrecisionRectangle getNewPosition() { return newPosition; } /** * Returns the new bounds of the container * * @return <ul> * <li>{@link EditPartTree#diagramRect} if the container is the diagram</li> * <li>the bounds of the container after the shift</li> * </ul> */ public PrecisionRectangle getNewContainerBounds() { AlignmentTree treeParent = (AlignmentTree)this.getParent(); PrecisionRectangle newContainerBounds; if(treeParent.getEditPart() != null) { Point oldParentLocation = LayoutUtils.getAbsolutePosition(treeParent.getEditPart()).getLocation(); Point newParentLocation = treeParent.getNewPosition().getLocation(); // shift between the two positions Point shift = newParentLocation.getTranslated(oldParentLocation.getNegated()); // we want know the final position for the container PrecisionRectangle oldContainerBounds = LayoutUtils.getAbsolutePosition(this.getEditPart().getParent()); newContainerBounds = new PrecisionRectangle(oldContainerBounds); newContainerBounds.translate(shift); } else {// treeParent is the root of the tree EditPart containerEditPart = this.getEditPart().getParent(); newContainerBounds = LayoutUtils.getAbsolutePosition(containerEditPart); } return newContainerBounds; } /** * Returns the absolute position for the editpart in the new container * * @return the absolute position for the editpart in the new container. * That's to say the intermediate position, when the container has * moved, and the editpart hasn't moved */ public PrecisionRectangle getAbsolutePositionInTheNewContainerPosition() { PrecisionRectangle newPosition = new PrecisionRectangle(LayoutUtils.getAbsolutePosition(getEditPart())); PrecisionRectangle newContainerPosition = getNewContainerBounds(); PrecisionRectangle oldContainerPosition = LayoutUtils.getAbsolutePosition(getEditPart().getParent()); PrecisionRectangle distance = (PrecisionRectangle)newContainerPosition.translate(oldContainerPosition.getLocation().getNegated()); return (PrecisionRectangle)newPosition.translate(distance.getLocation()); } /** * Sets the alignment position for the editpart * * @param newPosition * the new alignment position for the editpart */ public void setNewPosition(PrecisionRectangle newPosition) { this.newPosition = newPosition; } /** * * @see org.eclipse.papyrus.uml.diagram.common.layout.EditPartTree#createChildrenTree(java.util.List, java.util.List) * * @param editparts * the selected editpart * @param parentsList * parents of editparts which could be interesting to add to the * tree * @return */ @Override protected EditPartTree createChildrenTree(List<EditPart> editparts, List<EditPart> parentsList) { EditPartTree childTree = null; for(EditPart editpart : parentsList) { /* * the editparts are interesting only if they are selected or if its * parent is selected! */ if(editparts.contains(editpart) || ((!editparts.contains(editpart)) && ToolUtilities.isAncestorContainedIn(editparts, editpart))) { boolean isSelected = editparts.contains(editpart); AlignmentTree parentTree = new AlignmentTree(editpart, isSelected); if(!isSelected) { // this editpart won't move, so we can precise now its // position parentTree.setNewPosition(LayoutUtils.getAbsolutePosition(editpart)); } if(childTree != null) { parentTree.add(childTree); } childTree = parentTree; } } return childTree; } /** * Specifies in the tree which editpart in the selected editpart is used * like reference to do the alignment action * * @see org.eclipse.papyrus.uml.diagram.common.layout.EditPartTree#postBuildOperations(java.util.List) * * @param editparts * the editparts list */ @Override protected void postBuildOperations(List<EditPart> editparts) { // the reference for the alignment is the last selected element ((AlignmentTree)this.getTree(editparts.get(editparts.size() - 1))).setNewPosition(LayoutUtils.getAbsolutePosition(editparts.get(editparts.size() - 1))); } }